changeset 12371:e32f2b195867

Merge
author Christos Kotselidis <christos.kotselidis@oracle.com>
date Fri, 11 Oct 2013 17:21:14 +0200
parents 1e4d1c150ed5 (current diff) bba234a1670e (diff)
children 2dfccd93510a
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DelegatingCodeCacheProvider.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DelegatingMetaAccessProvider.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MemoryMap.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/VerifyHotSpotOptionsPhase.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryState.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/SurvivingCounterNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Canonicalizable.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/DelegatingGraalCodeCacheProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Simplifiable.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/SimplifierTool.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PhiStampPhase.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java src/os_cpu/bsd_x86/vm/bsd_x86_32.ad src/os_cpu/bsd_x86/vm/bsd_x86_64.ad src/os_cpu/linux_x86/vm/linux_x86_32.ad src/os_cpu/linux_x86/vm/linux_x86_64.ad src/os_cpu/solaris_sparc/vm/solaris_sparc.ad src/os_cpu/solaris_x86/vm/solaris_x86_32.ad src/os_cpu/solaris_x86/vm/solaris_x86_64.ad src/os_cpu/windows_x86/vm/windows_x86_32.ad src/os_cpu/windows_x86/vm/windows_x86_64.ad test/runtime/7196045/Test7196045.java test/runtime/8000968/Test8000968.sh
diffstat 623 files changed, 8960 insertions(+), 6150 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri Oct 11 17:14:35 2013 +0200
+++ b/.hgignore	Fri Oct 11 17:21:14 2013 +0200
@@ -79,3 +79,6 @@
 workingsets.xml
 .buildbot/
 graal.options
+agent/build/*
+agent/make/filelist
+agent/make/sa17.tar.gz
--- a/.hgtags	Fri Oct 11 17:14:35 2013 +0200
+++ b/.hgtags	Fri Oct 11 17:21:14 2013 +0200
@@ -363,3 +363,9 @@
 9f71e36a471ae4a668e08827d33035963ed10c08 hs25-b42
 5787fac72e760c6a5fd9efa113b0c75caf554136 jdk8-b100
 46487ba40ff225654d0c51787ed3839bafcbd9f3 hs25-b43
+f6921c876db192bba389cec062855a66372da01c jdk8-b101
+530fe88b3b2c710f42810b3580d86a0d83ad6c1c hs25-b44
+c4697c1c448416108743b59118b4a2498b339d0c jdk8-b102
+7f55137d6aa81efc6eb0035813709f2cb6a26b8b hs25-b45
+6f9be7f87b9653e94fd8fb3070891a0cc91b15bf jdk8-b103
+580430d131ccd475e2f2ad4006531b8c4813d102 hs25-b46
--- a/agent/src/share/classes/sun/jvm/hotspot/jdi/JVMTIThreadState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/jdi/JVMTIThreadState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -29,11 +29,10 @@
     public static final int JVMTI_THREAD_STATE_ALIVE = 0x0001;
     public static final int JVMTI_THREAD_STATE_TERMINATED = 0x0002;
     public static final int JVMTI_THREAD_STATE_RUNNABLE = 0x0004;
-    public static final int JVMTI_THREAD_STATE_WAITING = 0x0008;
+    public static final int JVMTI_THREAD_STATE_WAITING = 0x0080;
     public static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
     public static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
     public static final int JVMTI_THREAD_STATE_SLEEPING = 0x0040;
-    public static final int JVMTI_THREAD_STATE_WAITING_FOR_NOTIFICATION = 0x0080;
     public static final int JVMTI_THREAD_STATE_IN_OBJECT_WAIT = 0x0100;
     public static final int JVMTI_THREAD_STATE_PARKED = 0x0200;
     public static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;
--- a/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/opto/PhaseCFG.java	Fri Oct 11 17:21:14 2013 +0200
@@ -44,7 +44,7 @@
     Type type      = db.lookupType("PhaseCFG");
     numBlocksField = new CIntField(type.getCIntegerField("_num_blocks"), 0);
     blocksField = type.getAddressField("_blocks");
-    bbsField = type.getAddressField("_bbs");
+    bbsField = type.getAddressField("_node_to_block_mapping");
     brootField = type.getAddressField("_broot");
   }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/OSThread.java	Fri Oct 11 17:21:14 2013 +0200
@@ -32,7 +32,7 @@
 // to the sys_thread_t structure of the classic JVM implementation.
 public class OSThread extends VMObject {
     private static JIntField interruptedField;
-    private static JIntField threadIdField;
+    private static Field threadIdField;
     static {
         VM.registerVMInitializedObserver(new Observer() {
             public void update(Observable o, Object data) {
@@ -44,7 +44,7 @@
     private static synchronized void initialize(TypeDataBase db) {
         Type type = db.lookupType("OSThread");
         interruptedField = type.getJIntField("_interrupted");
-        threadIdField = type.getJIntField("_thread_id");
+        threadIdField = type.getField("_thread_id");
     }
 
     public OSThread(Address addr) {
@@ -56,7 +56,7 @@
     }
 
     public int threadId() {
-        return (int)threadIdField.getValue(addr);
+        return threadIdField.getJInt(addr);
     }
 
 }
--- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -74,23 +74,24 @@
     public void run() {
         // Ready to go with the database...
         try {
-            // The name of the filter always comes from a System property.
-            // If we have a pkgList, pass it, otherwise let the filter read
-            // its own System property for the list of classes.
-            String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter",
-                                                        "sun.jvm.hotspot.tools.jcore.PackageNameFilter");
-            try {
-                Class filterClass = Class.forName(filterClassName);
-                if (pkgList == null) {
-                    classFilter = (ClassFilter) filterClass.newInstance();
-                } else {
-                    Constructor con = filterClass.getConstructor(String.class);
-                    classFilter = (ClassFilter) con.newInstance(pkgList);
+            if (classFilter == null) {
+                // If not already set, the name of the filter comes from a System property.
+                // If we have a pkgList, pass it, otherwise let the filter read
+                // its own System property for the list of classes.
+                String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter",
+                                                            "sun.jvm.hotspot.tools.jcore.PackageNameFilter");
+                try {
+                    Class filterClass = Class.forName(filterClassName);
+                    if (pkgList == null) {
+                        classFilter = (ClassFilter) filterClass.newInstance();
+                    } else {
+                        Constructor con = filterClass.getConstructor(String.class);
+                        classFilter = (ClassFilter) con.newInstance(pkgList);
+                    }
+                } catch(Exception exp) {
+                    System.err.println("Warning: Can not create class filter!");
                 }
-            } catch(Exception exp) {
-                System.err.println("Warning: Can not create class filter!");
             }
-
             String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", ".");
             setOutputDirectory(outputDirectory);
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ArithmeticOperation.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ArithmeticOperation.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,13 @@
  */
 package com.oracle.graal.api.code;
 
+import com.oracle.graal.api.meta.*;
+
 /**
  * An {@code ArithmeticOperation} is an operation that does primitive value arithmetic without side
  * effect.
  */
 public interface ArithmeticOperation {
+
+    Constant evalConst(Constant... inputs);
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,9 +26,9 @@
 import com.oracle.graal.api.meta.*;
 
 /**
- * Encapsulates the main functionality of the runtime for the compiler.
+ * Access to code cache related details and requirements.
  */
-public interface CodeCacheProvider extends MetaAccessProvider {
+public interface CodeCacheProvider {
 
     /**
      * Adds the given compilation result as an implementation of the given method without making it
@@ -56,7 +56,7 @@
     /**
      * Gets the register configuration to use when compiling a given method.
      */
-    RegisterConfig lookupRegisterConfig();
+    RegisterConfig getRegisterConfig();
 
     /**
      * Minimum size of the stack area reserved for outgoing parameters. This area is reserved in all
@@ -72,13 +72,6 @@
     ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor);
 
     /**
-     * Encodes a deoptimization action and a deoptimization reason in an integer value.
-     * 
-     * @return the encoded value as an integer
-     */
-    int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason);
-
-    /**
      * Determines if a {@link DataPatch} should be created for a given
      * {@linkplain Constant#getPrimitiveAnnotation() annotated} primitive constant that part of a
      * {@link CompilationResult}. A data patch is always created for an object constant.
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Fri Oct 11 17:21:14 2013 +0200
@@ -339,7 +339,7 @@
             argTypes[argIndex++] = sig.getParameterType(i, null);
         }
 
-        RegisterConfig registerConfig = codeCache.lookupRegisterConfig();
+        RegisterConfig registerConfig = codeCache.getRegisterConfig();
         return registerConfig.getCallingConvention(type, retType, argTypes, codeCache.getTarget(), stackOnly);
     }
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DebugInfo.java	Fri Oct 11 17:21:14 2013 +0200
@@ -44,7 +44,6 @@
     private final BytecodePosition bytecodePosition;
     private final BitSet registerRefMap;
     private final BitSet frameRefMap;
-    private final short deoptimizationReason;
     private RegisterSaveLayout calleeSaveInfo;
 
     /**
@@ -55,11 +54,10 @@
      * @param registerRefMap the register map
      * @param frameRefMap the reference map for {@code frame}, which may be {@code null}
      */
-    public DebugInfo(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap, short deoptimizationReason) {
+    public DebugInfo(BytecodePosition codePos, BitSet registerRefMap, BitSet frameRefMap) {
         this.bytecodePosition = codePos;
         this.registerRefMap = registerRefMap;
         this.frameRefMap = frameRefMap;
-        this.deoptimizationReason = deoptimizationReason;
     }
 
     /**
@@ -127,15 +125,6 @@
     }
 
     /**
-     * Identifies the reason in case a deoptimization happens at this program counter.
-     * 
-     * @return the reason of the deoptimization
-     */
-    public short getDeoptimizationReason() {
-        return deoptimizationReason;
-    }
-
-    /**
      * Sets the map from the registers (in the caller's frame) to the slots where they are saved in
      * the current frame.
      */
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DelegatingCodeCacheProvider.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.code;
-
-import com.oracle.graal.api.meta.*;
-
-/**
- * A {@link CodeCacheProvider} that delegates to another {@link CodeCacheProvider}.
- */
-public class DelegatingCodeCacheProvider extends DelegatingMetaAccessProvider implements CodeCacheProvider {
-
-    public DelegatingCodeCacheProvider(CodeCacheProvider delegate) {
-        super(delegate);
-    }
-
-    @Override
-    protected CodeCacheProvider delegate() {
-        return (CodeCacheProvider) super.delegate();
-    }
-
-    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
-        return delegate().addMethod(method, compResult);
-    }
-
-    public String disassemble(CompilationResult compResult, InstalledCode installedCode) {
-        return delegate().disassemble(compResult, installedCode);
-    }
-
-    public RegisterConfig lookupRegisterConfig() {
-        return delegate().lookupRegisterConfig();
-    }
-
-    public int getMinimumOutgoingSize() {
-        return delegate().getMinimumOutgoingSize();
-    }
-
-    public ForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
-        return delegate().lookupForeignCall(descriptor);
-    }
-
-    public int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) {
-        return delegate().encodeDeoptActionAndReason(action, reason);
-    }
-
-    public boolean needsDataPatch(Constant constant) {
-        return delegate().needsDataPatch(constant);
-    }
-
-    public TargetDescription getTarget() {
-        return delegate().getTarget();
-    }
-}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DeoptimizationAction.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +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.api.code;
-
-/**
- * Specifies the action that should be taken by the runtime in case a certain deoptimization is
- * triggered.
- */
-public enum DeoptimizationAction {
-    /**
-     * Do not invalidate the machine code. This is typically used when deoptimizing at a point where
-     * it's highly likely nothing will change the likelihood of the deoptimization happening again.
-     * For example, a compiled array allocation where the size is negative.
-     */
-    None(false),
-
-    /**
-     * Do not invalidate the machine code, but schedule a recompilation if this deoptimization is
-     * triggered too often.
-     */
-    RecompileIfTooManyDeopts(true),
-
-    /**
-     * Invalidate the machine code and reset the profiling information.
-     */
-    InvalidateReprofile(true),
-
-    /**
-     * Invalidate the machine code and immediately schedule a recompilation. This is typically used
-     * when deoptimizing to resolve an unresolved symbol in which case extra profiling is not
-     * required to determine that the deoptimization will not re-occur.
-     */
-    InvalidateRecompile(true),
-
-    /**
-     * Invalidate the machine code and stop compiling the outermost method of this compilation.
-     */
-    InvalidateStopCompiling(true);
-
-    private final boolean invalidatesCompilation;
-
-    private DeoptimizationAction(boolean invalidatesCompilation) {
-        this.invalidatesCompilation = invalidatesCompilation;
-    }
-
-    public boolean doesInvalidateCompilation() {
-        return invalidatesCompilation;
-    }
-
-}
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/SpeculationLog.java	Fri Oct 11 17:21:14 2013 +0200
@@ -36,11 +36,11 @@
 
     public static final int MAX_CACHE_SIZE = 1 << 15;
 
-    private List<DeoptimizationReason> speculations = new ArrayList<>();
+    private List<Object> speculations = new ArrayList<>();
     private boolean[] map = new boolean[10];
-    private Set<DeoptimizationReason> snapshot = new HashSet<>();
+    private Set<Object> snapshot = new HashSet<>();
 
-    public short addSpeculation(DeoptimizationReason reason) {
+    private short addSpeculation(Object reason) {
         short index = (short) speculations.indexOf(reason);
         if (index != -1) {
             // Nothing to add, reason already registered.
@@ -68,7 +68,10 @@
         }
     }
 
-    public boolean maySpeculate(DeoptimizationReason reason) {
-        return !snapshot.contains(reason);
+    public Constant maySpeculate(Object reason) {
+        if (snapshot.contains(reason)) {
+            return null;
+        }
+        return Constant.forShort(addSpeculation(reason));
     }
 }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java	Fri Oct 11 17:21:14 2013 +0200
@@ -38,11 +38,11 @@
     public MethodUniverse() {
         for (Class c : classes) {
             for (Method m : c.getDeclaredMethods()) {
-                ResolvedJavaMethod method = runtime.lookupJavaMethod(m);
+                ResolvedJavaMethod method = metaAccess.lookupJavaMethod(m);
                 methods.put(m, method);
             }
             for (Constructor m : c.getDeclaredConstructors()) {
-                constructors.put(m, runtime.lookupJavaConstructor(m));
+                constructors.put(m, metaAccess.lookupJavaConstructor(m));
             }
         }
     }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaMethod.java	Fri Oct 11 17:21:14 2013 +0200
@@ -50,7 +50,7 @@
         for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
             Class expected = e.getKey().getDeclaringClass();
             ResolvedJavaType actual = e.getValue().getDeclaringClass();
-            assertTrue(actual.equals(runtime.lookupJavaType(expected)));
+            assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
         }
     }
 
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestJavaType.java	Fri Oct 11 17:21:14 2013 +0200
@@ -39,7 +39,7 @@
     @Test
     public void getKindTest() {
         for (Class c : classes) {
-            JavaType type = runtime.lookupJavaType(c);
+            JavaType type = metaAccess.lookupJavaType(c);
             Kind expected = Kind.fromJavaClass(c);
             Kind actual = type.getKind();
             assertEquals(expected, actual);
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestMetaAccessProvider.java	Fri Oct 11 17:21:14 2013 +0200
@@ -39,7 +39,7 @@
     @Test
     public void lookupJavaTypeTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             assertNotNull(type);
             assertEquals(c.getModifiers(), type.getModifiers());
             if (!type.isArray()) {
@@ -53,12 +53,12 @@
     public void lookupJavaMethodTest() {
         for (Class c : classes) {
             for (Method reflect : c.getDeclaredMethods()) {
-                ResolvedJavaMethod method = runtime.lookupJavaMethod(reflect);
+                ResolvedJavaMethod method = metaAccess.lookupJavaMethod(reflect);
                 assertNotNull(method);
                 int expected = reflect.getModifiers() & Modifier.methodModifiers();
                 int actual = method.getModifiers();
                 assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual);
-                assertTrue(method.getDeclaringClass().equals(runtime.lookupJavaType(reflect.getDeclaringClass())));
+                assertTrue(method.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass())));
             }
         }
     }
@@ -67,12 +67,12 @@
     public void lookupJavaFieldTest() {
         for (Class c : classes) {
             for (Field reflect : c.getDeclaredFields()) {
-                ResolvedJavaField field = runtime.lookupJavaField(reflect);
+                ResolvedJavaField field = metaAccess.lookupJavaField(reflect);
                 assertNotNull(field);
                 int expected = reflect.getModifiers() & Modifier.fieldModifiers();
                 int actual = field.getModifiers();
                 assertEquals(String.format("%s: 0x%x != 0x%x", reflect, expected, actual), expected, actual);
-                assertTrue(field.getDeclaringClass().equals(runtime.lookupJavaType(reflect.getDeclaringClass())));
+                assertTrue(field.getDeclaringClass().equals(metaAccess.lookupJavaType(reflect.getDeclaringClass())));
             }
         }
     }
@@ -82,11 +82,11 @@
         for (Constant c : constants) {
             if (c.getKind() == Kind.Object && !c.isNull()) {
                 Object o = c.asObject();
-                ResolvedJavaType type = runtime.lookupJavaType(c);
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
                 assertNotNull(type);
-                assertTrue(type.equals(runtime.lookupJavaType(o.getClass())));
+                assertTrue(type.equals(metaAccess.lookupJavaType(o.getClass())));
             } else {
-                assertEquals(runtime.lookupJavaType(c), null);
+                assertEquals(metaAccess.lookupJavaType(c), null);
             }
         }
     }
@@ -96,9 +96,9 @@
         for (Constant c1 : constants) {
             for (Constant c2 : constants) {
                 // test symmetry
-                assertEquals(runtime.constantEquals(c1, c2), runtime.constantEquals(c2, c1));
+                assertEquals(constantReflection.constantEquals(c1, c2), constantReflection.constantEquals(c2, c1));
                 if (c1.getKind() != Kind.Object && c2.getKind() != Kind.Object) {
-                    assertEquals(c1.equals(c2), runtime.constantEquals(c2, c1));
+                    assertEquals(c1.equals(c2), constantReflection.constantEquals(c2, c1));
                 }
             }
         }
@@ -107,7 +107,7 @@
     @Test
     public void lookupArrayLengthTest() {
         for (Constant c : constants) {
-            Integer actual = runtime.lookupArrayLength(c);
+            Integer actual = constantReflection.lookupArrayLength(c);
             if (c.getKind() != Kind.Object || c.isNull() || !c.asObject().getClass().isArray()) {
                 assertNull(actual);
             } else {
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Fri Oct 11 17:21:14 2013 +0200
@@ -174,13 +174,13 @@
 
     @Test
     public void getExceptionHandlersTest() throws NoSuchMethodException {
-        ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithExceptionHandlers", String.class, Object.class));
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithExceptionHandlers", String.class, Object.class));
         ExceptionHandler[] handlers = method.getExceptionHandlers();
         assertNotNull(handlers);
         assertEquals(handlers.length, 3);
-        handlers[0].getCatchType().equals(runtime.lookupJavaType(IndexOutOfBoundsException.class));
-        handlers[1].getCatchType().equals(runtime.lookupJavaType(NullPointerException.class));
-        handlers[2].getCatchType().equals(runtime.lookupJavaType(RuntimeException.class));
+        handlers[0].getCatchType().equals(metaAccess.lookupJavaType(IndexOutOfBoundsException.class));
+        handlers[1].getCatchType().equals(metaAccess.lookupJavaType(NullPointerException.class));
+        handlers[2].getCatchType().equals(metaAccess.lookupJavaType(RuntimeException.class));
     }
 
     private static String nullPointerExceptionOnFirstLine(Object o, String ignored) {
@@ -194,7 +194,7 @@
             Assert.fail("should not reach here");
         } catch (NullPointerException e) {
             StackTraceElement expected = e.getStackTrace()[0];
-            ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
+            ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
             StackTraceElement actual = method.asStackTraceElement(0);
             assertEquals(expected, actual);
         }
@@ -211,7 +211,7 @@
 
     @Test(timeout = 1000L)
     public void getAnnotationTest() throws NoSuchMethodException {
-        ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationTest"));
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationTest"));
         Test annotation = method.getAnnotation(Test.class);
         assertNotNull(annotation);
         assertEquals(1000L, annotation.timeout());
@@ -231,7 +231,7 @@
 
     @Test
     public void getParameterAnnotationsTest() throws NoSuchMethodException {
-        ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
         Annotation[][] annotations = method.getParameterAnnotations();
         assertEquals(2, annotations.length);
         assertEquals(1, annotations[0].length);
@@ -243,7 +243,7 @@
 
     @Test
     public void getGenericParameterTypesTest() throws NoSuchMethodException {
-        ResolvedJavaMethod method = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
+        ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
         Type[] genericParameterTypes = method.getGenericParameterTypes();
         assertEquals(2, genericParameterTypes.length);
         assertEquals("java.util.HashMap<java.lang.String, java.lang.String>", genericParameterTypes[0].toString());
@@ -252,8 +252,8 @@
 
     @Test
     public void getMaxLocalsTest() throws NoSuchMethodException {
-        ResolvedJavaMethod method1 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
-        ResolvedJavaMethod method2 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
+        ResolvedJavaMethod method1 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
+        ResolvedJavaMethod method2 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
         assertEquals(0, method1.getMaxLocals());
         assertEquals(2, method2.getMaxLocals());
 
@@ -261,8 +261,8 @@
 
     @Test
     public void getMaxStackSizeTest() throws NoSuchMethodException {
-        ResolvedJavaMethod method1 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
-        ResolvedJavaMethod method2 = runtime.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
+        ResolvedJavaMethod method1 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
+        ResolvedJavaMethod method2 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
         assertEquals(0, method1.getMaxStackSize());
         // some versions of javac produce bytecode with a stacksize of 2 for this method
         // JSR 292 also sometimes need one more stack slot
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java	Fri Oct 11 17:21:14 2013 +0200
@@ -48,7 +48,7 @@
     @Test
     public void findInstanceFieldWithOffsetTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             Set<Field> reflectionFields = getInstanceFields(c, true);
             for (Field f : reflectionFields) {
                 ResolvedJavaField rf = lookupField(type.getInstanceFields(true), f);
@@ -64,7 +64,7 @@
     @Test
     public void isInterfaceTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             boolean expected = c.isInterface();
             boolean actual = type.isInterface();
             assertEquals(expected, actual);
@@ -74,7 +74,7 @@
     @Test
     public void isInstanceClassTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             boolean expected = !c.isArray() && !c.isPrimitive() && !c.isInterface();
             boolean actual = type.isInstanceClass();
             assertEquals(expected, actual);
@@ -84,7 +84,7 @@
     @Test
     public void isArrayTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             boolean expected = c.isArray();
             boolean actual = type.isArray();
             assertEquals(expected, actual);
@@ -94,7 +94,7 @@
     @Test
     public void getModifiersTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             int expected = c.getModifiers();
             int actual = type.getModifiers();
             assertEquals(expected, actual);
@@ -108,8 +108,8 @@
             Class<?> c1 = all[i];
             for (int j = i; j < all.length; j++) {
                 Class<?> c2 = all[j];
-                ResolvedJavaType t1 = runtime.lookupJavaType(c1);
-                ResolvedJavaType t2 = runtime.lookupJavaType(c2);
+                ResolvedJavaType t1 = metaAccess.lookupJavaType(c1);
+                ResolvedJavaType t2 = metaAccess.lookupJavaType(c2);
                 boolean expected = c1.isAssignableFrom(c2);
                 boolean actual = t1.isAssignableFrom(t2);
                 assertEquals(expected, actual);
@@ -127,7 +127,7 @@
                 Object o = c.asObject();
                 Class<? extends Object> cls = o.getClass();
                 while (cls != null) {
-                    ResolvedJavaType type = runtime.lookupJavaType(cls);
+                    ResolvedJavaType type = metaAccess.lookupJavaType(cls);
                     boolean expected = cls.isInstance(o);
                     boolean actual = type.isInstance(c);
                     assertEquals(expected, actual);
@@ -153,14 +153,14 @@
     @Test
     public void asExactTypeTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             ResolvedJavaType exactType = type.asExactType();
             Class expected = asExactClass(c);
             if (expected == null) {
                 assertTrue("exact(" + c.getName() + ") != null", exactType == null);
             } else {
                 assertNotNull(exactType);
-                assertTrue(exactType.equals(runtime.lookupJavaType(expected)));
+                assertTrue(exactType.equals(metaAccess.lookupJavaType(expected)));
             }
         }
     }
@@ -168,14 +168,14 @@
     @Test
     public void getSuperclassTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             Class expected = c.getSuperclass();
             ResolvedJavaType actual = type.getSuperclass();
             if (expected == null) {
                 assertTrue(actual == null);
             } else {
                 assertNotNull(actual);
-                assertTrue(actual.equals(runtime.lookupJavaType(expected)));
+                assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
             }
         }
     }
@@ -183,12 +183,12 @@
     @Test
     public void getInterfacesTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             Class[] expected = c.getInterfaces();
             ResolvedJavaType[] actual = type.getInterfaces();
             assertEquals(expected.length, actual.length);
             for (int i = 0; i < expected.length; i++) {
-                assertTrue(actual[i].equals(runtime.lookupJavaType(expected[i])));
+                assertTrue(actual[i].equals(metaAccess.lookupJavaType(expected[i])));
             }
         }
     }
@@ -234,15 +234,15 @@
             Class<?> c1 = all[i];
             for (int j = i; j < all.length; j++) {
                 Class<?> c2 = all[j];
-                ResolvedJavaType t1 = runtime.lookupJavaType(c1);
-                ResolvedJavaType t2 = runtime.lookupJavaType(c2);
+                ResolvedJavaType t1 = metaAccess.lookupJavaType(c1);
+                ResolvedJavaType t2 = metaAccess.lookupJavaType(c2);
                 Class expected = findLeastCommonAncestor(c1, c2);
                 ResolvedJavaType actual = t1.findLeastCommonAncestor(t2);
                 if (expected == null) {
                     assertTrue(actual == null);
                 } else {
                     assertNotNull(actual);
-                    assertTrue(actual.equals(runtime.lookupJavaType(expected)));
+                    assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
                 }
             }
         }
@@ -277,7 +277,7 @@
             if (expected == null) {
                 assertNull(subtype);
             } else {
-                assertTrue(subtype.equals(runtime.lookupJavaType(expected)));
+                assertTrue(subtype.equals(metaAccess.lookupJavaType(expected)));
             }
         }
 
@@ -294,18 +294,18 @@
 
     @Test
     public void findUniqueConcreteSubtypeTest() {
-        ResolvedJavaType base = runtime.lookupJavaType(Base.class);
+        ResolvedJavaType base = metaAccess.lookupJavaType(Base.class);
         checkConcreteSubtype(base, Base.class);
 
-        ResolvedJavaType a1 = runtime.lookupJavaType(Abstract1.class);
-        ResolvedJavaType c1 = runtime.lookupJavaType(Concrete1.class);
+        ResolvedJavaType a1 = metaAccess.lookupJavaType(Abstract1.class);
+        ResolvedJavaType c1 = metaAccess.lookupJavaType(Concrete1.class);
 
         checkConcreteSubtype(base, null);
         checkConcreteSubtype(a1, Concrete1.class);
         checkConcreteSubtype(c1, Concrete1.class);
 
-        ResolvedJavaType i1 = runtime.lookupJavaType(Interface1.class);
-        ResolvedJavaType c2 = runtime.lookupJavaType(Concrete2.class);
+        ResolvedJavaType i1 = metaAccess.lookupJavaType(Interface1.class);
+        ResolvedJavaType c2 = metaAccess.lookupJavaType(Concrete2.class);
 
         checkConcreteSubtype(base, null);
         checkConcreteSubtype(a1, null);
@@ -313,11 +313,11 @@
         checkConcreteSubtype(i1, Concrete2.class);
         checkConcreteSubtype(c2, Concrete2.class);
 
-        ResolvedJavaType c3 = runtime.lookupJavaType(Concrete3.class);
+        ResolvedJavaType c3 = metaAccess.lookupJavaType(Concrete3.class);
         checkConcreteSubtype(c2, null);
         checkConcreteSubtype(c3, Concrete3.class);
 
-        ResolvedJavaType a4 = runtime.lookupJavaType(Abstract4.class);
+        ResolvedJavaType a4 = metaAccess.lookupJavaType(Abstract4.class);
         checkConcreteSubtype(c3, null);
         checkConcreteSubtype(a4, null);
     }
@@ -325,13 +325,13 @@
     @Test
     public void getComponentTypeTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             Class expected = c.getComponentType();
             ResolvedJavaType actual = type.getComponentType();
             if (expected == null) {
                 assertNull(actual);
             } else {
-                assertTrue(actual.equals(runtime.lookupJavaType(expected)));
+                assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
             }
         }
     }
@@ -340,10 +340,10 @@
     public void getArrayClassTest() {
         for (Class c : classes) {
             if (c != void.class) {
-                ResolvedJavaType type = runtime.lookupJavaType(c);
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
                 Class expected = getArrayClass(c);
                 ResolvedJavaType actual = type.getArrayClass();
-                assertTrue(actual.equals(runtime.lookupJavaType(expected)));
+                assertTrue(actual.equals(metaAccess.lookupJavaType(expected)));
             }
         }
     }
@@ -399,9 +399,11 @@
             }
             for (Method m : c.getDeclaredMethods()) {
                 if (!isStatic(m.getModifiers()) && !isPrivate(m.getModifiers())) {
-                    Method overridden = vtable.methods.put(new NameAndSignature(m), m);
-                    if (overridden != null) {
-                        // println(m + " overrides " + overridden);
+                    if (isAbstract(m.getModifiers())) {
+                        // A subclass makes a concrete method in a superclass abstract
+                        vtable.methods.remove(new NameAndSignature(m));
+                    } else {
+                        vtable.methods.put(new NameAndSignature(m), m);
                     }
                 }
             }
@@ -438,25 +440,36 @@
     @Test
     public void resolveMethodTest() {
         for (Class c : classes) {
-            if (!c.isPrimitive() && !c.isInterface()) {
-                ResolvedJavaType type = runtime.lookupJavaType(c);
+            if (c.isInterface() || c.isPrimitive()) {
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
+                for (Method m : c.getDeclaredMethods()) {
+                    ResolvedJavaMethod impl = type.resolveMethod(metaAccess.lookupJavaMethod(m));
+                    assertEquals(m.toString(), null, impl);
+                }
+            } else {
+                ResolvedJavaType type = metaAccess.lookupJavaType(c);
                 VTable vtable = getVTable(c);
                 for (Method impl : vtable.methods.values()) {
                     Set<Method> decls = findDeclarations(impl, c);
                     for (Method decl : decls) {
-                        ResolvedJavaMethod m = runtime.lookupJavaMethod(decl);
-                        ResolvedJavaMethod i = runtime.lookupJavaMethod(impl);
+                        ResolvedJavaMethod m = metaAccess.lookupJavaMethod(decl);
+                        ResolvedJavaMethod i = metaAccess.lookupJavaMethod(impl);
                         checkResolveMethod(type, m, i);
                     }
                 }
+                for (Method m : c.getDeclaredMethods()) {
+                    ResolvedJavaMethod impl = type.resolveMethod(metaAccess.lookupJavaMethod(m));
+                    ResolvedJavaMethod expected = isAbstract(m.getModifiers()) ? null : impl;
+                    assertEquals(type + " " + m.toString(), expected, impl);
+                }
             }
         }
     }
 
     @Test
     public void findUniqueConcreteMethodTest() throws NoSuchMethodException {
-        ResolvedJavaMethod thisMethod = runtime.lookupJavaMethod(getClass().getDeclaredMethod("findUniqueConcreteMethodTest"));
-        ResolvedJavaMethod ucm = runtime.lookupJavaType(getClass()).findUniqueConcreteMethod(thisMethod);
+        ResolvedJavaMethod thisMethod = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("findUniqueConcreteMethodTest"));
+        ResolvedJavaMethod ucm = metaAccess.lookupJavaType(getClass()).findUniqueConcreteMethod(thisMethod);
         assertEquals(thisMethod, ucm);
     }
 
@@ -477,8 +490,8 @@
     }
 
     public boolean fieldsEqual(Field f, ResolvedJavaField rjf) {
-        return rjf.getDeclaringClass().equals(runtime.lookupJavaType(f.getDeclaringClass())) && rjf.getName().equals(f.getName()) &&
-                        rjf.getType().resolve(rjf.getDeclaringClass()).equals(runtime.lookupJavaType(f.getType()));
+        return rjf.getDeclaringClass().equals(metaAccess.lookupJavaType(f.getDeclaringClass())) && rjf.getName().equals(f.getName()) &&
+                        rjf.getType().resolve(rjf.getDeclaringClass()).equals(metaAccess.lookupJavaType(f.getType()));
     }
 
     public ResolvedJavaField lookupField(ResolvedJavaField[] fields, Field key) {
@@ -502,10 +515,10 @@
     }
 
     private boolean isHiddenFromReflection(ResolvedJavaField f) {
-        if (f.getDeclaringClass().equals(runtime.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) {
+        if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(Throwable.class)) && f.getName().equals("backtrace")) {
             return true;
         }
-        if (f.getDeclaringClass().equals(runtime.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) {
+        if (f.getDeclaringClass().equals(metaAccess.lookupJavaType(ConstantPool.class)) && f.getName().equals("constantPoolOop")) {
             return true;
         }
         return false;
@@ -514,7 +527,7 @@
     @Test
     public void getInstanceFieldsTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             for (boolean includeSuperclasses : new boolean[]{true, false}) {
                 Set<Field> expected = getInstanceFields(c, includeSuperclasses);
                 ResolvedJavaField[] actual = type.getInstanceFields(includeSuperclasses);
@@ -535,9 +548,52 @@
     }
 
     @Test
+    public void getDeclaredMethodsTest() {
+        for (Class c : classes) {
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
+            Method[] raw = c.getDeclaredMethods();
+            Set<ResolvedJavaMethod> expected = new HashSet<>();
+            for (Method m : raw) {
+                ResolvedJavaMethod resolvedMethod = metaAccess.lookupJavaMethod(m);
+                assertNotNull(resolvedMethod);
+                expected.add(resolvedMethod);
+            }
+            Set<ResolvedJavaMethod> actual = new HashSet<>(Arrays.asList(type.getDeclaredMethods()));
+            assertEquals(expected, actual);
+        }
+    }
+
+    static class A {
+        static String name = "foo";
+    }
+
+    static class B extends A {
+    }
+
+    static class C {
+    }
+
+    static class D {
+        void foo() {
+            // use of assertions causes the class to have a <clinit>
+            assert getClass() != null;
+        }
+    }
+
+    @Test
+    public void getClassInitializerTest() {
+        assertNotNull(metaAccess.lookupJavaType(A.class).getClassInitializer());
+        assertNotNull(metaAccess.lookupJavaType(D.class).getClassInitializer());
+        assertNull(metaAccess.lookupJavaType(B.class).getClassInitializer());
+        assertNull(metaAccess.lookupJavaType(C.class).getClassInitializer());
+        assertNull(metaAccess.lookupJavaType(int.class).getClassInitializer());
+        assertNull(metaAccess.lookupJavaType(void.class).getClassInitializer());
+    }
+
+    @Test
     public void getAnnotationTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             for (Annotation a : c.getAnnotations()) {
                 assertEquals(a, type.getAnnotation(a.annotationType()));
             }
@@ -547,14 +603,14 @@
     @Test
     public void memberClassesTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             assertEquals(c.isLocalClass(), type.isLocal());
             assertEquals(c.isMemberClass(), type.isMember());
             Class enclc = c.getEnclosingClass();
             ResolvedJavaType enclt = type.getEnclosingType();
             assertFalse(enclc == null ^ enclt == null);
             if (enclc != null) {
-                assertEquals(enclt, runtime.lookupJavaType(enclc));
+                assertEquals(enclt, metaAccess.lookupJavaType(enclc));
             }
         }
     }
@@ -562,7 +618,7 @@
     @Test
     public void classFilePathTest() {
         for (Class c : classes) {
-            ResolvedJavaType type = runtime.lookupJavaType(c);
+            ResolvedJavaType type = metaAccess.lookupJavaType(c);
             URL path = type.getClassFilePath();
             if (type.isPrimitive() || type.isArray()) {
                 assertEquals(null, path);
@@ -591,7 +647,6 @@
         "initialize",
         "isPrimitive",
         "newArray",
-        "getDeclaredMethods",
         "getDeclaredConstructors",
         "isInitialized",
         "isLinked",
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TypeUniverse.java	Fri Oct 11 17:21:14 2013 +0200
@@ -40,7 +40,8 @@
 public class TypeUniverse {
 
     public final Unsafe unsafe;
-    public final MetaAccessProvider runtime = Graal.getRequiredCapability(MetaAccessProvider.class);
+    public final MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
+    public final ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class);
     public final Collection<Class<?>> classes = new HashSet<>();
     public final Map<Class<?>, Class<?>> arrayClasses = new HashMap<>();
     public final List<Constant> constants = new ArrayList<>();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ConstantReflectionProvider.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+/**
+ * Reflection operations on values represented as {@linkplain Constant constants}.
+ */
+public interface ConstantReflectionProvider {
+
+    /**
+     * Compares two constants for equality. The equality relationship is symmetric.
+     * 
+     * @return {@code true} if the two parameters represent the same runtime object, {@code false}
+     *         otherwise
+     */
+    boolean constantEquals(Constant x, Constant y);
+
+    /**
+     * Returns the length of an array that is wrapped in a {@link Constant} object. If {@code array}
+     * is not an array, or the array length is not available at this point, the return value is
+     * {@code null}.
+     */
+    Integer lookupArrayLength(Constant array);
+
+    /**
+     * Reads a value of this kind using a base address and a displacement.
+     * 
+     * @param base the base address from which the value is read
+     * @param displacement the displacement within the object in bytes
+     * @param compressible whether this is a read of a compressed or an uncompressed pointer
+     * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the
+     *         value cannot be read.
+     */
+    Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible);
+}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DelegatingMetaAccessProvider.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.meta;
-
-import java.lang.reflect.*;
-
-/**
- * A {@link MetaAccessProvider} that delegates to another {@link MetaAccessProvider}.
- */
-public class DelegatingMetaAccessProvider implements MetaAccessProvider {
-
-    private final MetaAccessProvider delegate;
-
-    public DelegatingMetaAccessProvider(MetaAccessProvider delegate) {
-        this.delegate = delegate;
-    }
-
-    protected MetaAccessProvider delegate() {
-        return delegate;
-    }
-
-    public ResolvedJavaType lookupJavaType(Class<?> clazz) {
-        return delegate.lookupJavaType(clazz);
-    }
-
-    public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) {
-        return delegate.lookupJavaMethod(reflectionMethod);
-    }
-
-    public ResolvedJavaMethod lookupJavaConstructor(Constructor reflectionConstructor) {
-        return delegate.lookupJavaConstructor(reflectionConstructor);
-    }
-
-    public ResolvedJavaField lookupJavaField(Field reflectionField) {
-        return delegate.lookupJavaField(reflectionField);
-    }
-
-    public ResolvedJavaType lookupJavaType(Constant constant) {
-        return delegate.lookupJavaType(constant);
-    }
-
-    public Signature parseMethodDescriptor(String methodDescriptor) {
-        return delegate.parseMethodDescriptor(methodDescriptor);
-    }
-
-    public boolean constantEquals(Constant x, Constant y) {
-        return delegate.constantEquals(x, y);
-    }
-
-    public Integer lookupArrayLength(Constant array) {
-        return delegate.lookupArrayLength(array);
-    }
-
-    public Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible) {
-        return delegate.readUnsafeConstant(kind, base, displacement, compressible);
-    }
-
-    public boolean isReexecutable(ForeignCallDescriptor descriptor) {
-        return delegate.isReexecutable(descriptor);
-    }
-
-    public LocationIdentity[] getKilledLocations(ForeignCallDescriptor descriptor) {
-        return delegate.getKilledLocations(descriptor);
-    }
-
-    public boolean canDeoptimize(ForeignCallDescriptor descriptor) {
-        return delegate.canDeoptimize(descriptor);
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DeoptimizationAction.java	Fri Oct 11 17:21:14 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.api.meta;
+
+/**
+ * Specifies the action that should be taken by the runtime in case a certain deoptimization is
+ * triggered.
+ */
+public enum DeoptimizationAction {
+    /**
+     * Do not invalidate the machine code. This is typically used when deoptimizing at a point where
+     * it's highly likely nothing will change the likelihood of the deoptimization happening again.
+     * For example, a compiled array allocation where the size is negative.
+     */
+    None(false),
+
+    /**
+     * Do not invalidate the machine code, but schedule a recompilation if this deoptimization is
+     * triggered too often.
+     */
+    RecompileIfTooManyDeopts(true),
+
+    /**
+     * Invalidate the machine code and reset the profiling information.
+     */
+    InvalidateReprofile(true),
+
+    /**
+     * Invalidate the machine code and immediately schedule a recompilation. This is typically used
+     * when deoptimizing to resolve an unresolved symbol in which case extra profiling is not
+     * required to determine that the deoptimization will not re-occur.
+     */
+    InvalidateRecompile(true),
+
+    /**
+     * Invalidate the machine code and stop compiling the outermost method of this compilation.
+     */
+    InvalidateStopCompiling(true);
+
+    private final boolean invalidatesCompilation;
+
+    private DeoptimizationAction(boolean invalidatesCompilation) {
+        this.invalidatesCompilation = invalidatesCompilation;
+    }
+
+    public boolean doesInvalidateCompilation() {
+        return invalidatesCompilation;
+    }
+
+}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MemoryMap.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.meta;
-
-public interface MemoryMap<T> {
-
-    T getLastLocationAccess(LocationIdentity locationIdentity);
-}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,7 +25,7 @@
 import java.lang.reflect.*;
 
 /**
- * Interface implemented by the runtime to allow access to its metadata.
+ * Provides access to the metadata of a class typically provided in a class file.
  */
 public interface MetaAccessProvider {
 
@@ -68,35 +68,6 @@
     Signature parseMethodDescriptor(String methodDescriptor);
 
     /**
-     * Compares two constants for equality. This is used instead of {@link Constant#equals(Object)}
-     * in case the runtime has an interpretation for object equality other than
-     * {@code x.asObject() == y.asObject()}. For primitive constants, this is equivalent to calling
-     * {@code x.equals(y)}. The equality relationship is symmetric.
-     * 
-     * @return {@code true} if the two parameters represent the same runtime object, {@code false}
-     *         otherwise
-     */
-    boolean constantEquals(Constant x, Constant y);
-
-    /**
-     * Returns the length of an array that is wrapped in a {@link Constant} object. If {@code array}
-     * is not an array, or the array length is not available at this point, the return value is
-     * {@code null}.
-     */
-    Integer lookupArrayLength(Constant array);
-
-    /**
-     * Reads a value of this kind using a base address and a displacement.
-     * 
-     * @param base the base address from which the value is read
-     * @param displacement the displacement within the object in bytes
-     * @param compressible whether this is a read of a compressed or an uncompressed pointer
-     * @return the read value encapsulated in a {@link Constant} object, or {@code null} if the
-     *         value cannot be read.
-     */
-    Constant readUnsafeConstant(Kind kind, Object base, long displacement, boolean compressible);
-
-    /**
      * Determines if a given foreign call is side-effect free. Deoptimization cannot return
      * execution to a point before a foreign call that has a side effect.
      */
@@ -113,4 +84,11 @@
      * Determines if deoptimization can occur during a given foreign call.
      */
     boolean canDeoptimize(ForeignCallDescriptor descriptor);
+
+    /**
+     * Encodes a deoptimization action and a deoptimization reason in an integer value.
+     * 
+     * @return the encoded value as an integer
+     */
+    Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ObjectLocationIdentity.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+import java.util.*;
+
+/**
+ * A {@link LocationIdentity} warpping an object.
+ */
+public final class ObjectLocationIdentity implements LocationIdentity {
+
+    private static IdentityHashMap<Object, LocationIdentity> map = new IdentityHashMap<>();
+
+    private Object object;
+
+    public static LocationIdentity create(Object object) {
+        synchronized (map) {
+            if (map.containsKey(object)) {
+                return map.get(object);
+            } else {
+                ObjectLocationIdentity locationIdentity = new ObjectLocationIdentity(object);
+                map.put(object, locationIdentity);
+                return locationIdentity;
+            }
+        }
+    }
+
+    private ObjectLocationIdentity(Object object) {
+        this.object = object;
+    }
+
+    @Override
+    public String toString() {
+        return "Identity(" + object + ")";
+    }
+}
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaField.java	Fri Oct 11 17:21:14 2013 +0200
@@ -29,7 +29,7 @@
  * Represents a reference to a resolved Java field. Fields, like methods and types, are resolved
  * through {@link ConstantPool constant pools}.
  */
-public interface ResolvedJavaField extends JavaField {
+public interface ResolvedJavaField extends JavaField, LocationIdentity {
 
     /**
      * Returns the Java language modifiers for this field, as an integer. The {@link Modifier} class
@@ -50,17 +50,21 @@
     boolean isSynthetic();
 
     /**
-     * Gets the constant value of this field for a given object, if available.
+     * Gets the constant value of this field. Note that a {@code static final} field may not be
+     * considered constant if its declaring class is not yet initialized or if it is a well known
+     * field that can be updated via other means (e.g., {@link System#setOut(java.io.PrintStream)}).
      * 
      * @param receiver object from which this field's value is to be read. This value is ignored if
      *            this field is static.
-     * @return the constant value of this field or {@code null} if the constant value is not
-     *         available
+     * @return the constant value of this field or {@code null} if this field is not considered
+     *         constant by the runtime
      */
     Constant readConstantValue(Constant receiver);
 
     /**
-     * Gets the current value of this field for a given object, if available.
+     * Gets the current value of this field for a given object, if available. There is no guarantee
+     * that the same value will be returned by this method for a field unless the field is
+     * considered to be {@link #readConstantValue(Constant)} by the runtime.
      * 
      * @param receiver object from which this field's value is to be read. This value is ignored if
      *            this field is static.
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaType.java	Fri Oct 11 17:21:14 2013 +0200
@@ -205,10 +205,13 @@
 
     /**
      * Resolves the method implementation for virtual dispatches on objects of this dynamic type.
+     * This resolution process only searches "up" the class hierarchy of this type. A broader search
+     * that also walks "down" the hierarchy is implemented by
+     * {@link #findUniqueConcreteMethod(ResolvedJavaMethod)}.
      * 
      * @param method the method to select the implementation of
-     * @return the method implementation that would be selected at runtime, or {@code null} if the
-     *         runtime cannot resolve the method at this point in time.
+     * @return the concrete method that would be selected at runtime, or {@code null} if there is no
+     *         concrete implementation of {@code method} in this type or any of its superclasses
      */
     ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method);
 
@@ -298,6 +301,11 @@
     ResolvedJavaMethod[] getDeclaredMethods();
 
     /**
+     * Returns the {@code <clinit>} method for this class if there is one.
+     */
+    ResolvedJavaMethod getClassInitializer();
+
+    /**
      * Creates a new array with this type as the component type and the specified length. This
      * method is similar to {@link Array#newInstance(Class, int)}.
      */
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64Assembler.java	Fri Oct 11 17:21:14 2013 +0200
@@ -747,7 +747,7 @@
         emitOperandHelper(0, dst);
     }
 
-    private void jcc(ConditionFlag cc, int jumpTarget, boolean forceDisp32) {
+    public void jcc(ConditionFlag cc, int jumpTarget, boolean forceDisp32) {
         int shortSize = 2;
         int longSize = 6;
         long disp = jumpTarget - codeBuffer.position();
--- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/AbstractHSAILAssembler.java	Fri Oct 11 17:21:14 2013 +0200
@@ -57,6 +57,7 @@
 
     @Override
     protected String createLabelName(Label l, int id) {
-        return "@L" + id;
+        int blockId = l.getBlockId();
+        return "@L" + (blockId == -1 ? id : blockId);
     }
 }
--- a/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.asm.ptx/src/com/oracle/graal/asm/ptx/PTXAssembler.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 
+import com.oracle.graal.asm.Label;
 import com.oracle.graal.api.code.Register;
 import com.oracle.graal.api.code.RegisterConfig;
 import com.oracle.graal.api.code.TargetDescription;
@@ -32,6 +33,7 @@
 import com.oracle.graal.api.meta.Value;
 import com.oracle.graal.nodes.calc.Condition;
 import com.oracle.graal.graph.GraalInternalError;
+import com.oracle.graal.lir.LabelRef;
 import com.oracle.graal.lir.Variable;
 
 public class PTXAssembler extends AbstractPTXAssembler {
@@ -185,7 +187,7 @@
             assert v != null;
 
             if (isConstant(v)) {
-                return (emitConstant(v));
+                return (emitConstant(v, comma));
             } else {
                 return (emitRegister((Variable) v, comma));
             }
@@ -195,28 +197,38 @@
             return (" %r" + v.index + (comma ? "," : ""));
         }
 
-        public String emitConstant(Value v) {
+        public String emitConstant(Value v, boolean comma) {
             Constant constant = (Constant) v;
+            String str = null;
 
             switch (v.getKind().getTypeChar()) {
                 case 'i':
-                    return (String.valueOf((int) constant.asLong()));
+                    str = String.valueOf((int) constant.asLong());
+                    break;
                 case 'f':
-                    return (String.valueOf(constant.asFloat()));
+                    str = String.valueOf(constant.asFloat());
+                    break;
                 case 'j':
-                    return (String.valueOf(constant.asLong()));
+                    str = String.valueOf(constant.asLong());
+                    break;
                 case 'd':
-                    return (String.valueOf(constant.asDouble()));
+                    str = String.valueOf(constant.asDouble());
+                    break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
+            if (comma) {
+                return (str + ",");
+            } else {
+                return str;
+            }
         }
     }
 
     public static class SingleOperandFormat {
 
         protected Variable dest;
-        protected Value    source;
+        protected Value source;
 
         public SingleOperandFormat(Variable dst, Value src) {
             setDestination(dst);
@@ -288,7 +300,34 @@
         }
 
         public String emitVariable(Variable v) {
-            return (" %r" + v.index);
+            String name = v.getName();
+
+            if (name == null) {
+                return (" %r" + v.index);
+            } else {
+                return name;
+            }
+        }
+    }
+
+    public static class BinarySingleOperandFormat extends SingleOperandFormat {
+
+        public BinarySingleOperandFormat(Variable dst, Value src) {
+            super(dst, src);
+        }
+
+        @Override
+        public String typeForKind(Kind k) {
+            switch (k.getTypeChar()) {
+                case 's':
+                    return "b16";
+                case 'i':
+                    return "b32";
+                case 'j':
+                    return "b64";
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
         }
     }
 
@@ -300,8 +339,7 @@
 
         @Override
         public String emit() {
-            return (typeForKind(dest.getKind()) + "." + typeForKind(source.getKind()) + " " +
-                    emitVariable(dest) + ", " + emitValue(source) + ";");
+            return (typeForKind(dest.getKind()) + "." + typeForKind(source.getKind()) + " " + emitVariable(dest) + ", " + emitValue(source) + ";");
         }
     }
 
@@ -327,21 +365,18 @@
 
         @Override
         public String emitRegister(Variable var, boolean comma) {
-            /* if (space == Parameter) {
-                return ("param" + var.index);
-            } else {
-                return ("%r" + var.index);
-            } */
+            /*
+             * if (space == Parameter) { return ("param" + var.index); } else { return ("%r" +
+             * var.index); }
+             */
             return ("%r" + var.index);
         }
 
         public String emit(boolean isLoad) {
             if (isLoad) {
-                return (space.getStateName() + "." + typeForKind(valueKind) + " " +
-                        emitRegister(dest, false) + ", " + emitAddress(source1, source2) + ";");
+                return (space.getStateName() + "." + typeForKind(valueKind) + " " + emitRegister(dest, false) + ", " + emitAddress(source1, source2) + ";");
             } else {
-                return (space.getStateName() + "." + typeForKind(valueKind) + " " +
-                        emitAddress(source1, source2) + ", " + emitRegister(dest, false) + ";");
+                return (space.getStateName() + "." + typeForKind(valueKind) + " " + emitAddress(source1, source2) + ", " + emitRegister(dest, false) + ";");
             }
         }
     }
@@ -474,7 +509,16 @@
 
     // Checkstyle: stop method name check
     public final void bra(String tgt, int pred) {
-        emitString((pred >= 0) ? "" : ("@%p" + pred + "  ") + "bra" + " " + tgt + ";" + "");
+        assert pred >= 0;
+
+        if (tgt.equals("?")) {
+            Thread.dumpStack();
+        }
+        emitString("@%p" + pred + " " + "bra" + " " + tgt + ";");
+    }
+
+    public final void bra(String src) {
+        emitString("bra " + src + ";");
     }
 
     public final void bra_uni(String tgt) {
@@ -488,27 +532,42 @@
         }
 
         public void emit(PTXAssembler asm) {
-            asm.emitString("cvt." + super.emit());
+            if (dest.getKind() == Kind.Float || dest.getKind() == Kind.Double) {
+                // round-to-zero - might not be right
+                asm.emitString("cvt.rz." + super.emit());
+            } else {
+                asm.emitString("cvt." + super.emit());
+            }
         }
     }
-    
+
     public static class Mov extends SingleOperandFormat {
 
+        private int predicateRegisterNumber = -1;
+
         public Mov(Variable dst, Value src) {
             super(dst, src);
         }
 
-        /*
-        public Mov(Variable dst, AbstractAddress src) {
-            throw GraalInternalError.unimplemented("AbstractAddress Mov");
+        public Mov(Variable dst, Value src, int predicate) {
+            super(dst, src);
+            this.predicateRegisterNumber = predicate;
         }
-        */
-        
+
+        /*
+         * public Mov(Variable dst, AbstractAddress src) { throw
+         * GraalInternalError.unimplemented("AbstractAddress Mov"); }
+         */
+
         public void emit(PTXAssembler asm) {
-            asm.emitString("mov." + super.emit());
+            if (predicateRegisterNumber >= 0) {
+                asm.emitString("@%p" + String.valueOf(predicateRegisterNumber) + " mov." + super.emit());
+            } else {
+                asm.emitString("mov." + super.emit());
+            }
         }
     }
-    
+
     public static class Neg extends SingleOperandFormat {
 
         public Neg(Variable dst, Variable src) {
@@ -519,8 +578,8 @@
             asm.emitString("neg." + super.emit());
         }
     }
-    
-    public static class Not extends SingleOperandFormat {
+
+    public static class Not extends BinarySingleOperandFormat {
 
         public Not(Variable dst, Variable src) {
             super(dst, src);
@@ -530,7 +589,7 @@
             asm.emitString("not." + super.emit());
         }
     }
-    
+
     public static class Ld extends LoadStoreFormat {
 
         public Ld(PTXStateSpace space, Variable dst, Variable src1, Value src2) {
@@ -557,6 +616,47 @@
         emitString("exit;" + " " + "");
     }
 
+    public static class Global {
+
+        private Kind kind;
+        private String name;
+        private LabelRef[] targets;
+
+        public Global(Value val, String name, LabelRef[] targets) {
+            this.kind = val.getKind();
+            this.name = name;
+            this.targets = targets;
+        }
+
+        private static String valueForKind(Kind k) {
+            switch (k.getTypeChar()) {
+                case 'i':
+                    return "s32";
+                case 'j':
+                    return "s64";
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+
+        private static String emitTargets(PTXAssembler asm, LabelRef[] refs) {
+            StringBuffer sb = new StringBuffer();
+
+            for (int i = 0; i < refs.length; i++) {
+                sb.append(asm.nameOf(refs[i].label()));
+                if (i < (refs.length - 1)) {
+                    sb.append(", ");
+                }
+            }
+
+            return sb.toString();
+        }
+
+        public void emit(PTXAssembler asm) {
+            asm.emitString(".global ." + valueForKind(kind) + " " + name + "[" + targets.length + "] = " + "{ " + emitTargets(asm, targets) + " };");
+        }
+    }
+
     public static class Param extends SingleOperandFormat {
 
         private boolean lastParameter;
@@ -575,8 +675,33 @@
         }
 
         public void emit(PTXAssembler asm) {
-            asm.emitString(".param ." + typeForKind(dest.getKind()) + emitParameter(dest)  + (lastParameter ? "" : ","));
+            asm.emitString(".param ." + paramForKind(dest.getKind()) + emitParameter(dest) + (lastParameter ? "" : ","));
         }
+
+        public String paramForKind(Kind k) {
+            switch (k.getTypeChar()) {
+                case 'z':
+                case 'f':
+                    return "s32";
+                case 'b':
+                    return "s8";
+                case 's':
+                    return "s16";
+                case 'c':
+                    return "u16";
+                case 'i':
+                    return "s32";
+                case 'j':
+                    return "s64";
+                case 'd':
+                    return "f64";
+                case 'a':
+                    return "u64";
+                default:
+                    throw GraalInternalError.shouldNotReachHere();
+            }
+        }
+
     }
 
     public final void popc_b32(Register d, Register a) {
@@ -595,9 +720,24 @@
         emitString("ret.uni;" + " " + "");
     }
 
-    public static class Setp  {
+    public enum BooleanOperator {
+        AND("and"), OR("or"), XOR("xor");
+
+        private final String output;
+
+        private BooleanOperator(String out) {
+            this.output = out;
+        }
 
-        private ConditionOperator  operator;
+        public String getOperator() {
+            return output + ".";
+        }
+    }
+
+    public static class Setp {
+
+        private BooleanOperator booleanOperator;
+        private ConditionOperator operator;
         private Value first, second;
         private Kind kind;
         private int predicate;
@@ -610,6 +750,15 @@
             setConditionOperator(operatorForConditon(condition));
         }
 
+        public Setp(Condition condition, BooleanOperator operator, Value first, Value second, int predicateRegisterNumber) {
+            setFirst(first);
+            setSecond(second);
+            setPredicate(predicateRegisterNumber);
+            setKind();
+            setConditionOperator(operatorForConditon(condition));
+            setBooleanOperator(operator);
+        }
+
         public void setFirst(Value v) {
             first = v;
         }
@@ -626,6 +775,10 @@
             operator = co;
         }
 
+        public void setBooleanOperator(BooleanOperator bo) {
+            booleanOperator = bo;
+        }
+
         private ConditionOperator operatorForConditon(Condition condition) {
             char typeChar = kind.getTypeChar();
 
@@ -635,12 +788,18 @@
                 case 'a':
                     // unsigned
                     switch (condition) {
-                        case EQ: return ConditionOperator.U_EQ;
-                        case NE: return ConditionOperator.U_NE;
-                        case LT: return ConditionOperator.U_LO;
-                        case LE: return ConditionOperator.U_LS;
-                        case GT: return ConditionOperator.U_HI;
-                        case GE: return ConditionOperator.U_HS;
+                        case EQ:
+                            return ConditionOperator.U_EQ;
+                        case NE:
+                            return ConditionOperator.U_NE;
+                        case LT:
+                            return ConditionOperator.U_LO;
+                        case LE:
+                            return ConditionOperator.U_LS;
+                        case GT:
+                            return ConditionOperator.U_HI;
+                        case GE:
+                            return ConditionOperator.U_HS;
                         default:
                             throw GraalInternalError.shouldNotReachHere();
                     }
@@ -650,11 +809,16 @@
                 case 'j':
                     // signed
                     switch (condition) {
-                        case EQ: return ConditionOperator.S_EQ;
-                        case NE: return ConditionOperator.S_NE;
-                        case LT: return ConditionOperator.S_LT;
-                        case LE: return ConditionOperator.S_LE;
-                        case GT: return ConditionOperator.S_GT;
+                        case EQ:
+                            return ConditionOperator.S_EQ;
+                        case NE:
+                            return ConditionOperator.S_NE;
+                        case LT:
+                            return ConditionOperator.S_LT;
+                        case LE:
+                            return ConditionOperator.S_LE;
+                        case GT:
+                            return ConditionOperator.S_GT;
                         case GE:
                         case AE:
                             return ConditionOperator.S_GE;
@@ -665,12 +829,18 @@
                 case 'd':
                     // floating point - do these need to accept NaN??
                     switch (condition) {
-                        case EQ: return ConditionOperator.F_EQ;
-                        case NE: return ConditionOperator.F_NE;
-                        case LT: return ConditionOperator.F_LT;
-                        case LE: return ConditionOperator.F_LE;
-                        case GT: return ConditionOperator.F_GT;
-                        case GE: return ConditionOperator.F_GE;
+                        case EQ:
+                            return ConditionOperator.F_EQ;
+                        case NE:
+                            return ConditionOperator.F_NE;
+                        case LT:
+                            return ConditionOperator.F_LT;
+                        case LE:
+                            return ConditionOperator.F_LE;
+                        case GT:
+                            return ConditionOperator.F_GT;
+                        case GE:
+                            return ConditionOperator.F_GE;
                         default:
                             throw GraalInternalError.shouldNotReachHere();
                     }
@@ -688,7 +858,7 @@
                 kind = first.getKind();
             }
         }
-        
+
         public String emitValue(Value v) {
             assert v != null;
 
@@ -740,16 +910,23 @@
                     throw GraalInternalError.shouldNotReachHere();
             }
         }
-        
+
         public String emitVariable(Variable v) {
             return ("%r" + v.index);
         }
 
         public void emit(PTXAssembler asm) {
-            asm.emitString("setp." + operator.getOperator() + "." + typeForKind(kind) +
-                           " %p" + predicate + emitValue(first) + emitValue(second) + ";");
+
+            if (booleanOperator != null) {
+                asm.emitString("setp." + operator.getOperator() + "." + booleanOperator.getOperator() + typeForKind(kind) + " %p" + predicate + emitValue(first) + emitValue(second) + ", %r;"); // Predicates
+// need to be objects
+
+            } else {
+                asm.emitString("setp." + operator.getOperator() + "." + typeForKind(kind) + " %p" + predicate + emitValue(first) + emitValue(second) + ";");
+            }
         }
     }
+
     @Override
     public PTXAddress makeAddress(Register base, int displacement) {
         throw GraalInternalError.shouldNotReachHere();
@@ -757,6 +934,16 @@
 
     @Override
     public PTXAddress getPlaceholder() {
-        throw GraalInternalError.unimplemented("PTXAddress.getPlaceholder()");
+        return null;
     }
+
+    @Override
+    public void jmp(Label l) {
+        String str = nameOf(l);
+        if (l.equals("?")) {
+            Thread.dumpStack();
+        }
+        bra(str);
+    }
+
 }
--- a/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.asm.test/src/com/oracle/graal/asm/test/AssemblerTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -34,6 +34,7 @@
 
 public abstract class AssemblerTest extends GraalTest {
 
+    private final MetaAccessProvider metaAccess;
     protected final CodeCacheProvider codeCache;
 
     public interface CodeGenTest {
@@ -42,12 +43,17 @@
     }
 
     public AssemblerTest() {
+        this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
         this.codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
     }
 
+    public MetaAccessProvider getMetaAccess() {
+        return metaAccess;
+    }
+
     protected InstalledCode assembleMethod(Method m, CodeGenTest test) {
-        ResolvedJavaMethod method = codeCache.lookupJavaMethod(m);
-        RegisterConfig registerConfig = codeCache.lookupRegisterConfig();
+        ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(m);
+        RegisterConfig registerConfig = codeCache.getRegisterConfig();
         CallingConvention cc = CodeUtil.getCallingConvention(codeCache, CallingConvention.Type.JavaCallee, method, false);
 
         CompilationResult compResult = new CompilationResult();
--- a/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.asm/src/com/oracle/graal/asm/Label.java	Fri Oct 11 17:21:14 2013 +0200
@@ -30,13 +30,14 @@
 public final class Label {
 
     private int position = -1;
+    private int blockId = -1;
 
     /**
      * References to instructions that jump to this unresolved label. These instructions need to be
      * patched when the label is bound using the {@link #patchInstructions(AbstractAssembler)}
      * method.
      */
-    private ArrayList<Integer> patchPositions = new ArrayList<>(4);
+    private ArrayList<Integer> patchPositions = null;
 
     /**
      * Returns the position of this label in the code buffer.
@@ -51,6 +52,14 @@
     public Label() {
     }
 
+    public Label(int id) {
+        blockId = id;
+    }
+
+    public int getBlockId() {
+        return blockId;
+    }
+
     /**
      * Binds the label to the specified position.
      * 
@@ -67,15 +76,20 @@
 
     public void addPatchAt(int branchLocation) {
         assert !isBound() : "Label is already bound " + this + " " + branchLocation + " at position " + position;
+        if (patchPositions == null) {
+            patchPositions = new ArrayList<>(2);
+        }
         patchPositions.add(branchLocation);
     }
 
     protected void patchInstructions(AbstractAssembler masm) {
         assert isBound() : "Label should be bound";
-        int target = position;
-        for (int i = 0; i < patchPositions.size(); ++i) {
-            int pos = patchPositions.get(i);
-            masm.patchJumpTarget(pos, target);
+        if (patchPositions != null) {
+            int target = position;
+            for (int i = 0; i < patchPositions.size(); ++i) {
+                int pos = patchPositions.get(i);
+                masm.patchJumpTarget(pos, target);
+            }
         }
     }
 
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -86,8 +86,8 @@
         }
     }
 
-    public AMD64LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, runtime, target, frameMap, cc, lir);
+    public AMD64LIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, metaAccess, codeCache, target, 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()) && !runtime.needsDataPatch(c);
+                return Util.isInt(c.asLong()) && !codeCache.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()) && !runtime.needsDataPatch(c);
+                return NumUtil.isInt(c.asLong()) && !codeCache.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 && !runtime.needsDataPatch(asConstant(base))) {
+            } else if (asConstant(base).getKind() != Kind.Object && !codeCache.needsDataPatch(asConstant(base))) {
                 finalDisp += asConstant(base).asLong();
                 baseRegister = Value.ILLEGAL;
             } else {
@@ -881,7 +881,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(runtime);
+            sig[i] = node.arguments().get(i).stamp().javaType(metaAccess);
         }
 
         Value[] parameters = visitInvokeArguments(frameMap.registerConfig.getCallingConvention(CallingConvention.Type.JavaCall, null, sig, target(), false), node.arguments());
@@ -890,6 +890,6 @@
 
     @Override
     public void visitInfopointNode(InfopointNode i) {
-        append(new InfopointOp(stateFor(i.getState(), DeoptimizationReason.None), i.reason));
+        append(new InfopointOp(stateFor(i.getState()), i.reason));
     }
 }
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/ForEachToGraal.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,27 +23,20 @@
 
 package com.oracle.graal.compiler.hsail;
 
-import com.oracle.graal.api.code.CompilationResult;
-import java.lang.reflect.Method;
+import java.lang.reflect.*;
 
-import com.amd.okra.OkraContext;
-import com.amd.okra.OkraKernel;
-import com.oracle.graal.hotspot.HotSpotGraalRuntime;
-import com.oracle.graal.hotspot.HotSpotVMConfig;
-import com.oracle.graal.hotspot.amd64.AMD64HotSpotRuntime;
+import com.amd.okra.*;
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.Graal;
-import com.oracle.graal.java.GraphBuilderConfiguration;
-import com.oracle.graal.java.GraphBuilderPhase;
-import com.oracle.graal.nodes.StructuredGraph;
-import com.oracle.graal.nodes.java.MethodCallTargetNode;
-import com.oracle.graal.nodes.spi.Replacements;
-import com.oracle.graal.phases.OptimisticOptimizations;
-import com.oracle.graal.graph.Node;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
-import com.oracle.graal.compiler.target.Backend;
-import com.oracle.graal.nodes.spi.GraalCodeCacheProvider;
-import com.oracle.graal.debug.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.amd64.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.phases.*;
 
 /**
  * Implements compile and dispatch of Java code containing lambda constructs. Currently only used by
@@ -51,16 +44,6 @@
  */
 public class ForEachToGraal implements CompileAndDispatch {
 
-    protected final GraalCodeCacheProvider runtime;
-    protected final Replacements replacements;
-    protected final Backend backend;
-
-    public ForEachToGraal() {
-        this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
-        this.replacements = Graal.getRequiredCapability(Replacements.class);
-        this.backend = Graal.getRequiredCapability(Backend.class);
-    }
-
     private static CompilationResult getCompiledLambda(Class consumerClass) {
         /**
          * Find the accept() method in the IntConsumer, then use Graal API to find the target lambda
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILBackend.java	Fri Oct 11 17:21:14 2013 +0200
@@ -51,8 +51,8 @@
     private Map<String, String> paramTypeMap = new HashMap<>();
     private Buffer codeBuffer;
 
-    public HSAILBackend(CodeCacheProvider runtime, TargetDescription target) {
-        super(runtime, target);
+    public HSAILBackend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target) {
+        super(metaAccess, codeCache, target);
         paramTypeMap.put("HotSpotResolvedPrimitiveType<int>", "s32");
         paramTypeMap.put("HotSpotResolvedPrimitiveType<float>", "f32");
         paramTypeMap.put("HotSpotResolvedPrimitiveType<double>", "f64");
@@ -69,12 +69,12 @@
      */
     @Override
     public FrameMap newFrameMap() {
-        return new HSAILFrameMap(runtime(), target, new HSAILRegisterConfig());
+        return new HSAILFrameMap(getCodeCache(), target, new HSAILRegisterConfig());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new HSAILLIRGenerator(graph, runtime(), target, frameMap, cc, lir);
+        return new HSAILLIRGenerator(graph, getMetaAccess(), getCodeCache(), target, frameMap, cc, lir);
     }
 
     public String getPartialCodeString() {
@@ -104,7 +104,7 @@
         FrameMap frameMap = lirGen.frameMap;
         AbstractAssembler masm = new HSAILAssembler(target);
         HotSpotFrameContext frameContext = new HotSpotFrameContext();
-        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, getCodeCache(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(frameMap.frameSize());
         return tasm;
     }
@@ -142,12 +142,12 @@
         int pidx = 0;
         for (int i = 0; i < totalParamCount; i++) {
             if (i == 0 && !isStatic) {
-                paramtypes[i] = runtime().lookupJavaType(Object.class);
+                paramtypes[i] = getMetaAccess().lookupJavaType(Object.class);
                 paramNames[i] = "%_this";
             } else if (i < nonConstantParamCount) {
                 if (isObjectLambda && (i == (nonConstantParamCount))) {
                     // Set up the gid register mapping.
-                    paramtypes[i] = runtime().lookupJavaType(int.class);
+                    paramtypes[i] = getMetaAccess().lookupJavaType(int.class);
                     paramNames[i] = "%_gid";
                 } else {
                     paramtypes[i] = signature.getParameterType(pidx++, null);
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java	Fri Oct 11 17:21:14 2013 +0200
@@ -31,17 +31,16 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.*;
-import com.oracle.graal.compiler.target.*;
 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.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * Class that represents a HSAIL compilation result. Includes the compiled HSAIL code.
@@ -49,10 +48,6 @@
 public class HSAILCompilationResult {
 
     private CompilationResult compResult;
-    protected static GraalCodeCacheProvider runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
-    protected static Replacements replacements = Graal.getRequiredCapability(Replacements.class);
-    protected static Backend backend = Graal.getRequiredCapability(Backend.class);
-    protected static SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class);
     private static final String propPkgName = HSAILCompilationResult.class.getPackage().getName();
     private static Level logLevel;
     private static ConsoleHandler consoleHandler;
@@ -78,13 +73,15 @@
     }
 
     public static HSAILCompilationResult getHSAILCompilationResult(Method meth) {
-        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(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);
         StructuredGraph graph = new StructuredGraph(javaMethod);
-        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
         return getHSAILCompilationResult(graph);
     }
 
@@ -117,17 +114,19 @@
 
     public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) {
         Debug.dump(graph, "Graph");
+        Providers providers = GraalCompiler.getGraalProviders();
         TargetDescription target = new TargetDescription(new HSAIL(), true, 8, 0, true);
-        HSAILBackend hsailBackend = new HSAILBackend(Graal.getRequiredCapability(GraalCodeCacheProvider.class), target);
+        HSAILBackend hsailBackend = new HSAILBackend(providers.getMetaAccess(), providers.getCodeCache(), target);
         PhasePlan phasePlan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, new HSAILPhase());
         new HSAILPhase().apply(graph);
         CallingConvention cc = getHSAILCallingConvention(Type.JavaCallee, target, graph.method(), false);
+        SuitesProvider suitesProvider = Graal.getRequiredCapability(SuitesProvider.class);
         try {
-            CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, hsailBackend, target, null, phasePlan, OptimisticOptimizations.NONE,
-                            new SpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult());
+            CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, graph.method(), providers, hsailBackend, target, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(),
+                            suitesProvider.getDefaultSuites(), new CompilationResult());
             return new HSAILCompilationResult(compResult);
         } catch (GraalInternalError e) {
             String partialCode = hsailBackend.getPartialCodeString();
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -66,7 +66,7 @@
 public class HSAILLIRGenerator extends LIRGenerator {
 
     private HotSpotRuntime runtime() {
-        return (HotSpotRuntime) runtime;
+        return (HotSpotRuntime) codeCache;
     }
 
     public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory {
@@ -83,8 +83,8 @@
         }
     }
 
-    public HSAILLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, runtime, target, frameMap, cc, lir);
+    public HSAILLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, metaAccess, codeCache, target, frameMap, cc, lir);
         lir.spillMoveFactory = new HSAILSpillMoveFactory();
     }
 
@@ -98,7 +98,7 @@
     public boolean canInlineConstant(Constant c) {
         switch (c.getKind()) {
             case Long:
-                return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c);
+                return NumUtil.isInt(c.asLong()) && !codeCache.needsDataPatch(c);
             case Object:
                 return c.isNull();
             default:
@@ -579,7 +579,7 @@
     }
 
     @Override
-    public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) {
+    public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) {
         append(new ReturnOp(Value.ILLEGAL));
     }
 
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ArrayPTXTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,97 +22,54 @@
  */
 package com.oracle.graal.compiler.ptx.test;
 
-import java.lang.reflect.Method;
+import static com.oracle.graal.lir.ptx.ThreadDimension.*;
 
-import org.junit.*;
+import com.oracle.graal.lir.ptx.ParallelOver;
+import com.oracle.graal.lir.ptx.Warp;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import org.junit.Test;
 
 public class ArrayPTXTest extends PTXTestBase {
 
-    @Ignore
     @Test
     public void testArray() {
-        int[] arrayI = {
-            1, 2, 3, 4, 5
+        int[] array1 = {
+            1, 2, 3, 4, 5, 6, 7, 8, 9
+        };
+        int[] array2 = {
+            1, 2, 3, 4, 5, 6, 7, 8, 9
+        };
+        int[] array3 = {
+            1, 2, 3, 4, 5, 6, 7, 8, 9
         };
-        Integer resI = (Integer) invoke(compile("testArray1I"), arrayI, 3);
-        printReport("testArray1I: " + resI);
-        // compile("testArray1J");
-        // compile("testArray1B");
-        // compile("testArray1S");
-        // compile("testArray1C");
-        // compile("testArray1F");
-        // compile("testArray1D");
-        // compile("testArray1L");
-        // compile("testStoreArray1I");
-        // compile("testStoreArray1J");
-        // compile("testStoreArray1B");
-        // compile("testStoreArray1S");
-        // compile("testStoreArray1F");
-        // compile("testStoreArray1D");
-    }
+
+        invoke(compile("testStoreArray1I"), array1, 2);
+        printReport("testStoreArray1I: " + Arrays.toString(array1));
 
-    public static int testArray1I(int[] array, int i) {
-        return array[i];
-    }
-
-    public static long testArray1J(long[] array, int i) {
-        return array[i];
-    }
+        invoke(compile("testStoreArrayWarp0"), array2, 2);
+        printReport("testStoreArrayWarp0: " + Arrays.toString(array2));
 
-    public static byte testArray1B(byte[] array, int i) {
-        return array[i];
-    }
+        invoke(compile("testStoreArrayWarp1I"), array3, 2);
+        printReport("testStoreArrayWarp1I: " + Arrays.toString(array3));
 
-    public static short testArray1S(short[] array, int i) {
-        return array[i];
-    }
-
-    public static char testArray1C(char[] array, int i) {
-        return array[i];
     }
 
-    public static float testArray1F(float[] array, int i) {
-        return array[i];
-    }
-
-    public static double testArray1D(double[] array, int i) {
-        return array[i];
-    }
-
-    public static Object testArray1L(Object[] array, int i) {
-        return array[i];
-    }
-
-    public static void testStoreArray1I(int[] array, int i, int val) {
-        array[i] = val;
-    }
-
-    public static void testStoreArray1B(byte[] array, int i, byte val) {
-        array[i] = val;
+    public static void testStoreArray1I(int[] array, int i) {
+        array[i] = 42;
     }
 
-    public static void testStoreArray1S(short[] array, int i, short val) {
-        array[i] = val;
-    }
-
-    public static void testStoreArray1J(long[] array, int i, long val) {
-        array[i] = val;
+    public static void testStoreArrayWarp0(int[] array,
+                                           @Warp(dimension = X) int i) {
+        array[i] = 42;
     }
 
-    public static void testStoreArray1F(float[] array, int i, float val) {
-        array[i] = val;
+    public static void testStoreArrayWarp1I(@ParallelOver(dimension = X) int[] array,
+                                            @Warp(dimension = X) int i) {
+        array[i] = 42;
     }
 
-    public static void testStoreArray1D(double[] array, int i, double val) {
-        array[i] = val;
-    }
-
-    public static void printReport(String message) {
-        // CheckStyle: stop system..print check
-        System.out.println(message);
-        // CheckStyle: resume system..print check
-
-    }
 
     public static void main(String[] args) {
         ArrayPTXTest test = new ArrayPTXTest();
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/BasicPTXTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,13 +24,11 @@
 
 import java.lang.reflect.Method;
 
-import org.junit.Ignore;
 import org.junit.Test;
 
 /**
  * Test class for small Java methods compiled to PTX kernels.
  */
-@Ignore
 public class BasicPTXTest extends PTXTestBase {
 
     @Test
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/ControlPTXTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -28,14 +28,54 @@
 
 public class ControlPTXTest extends PTXTestBase {
 
-    @Ignore
     @Test
     public void testControl() {
-        compile("testLoop");
-        // compile("testSwitch1I");
-        // compile("testStatic");
-        // compile("testCall");
-        // compile("testLookupSwitch1I");
+        Integer ret = (Integer) invoke(compile("testLoop"), 42);
+        if (ret != null) {
+            printReport("testLoop: " + ret);
+        } else {
+            printReport("testLoop: no VALUE");
+        }
+        ret = (Integer) invoke(compile("testSwitchDefault1I"), 3);
+        if (ret != null) {
+            printReport("testSwitchDefault1I: " + ret);
+        } else {
+            printReport("testSwitchDefault1I: no VALUE");
+        }
+        ret = (Integer) invoke(compile("testSwitch1I"), 2);
+        if (ret != null) {
+            printReport("testSwitch1I: " + ret);
+        } else {
+            printReport("testSwitch1I: no VALUE");
+        }
+        ret = (Integer) invoke(compile("testIfElse1I"), 222);
+        if (ret != null) {
+            printReport("testIfElse1I: " + ret);
+        } else {
+            printReport("testIfElse1I: no VALUE");
+        }
+        ret = (Integer) invoke(compile("testIfElse2I"), 19, 64);
+        if (ret != null) {
+            printReport("testIfElse2I: " + (char) ret.intValue());
+        } else {
+            printReport("testIfElse2I: no VALUE");
+        }
+        Boolean bret = (Boolean) invoke(compile("testIntegerTestBranch2I"),
+                                        0xff00, 0x00ff);
+        if (bret != null) {
+            printReport("testIntegerTestBranch2I: " + bret);
+            printReport("testIntegerTestBranch2I: actual: " +
+                                testIntegerTestBranch2I(0xff00, 0x00ff));
+        } else {
+            printReport("testIntegerTestBranch2I: no VALUE");
+        }
+        compile("testStatic");
+        compile("testCall");
+        compile("testLookupSwitch1I");
+    }
+
+    public static boolean testIntegerTestBranch2I(int x, int y) {
+        return (x & y) == 0;
     }
 
     public static int testLoop(int n) {
@@ -47,6 +87,31 @@
         return sum;
     }
 
+    public static int testIfElse1I(int n) {
+        if (n > 22) {
+            return 42;
+        } else {
+            return -42;
+        }
+    }
+
+    public static int testIfElse2I(int c, int y) {
+        if (c > 19) {
+            return 'M';    // millenial
+        } else if (y > 84) {
+            return 'Y';    // young
+        } else {
+            return 'O';    // old
+        }
+    }
+
+    public static int testSwitchDefault1I(int a) {
+        switch (a) {
+            default:
+                return 4;
+        }
+    }
+
     public static int testSwitch1I(int a) {
         switch (a) {
             case 1:
@@ -61,31 +126,31 @@
     public static int testLookupSwitch1I(int a) {
         switch (a) {
             case 0:
-                return 1;
+                return 10;
             case 1:
-                return 2;
+                return 11;
             case 2:
-                return 3;
+                return 12;
             case 3:
-                return 1;
+                return 13;
             case 4:
-                return 2;
+                return 14;
             case 5:
-                return 3;
+                return 15;
             case 6:
-                return 1;
+                return 16;
             case 7:
-                return 2;
+                return 17;
             case 8:
-                return 3;
+                return 18;
             case 9:
-                return 1;
+                return 19;
             case 10:
-                return 2;
+                return 20;
             case 11:
-                return 3;
+                return 21;
             default:
-                return -1;
+                return 42;
         }
     }
 
@@ -100,7 +165,7 @@
         return a + b;
     }
 
-    public static int testCall(@SuppressWarnings("unused") Object o, int a, int b) {
+    public static int testCall(int a, int b) {
         return method(a, b);
     }
 
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/FloatPTXTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -29,44 +29,46 @@
 import com.oracle.graal.api.code.CompilationResult;
 
 /* PTX ISA 3.1 - 8.7.3 Floating-Point Instructions */
-@Ignore
 public class FloatPTXTest extends PTXTestBase {
 
-    @Ignore
     @Test
     public void testAdd() {
-        CompilationResult r = compile("testAdd2F");
-        if (r.getTargetCode() == null) {
-            printReport("Compilation of testAdd2F FAILED");
+        Float ret = (Float) invoke(compile("testAdd2I"), 42, 43);
+        if (ret != null) {
+            printReport("testAdd2I: " + ret);
+        } else {
+            printReport("testAdd2I: no VALUE");
         }
 
-        /*
-        r = compile("testAdd2D");
-        if (r.getTargetCode() == null) {
-            printReport("Compilation of testAdd2D FAILED");
+        ret = (Float) invoke(compile("testAdd2F"), 42.1F, 43.5F);
+        if (ret != null) {
+            printReport("testAdd2F: " + ret);
+        } else {
+            printReport("testAdd2F: no VALUE");
         }
 
-        r = compile("testAddFConst");
-        if (r.getTargetCode() == null) {
-            printReport("Compilation of testAddFConst FAILED");
-        }
-        r = compile("testAddConstF");
-        if (r.getTargetCode() == null) {
-            printReport("Compilation of testConstF FAILED");
+        ret = (Float) invoke(compile("testAddFConst"), 42.1F);
+        if (ret != null) {
+            printReport("testAddFConst: " + ret);
+        } else {
+            printReport("testAddFConst: no VALUE");
         }
-        r = compile("testAddDConst");
-        if (r.getTargetCode() == null) {
-            printReport("Compilation of testAddDConst FAILED");
+
+        Double dret = (Double) invoke(compile("testAdd2D"), 42.1, 43.5);
+        if (dret != null) {
+            printReport("testAdd2D: " + dret);
+        } else {
+            printReport("testAdd2D: no VALUE");
         }
-        r = compile("testAddConstD");
-        if (r.getTargetCode() == null) {
-            printReport("Compilation of testConstD FAILED");
-        }
-        */
+
+    }
+
+    public static float testAdd2I(int a, int b) {
+        return a + b;
     }
 
     public static float testAdd2F(float a, float b) {
-        return a + b;
+        return (a + b);
     }
 
     public static double testAdd2D(double a, double b) {
@@ -359,13 +361,6 @@
         return (float) a;
     }
 
-    public static void printReport(String message) {
-        // CheckStyle: stop system..print check
-        System.out.println(message);
-        // CheckStyle: resume system..print check
-
-    }
-
     public static void main(String[] args) {
         FloatPTXTest test = new FloatPTXTest();
         for (Method m : FloatPTXTest.class.getMethods()) {
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/IntegerPTXTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -30,8 +30,8 @@
 
     @Test
     public void testAdd() {
-        /*
-        Integer r4 = (Integer) invoke(compile("testAdd2B"), (byte) 6, (byte) 4);
+
+        /* Integer r4 = (Integer) invoke(compile("testAdd2B"), (byte) 6, (byte) 4);
         if (r4 == null) {
             printReport("testAdd2B FAILED");
         } else if (r4.intValue() == testAdd2B((byte) 6, (byte) 4)) {
@@ -49,14 +49,14 @@
             printReport("testAdd2I FAILED");
         }
 
-        /* Long r2 = (Long) invoke(compile("testAdd2L"), (long) 12, (long) 6);
+        Long r2 = (Long) invoke(compile("testAdd2L"), (long) 12, (long) 6);
         if (r2 == null) {
             printReport("testAdd2L FAILED");
         } else if (r2.longValue() == testAdd2L(12, 6)) {
             printReport("testAdd2L PASSED");
         } else {
             printReport("testAdd2L FAILED");
-        } 
+        }
 
         r4 = (Integer) invoke(compile("testAddIConst"), 5);
         if (r4 == null) {
@@ -74,7 +74,7 @@
             printReport("testAddConstI PASSED");
         } else {
             printReport("testAddConstI FAILED");
-        } */
+        }
     }
 
     public static int testAdd2I(int a, int b) {
@@ -97,7 +97,6 @@
         return 32 + a;
     }
 
-    @Ignore
     @Test
     public void testSub() {
 
@@ -155,7 +154,6 @@
         return 32 - a;
     }
 
-    @Ignore
     @Test
     public void testMul() {
 
@@ -348,12 +346,6 @@
         return (int) a;
     }
 
-    public static void printReport(String message) {
-        // CheckStyle: stop system..print check
-        System.out.println(message);
-        // CheckStyle: resume system..print check
-
-    }
 
     public static void main(String[] args) {
         IntegerPTXTest test = new IntegerPTXTest();
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/LogicPTXTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,11 +24,9 @@
 
 import java.lang.reflect.Method;
 
-import org.junit.Ignore;
 import org.junit.Test;
 
 /* PTX ISA 3.1 - 8.7.5 Logic and Shift Instructions */
-@Ignore
 public class LogicPTXTest extends PTXTestBase {
 
     @Test
--- a/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx.test/src/com/oracle/graal/compiler/ptx/test/PTXTestBase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,60 +23,61 @@
 package com.oracle.graal.compiler.ptx.test;
 
 import static com.oracle.graal.api.code.CodeUtil.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+
+import java.lang.annotation.*;
+import java.lang.reflect.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CallingConvention.*;
-import com.oracle.graal.api.runtime.Graal;
-import com.oracle.graal.compiler.GraalCompiler;
-import com.oracle.graal.compiler.ptx.PTXBackend;
-import com.oracle.graal.compiler.test.GraalCompilerTest;
-import com.oracle.graal.debug.Debug;
-import com.oracle.graal.hotspot.meta.HotSpotRuntime;
-import com.oracle.graal.hotspot.meta.HotSpotResolvedJavaMethod;
-import com.oracle.graal.hotspot.ptx.PTXHotSpotRuntime;
-import com.oracle.graal.java.GraphBuilderConfiguration;
-import com.oracle.graal.java.GraphBuilderPhase;
-import com.oracle.graal.nodes.StructuredGraph;
-import com.oracle.graal.nodes.spi.GraalCodeCacheProvider;
-import com.oracle.graal.phases.OptimisticOptimizations;
-import com.oracle.graal.phases.PhasePlan;
+import com.oracle.graal.api.code.CallingConvention.Type;
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.compiler.ptx.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.ptx.*;
+import com.oracle.graal.java.*;
+import com.oracle.graal.lir.ptx.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.ptx.PTX;
-import java.lang.reflect.Modifier;
+import com.oracle.graal.ptx.*;
 
 public abstract class PTXTestBase extends GraalCompilerTest {
 
     private StructuredGraph sg;
 
+    public void printReport(String message) {
+        // CheckStyle: stop system..print check
+        System.out.println(message);
+        // CheckStyle: resume system..print check
+
+    }
+
     protected CompilationResult compile(String test) {
-        if (runtime instanceof PTXHotSpotRuntime) {
+        if (getCodeCache() instanceof PTXHotSpotRuntime) {
             StructuredGraph graph = parse(test);
             sg = graph;
             Debug.dump(graph, "Graph");
             TargetDescription target = new TargetDescription(new PTX(), true, 1, 0, true);
-            PTXBackend ptxBackend = new PTXBackend(Graal.getRequiredCapability(GraalCodeCacheProvider.class), target);
+            PTXBackend ptxBackend = new PTXBackend(getMetaAccess(), getCodeCache(), target);
             PhasePlan phasePlan = new PhasePlan();
-            GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE);
+            GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE);
             phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
             phasePlan.addPhase(PhasePosition.AFTER_PARSING, new PTXPhase());
             new PTXPhase().apply(graph);
-            CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
+            CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
             /*
              * Use Suites.createDefaultSuites() instead of GraalCompilerTest.suites. The
-             * GraalCompilerTest.suites variable contains the Suites for the HotSpotRuntime. This code
-             * will not run on hotspot, so it should use the plain Graal default suites, without hotspot
-             * specific phases.
-             *
-             * Ultimately we might want to have both the kernel and the code natively compiled for GPU fallback to CPU in cases
-             * of ECC failure on kernel invocation.  
+             * GraalCompilerTest.suites variable contains the Suites for the HotSpotRuntime. This
+             * code will not run on hotspot, so it should use the plain Graal default suites,
+             * without hotspot specific phases.
+             * 
+             * Ultimately we might want to have both the kernel and the code natively compiled for
+             * GPU fallback to CPU in cases of ECC failure on kernel invocation.
              */
-            CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime,
-                                                                  graalRuntime().getReplacements(), ptxBackend, target,
-                                                                  null, phasePlan,
-                                                                  OptimisticOptimizations.NONE, new SpeculationLog(),
-                                                                  Suites.createDefaultSuites(), new ExternalCompilationResult());
+            CompilationResult result = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), ptxBackend, target, null, phasePlan, OptimisticOptimizations.NONE,
+                            new SpeculationLog(), Suites.createDefaultSuites(), new ExternalCompilationResult());
             return result;
         } else {
             return null;
@@ -101,9 +102,49 @@
             HotSpotResolvedJavaMethod compiledMethod = (HotSpotResolvedJavaMethod) sg.method();
             boolean isStatic = Modifier.isStatic(compiledMethod.getModifiers());
             Object[] executeArgs = argsWithReceiver((isStatic ? null : this), args);
-            HotSpotRuntime hsr = (HotSpotRuntime) runtime;
-            InstalledCode installedCode = hsr.addExternalMethod(sg.method(), result, sg);
-            Object r = installedCode.executeVarargs(executeArgs);
+            HotSpotRuntime hsr = (HotSpotRuntime) getCodeCache();
+            InstalledCode installedCode = hsr.addExternalMethod(compiledMethod, result);
+            Annotation[][] params = compiledMethod.getParameterAnnotations();
+
+            int dimensionX = 1;
+            int dimensionY = 1;
+            int dimensionZ = 1;
+
+            for (int p = 0; p < params.length; p++) {
+                Annotation[] annos = params[p];
+                if (annos != null) {
+                    for (int a = 0; a < annos.length; a++) {
+                        Annotation aa = annos[a];
+                        if (args[p] instanceof int[] && aa.annotationType().equals(ParallelOver.class)) {
+                            int[] iarray = (int[]) args[p];
+                            ParallelOver threadBlockDimension = (ParallelOver) aa;
+                            switch (threadBlockDimension.dimension()) {
+                                case X:
+                                    dimensionX = iarray.length;
+                                    break;
+                                case Y:
+                                    dimensionY = iarray.length;
+                                    break;
+                                case Z:
+                                    dimensionZ = iarray.length;
+                                    break;
+                            }
+                        }
+                    }
+                }
+            }
+            Object r;
+            if (dimensionX != 1 || dimensionY != 1 || dimensionZ != 1) {
+                /*
+                 * for now assert that the warp array block is no larger than the number of physical
+                 * gpu cores.
+                 */
+                assert dimensionX * dimensionY * dimensionZ < PTXTargetMethodAssembler.getAvailableProcessors();
+
+                r = ((HotSpotNmethod) installedCode).executeParallel(dimensionX, dimensionY, dimensionZ, executeArgs);
+            } else {
+                r = installedCode.executeVarargs(executeArgs);
+            }
             return r;
         } catch (Throwable th) {
             th.printStackTrace();
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXBackend.java	Fri Oct 11 17:21:14 2013 +0200
@@ -48,8 +48,8 @@
  */
 public class PTXBackend extends Backend {
 
-    public PTXBackend(CodeCacheProvider runtime, TargetDescription target) {
-        super(runtime, target);
+    public PTXBackend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target) {
+        super(metaAccess, codeCache, target);
     }
 
     @Override
@@ -59,12 +59,12 @@
 
     @Override
     public FrameMap newFrameMap() {
-        return new PTXFrameMap(runtime(), target, runtime().lookupRegisterConfig());
+        return new PTXFrameMap(getCodeCache(), target, getCodeCache().getRegisterConfig());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new PTXLIRGenerator(graph, runtime(), target, frameMap, cc, lir);
+        return new PTXLIRGenerator(graph, getMetaAccess(), getCodeCache(), target, frameMap, cc, lir);
     }
 
     class HotSpotFrameContext implements FrameContext {
@@ -94,7 +94,7 @@
         FrameMap frameMap = lirGen.frameMap;
         AbstractAssembler masm = createAssembler(frameMap);
         HotSpotFrameContext frameContext = new HotSpotFrameContext();
-        TargetMethodAssembler tasm = new PTXTargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new PTXTargetMethodAssembler(target, getCodeCache(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(0);
         return tasm;
     }
@@ -109,8 +109,8 @@
         Buffer codeBuffer = tasm.asm.codeBuffer;
 
         // Emit initial boiler-plate directives.
-        codeBuffer.emitString(".version 1.4");
-        codeBuffer.emitString(".target sm_10");
+        codeBuffer.emitString(".version 3.0");
+        codeBuffer.emitString(".target sm_30");
         codeBuffer.emitString0(".entry " + name + " (");
         codeBuffer.emitString("");
 
@@ -140,9 +140,10 @@
     }
 
     // Emit .reg space declarations
-    private static void emitRegisterDecl(TargetMethodAssembler tasm, LIRGenerator lirGen,
-                                         ResolvedJavaMethod codeCacheOwner) {
+    private static void emitRegisterDecl(TargetMethodAssembler tasm, LIRGenerator lirGen, ResolvedJavaMethod codeCacheOwner) {
+
         assert codeCacheOwner != null : lirGen.getGraph() + " is not associated with a method";
+
         Buffer codeBuffer = tasm.asm.codeBuffer;
 
         final SortedSet<Integer> signed32 = new TreeSet<>();
@@ -231,6 +232,7 @@
         if (maxPredRegNum > 0) {
             codeBuffer.emitString(".reg .pred %p<" + maxPredRegNum + ">;");
         }
+        codeBuffer.emitString(".reg .pred %r;");  // used for setp bool
     }
 
     @Override
@@ -246,7 +248,7 @@
         } catch (GraalInternalError e) {
             e.printStackTrace();
             // TODO : Better error handling needs to be done once
-            //        all types of parameters are handled.
+            // all types of parameters are handled.
             codeBuffer.setPosition(0);
             codeBuffer.close(false);
             return;
@@ -257,7 +259,7 @@
         } catch (GraalInternalError e) {
             e.printStackTrace();
             // TODO : Better error handling needs to be done once
-            //        all types of parameters are handled.
+            // all types of parameters are handled.
             codeBuffer.setPosition(0);
             codeBuffer.close(false);
             return;
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -46,6 +46,8 @@
 import com.oracle.graal.lir.ptx.PTXArithmetic.Unary2Op;
 import com.oracle.graal.lir.ptx.PTXCompare.CompareOp;
 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.ReturnOp;
 import com.oracle.graal.lir.ptx.PTXControlFlow.ReturnNoValOp;
 import com.oracle.graal.lir.ptx.PTXControlFlow.SequentialSwitchOp;
@@ -62,6 +64,8 @@
 import com.oracle.graal.nodes.calc.ConvertNode.Op;
 import com.oracle.graal.nodes.java.*;
 
+import java.lang.annotation.*;
+
 /**
  * This class implements the PTX specific portion of the LIR generator.
  */
@@ -83,8 +87,8 @@
         }
     }
 
-    public PTXLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, runtime, target, frameMap, cc, lir);
+    public PTXLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, metaAccess, codeCache, target, frameMap, cc, lir);
         lir.spillMoveFactory = new PTXSpillMoveFactory();
         int callVariables = cc.getArgumentCount() + (cc.getReturn() == Value.ILLEGAL ? 0 : 1);
         lir.setFirstVariableNumber(callVariables);
@@ -105,7 +109,7 @@
     public boolean canInlineConstant(Constant c) {
         switch (c.getKind()) {
             case Long:
-                return NumUtil.isInt(c.asLong()) && !runtime.needsDataPatch(c);
+                return NumUtil.isInt(c.asLong()) && !codeCache.needsDataPatch(c);
             case Object:
                 return c.isNull();
             default:
@@ -132,22 +136,62 @@
     public void emitPrologue() {
         // Need to emit .param directives based on incoming arguments and return value
         CallingConvention incomingArguments = cc;
-        int argCount = incomingArguments.getArgumentCount();
-        // Additional argument for return value.
-        Variable[] params = new Variable[argCount + 1];
-        for (int i = 0; i < argCount; i++) {
-            params[i] = (Variable) incomingArguments.getArgument(i);
+        Object returnObject = incomingArguments.getReturn();
+        AllocatableValue[] params;
+        int argCount;
+
+        if (returnObject == Value.ILLEGAL) {
+            params = incomingArguments.getArguments();
+        } else {
+            argCount = incomingArguments.getArgumentCount();
+            params = new Variable[argCount + 1];
+            for (int i = 0; i < argCount; i++) {
+                params[i] = incomingArguments.getArgument(i);
+            }
+            params[argCount] = (Variable) returnObject;
         }
-        // Add the return value as the last parameter.
-        params[argCount] =  (Variable) incomingArguments.getReturn();
 
         append(new PTXParameterOp(params));
         for (LocalNode local : graph.getNodes(LocalNode.class)) {
             Value param = params[local.index()];
-            setResult(local, emitLoadParam(param.getKind(), param, null));
+            Annotation[] annos = graph.method().getParameterAnnotations()[local.index()];
+            Warp warpAnnotation = null;
+
+            if (annos != null) {
+                for (int a = 0; a < annos.length; a++) {
+                    if (annos[a].annotationType().equals(Warp.class)) {
+                        warpAnnotation = (Warp) annos[a];
+                    }
+                }
+            }
+            if (warpAnnotation != null) {
+                setResult(local, emitWarpParam(param.getKind(), warpAnnotation));
+            } else {
+                setResult(local, emitLoadParam(param.getKind(), param, null));
+            }
         }
     }
 
+    public Variable emitWarpParam(Kind kind, Warp annotation) {
+        Variable result = newVariable(kind);
+        Variable tid = newVariable(Kind.Char);
+
+        switch (annotation.dimension()) {
+            case X:
+                tid.setName("%tid.x");
+                break;
+            case Y:
+                tid.setName("%tid.y");
+                break;
+            case Z:
+                tid.setName("%tid.y");
+                break;
+        }
+        emitMove(result, tid);
+
+        return result;
+    }
+
     @Override
     public Variable emitMove(Value input) {
         Variable result = newVariable(input.getKind());
@@ -168,38 +212,47 @@
     public PTXAddressValue emitAddress(Value base, long displacement, Value index, int scale) {
         AllocatableValue baseRegister;
         long finalDisp = displacement;
+
         if (isConstant(base)) {
             if (asConstant(base).isNull()) {
                 baseRegister = Value.ILLEGAL;
-            } else if (asConstant(base).getKind() != Kind.Object) {
+            } else if (asConstant(base).getKind() != Kind.Object && !codeCache.needsDataPatch(asConstant(base))) {
                 finalDisp += asConstant(base).asLong();
                 baseRegister = Value.ILLEGAL;
             } else {
                 baseRegister = load(base);
             }
+        } else if (base.equals(Value.ILLEGAL)) {
+            baseRegister = Value.ILLEGAL;
         } else {
             baseRegister = asAllocatable(base);
         }
 
-        @SuppressWarnings("unused") Value indexRegister;
-        if (!index.equals(Value.ILLEGAL) && scale != 0) {
+        if (!index.equals(Value.ILLEGAL)) {
             if (isConstant(index)) {
                 finalDisp += asConstant(index).asLong() * scale;
-                indexRegister = Value.ILLEGAL;
             } else {
+                Value convertedIndex;
+                Value indexRegister;
+
+                convertedIndex = emitConvert(Op.I2L, index);
                 if (scale != 1) {
-                    Variable longIndex = emitConvert(Op.I2L, index);
                     if (CodeUtil.isPowerOf2(scale)) {
-                        indexRegister = emitShl(longIndex, Constant.forLong(CodeUtil.log2(scale)));
+                        indexRegister = emitShl(convertedIndex, Constant.forInt(CodeUtil.log2(scale)));
                     } else {
-                        indexRegister = emitMul(longIndex, Constant.forLong(scale));
+                        indexRegister = emitMul(convertedIndex, Constant.forInt(scale));
                     }
                 } else {
-                    indexRegister = asAllocatable(index);
+                    indexRegister = convertedIndex;
+                }
+                if (baseRegister.equals(Value.ILLEGAL)) {
+                    baseRegister = asAllocatable(indexRegister);
+                } else {
+                    Variable longBaseRegister = newVariable(Kind.Long);
+                    emitMove(longBaseRegister, baseRegister);
+                    baseRegister = emitAdd(longBaseRegister, indexRegister);
                 }
             }
-        } else {
-            indexRegister = Value.ILLEGAL;
         }
 
         return new PTXAddressValue(target().wordKind, baseRegister, finalDisp);
@@ -275,21 +328,100 @@
 
     @Override
     public void emitIntegerTestBranch(Value left, Value right, boolean negated, LabelRef label) {
-        throw GraalInternalError.unimplemented("PTXLIRGenerator.emitIntegerTestBranch()");
+        // / emitIntegerTest(left, right);
+        // append(new BranchOp(negated ? Condition.NE : Condition.EQ, label));
+        throw GraalInternalError.unimplemented("emitIntegerTestBranch()");
     }
 
     @Override
     public Variable emitConditionalMove(Value left, Value right, Condition cond, boolean unorderedIsTrue, Value trueValue, Value falseValue) {
-        // TODO: There is no conventional conditional move instruction in PTX.
-        // So, this method is changed to throw NYI exception.
-        // To be revisited if this needs to be really implemented.
-        throw GraalInternalError.unimplemented("PTXLIRGenerator.emitConditionalMove()");
+
+        Condition finalCondition = LIRValueUtil.isVariable(right) ? cond.mirror() : cond;
+
+        emitCompare(finalCondition, left, right);
+
+        Variable result = newVariable(trueValue.getKind());
+        switch (left.getKind().getStackKind()) {
+            case Int:
+            case Long:
+            case Object:
+                append(new CondMoveOp(result, finalCondition, load(trueValue), loadNonConst(falseValue), nextPredRegNum));
+                nextPredRegNum++;
+                break;
+            case Float:
+            case Double:
+                append(new FloatCondMoveOp(result, finalCondition, unorderedIsTrue, load(trueValue), load(falseValue), nextPredRegNum));
+                nextPredRegNum++;
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("" + left.getKind());
+        }
+        return result;
     }
 
+    /**
+     * This method emits the compare instruction, and may reorder the operands. It returns true if
+     * it did so.
+     * 
+     * @param a the left operand of the comparison
+     * @param b the right operand of the comparison
+     * @return true if the left and right operands were switched, false otherwise
+     */
+    private boolean emitCompare(Condition cond, Value a, Value b) {
+        Variable left;
+        Value right;
+        boolean mirrored;
+        if (LIRValueUtil.isVariable(b)) {
+            left = load(b);
+            right = loadNonConst(a);
+            mirrored = true;
+        } else {
+            left = load(a);
+            right = loadNonConst(b);
+            mirrored = false;
+        }
+        switch (left.getKind().getStackKind()) {
+            case Int:
+                append(new CompareOp(ICMP, cond, left, right, nextPredRegNum));
+                break;
+            case Long:
+                append(new CompareOp(LCMP, cond, left, right, nextPredRegNum));
+                break;
+            case Object:
+                append(new CompareOp(ACMP, cond, left, right, nextPredRegNum));
+                break;
+            case Float:
+                append(new CompareOp(FCMP, cond, left, right, nextPredRegNum));
+                break;
+            case Double:
+                append(new CompareOp(DCMP, cond, left, right, nextPredRegNum));
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+        return mirrored;
+    }
 
     @Override
     public Variable emitIntegerTestMove(Value left, Value right, Value trueValue, Value falseValue) {
-        throw new InternalError("NYI");
+
+        emitIntegerTest(left, right);
+        Variable result = newVariable(trueValue.getKind());
+        append(new CondMoveOp(result, Condition.EQ, load(trueValue), loadNonConst(falseValue), nextPredRegNum));
+        nextPredRegNum++;
+
+        return result;
+    }
+
+    private void emitIntegerTest(Value a, Value b) {
+
+        assert a.getKind().getStackKind() == Kind.Int || a.getKind() == Kind.Long;
+
+        if (LIRValueUtil.isVariable(b)) {
+            append(new PTXTestOp(load(b), loadNonConst(a), nextPredRegNum));
+        } else {
+            append(new PTXTestOp(load(a), loadNonConst(b), nextPredRegNum));
+        }
     }
 
     @Override
@@ -504,7 +636,7 @@
                 append(new Op2Stack(ISHL, result, a, loadNonConst(b)));
                 break;
             case Long:
-                append(new Op1Stack(LSHL, result, loadNonConst(b)));
+                append(new Op2Stack(LSHL, result, a, loadNonConst(b)));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -520,7 +652,7 @@
                 append(new Op2Stack(ISHR, result, a, loadNonConst(b)));
                 break;
             case Long:
-                append(new Op1Stack(LSHR, result, loadNonConst(b)));
+                append(new Op2Stack(LSHR, result, a, loadNonConst(b)));
                 break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
@@ -619,7 +751,7 @@
     }
 
     @Override
-    public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) {
+    public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) {
         append(new ReturnOp(Value.ILLEGAL));
     }
 
@@ -711,10 +843,10 @@
         // Making a copy of the switch value is necessary because jump table destroys the input
         // value
         if (key.getKind() == Kind.Int || key.getKind() == Kind.Long) {
-            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL, nextPredRegNum));
+            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, Value.ILLEGAL, nextPredRegNum++));
         } else {
             assert key.getKind() == Kind.Object : key.getKind();
-            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object), nextPredRegNum));
+            append(new SequentialSwitchOp(keyConstants, keyTargets, defaultTarget, key, newVariable(Kind.Object), nextPredRegNum++));
         }
     }
 
@@ -764,20 +896,36 @@
     }
 
     public Variable emitLoadParam(Kind kind, Value address, DeoptimizingNode deopting) {
+
         PTXAddressValue loadAddress = asAddress(address);
         Variable result = newVariable(kind);
         append(new LoadParamOp(kind, result, loadAddress, deopting != null ? state(deopting) : null));
+
         return result;
     }
 
     public Variable emitLoadReturnAddress(Kind kind, Value address, DeoptimizingNode deopting) {
+
         PTXAddressValue loadAddress = asAddress(address);
-        Variable result = newVariable(kind);
+        Variable result;
+        switch (kind) {
+            case Float:
+                result = newVariable(Kind.Int);
+                break;
+            case Double:
+                result = newVariable(Kind.Long);
+                break;
+            default:
+                result = newVariable(kind);
+
+        }
         append(new LoadReturnAddrOp(kind, result, loadAddress, deopting != null ? state(deopting) : null));
+
         return result;
     }
 
     public void emitStoreReturnValue(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) {
+
         PTXAddressValue storeAddress = asAddress(address);
         Variable input = load(inputVal);
         append(new StoreReturnValOp(kind, storeAddress, input, deopting != null ? state(deopting) : null));
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXTargetMethodAssembler.java	Fri Oct 11 17:21:14 2013 +0200
@@ -33,25 +33,41 @@
 
 public class PTXTargetMethodAssembler extends TargetMethodAssembler {
 
-    private static CompilerToGPU toGPU = HotSpotGraalRuntime.graalRuntime().getCompilerToGPU();
+    private static CompilerToGPU toGPU =
+                    HotSpotGraalRuntime.graalRuntime().getCompilerToGPU();
+
     private static boolean validDevice = toGPU.deviceInit();
 
+    private static final int totalProcessors =
+                            (validDevice ? toGPU.availableProcessors() : 0);
+
+    public static int getAvailableProcessors() {
+        return totalProcessors;
+    }
+
     // detach ??
 
-    public PTXTargetMethodAssembler(TargetDescription target, CodeCacheProvider runtime, FrameMap frameMap,
-                                    AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) {
-        super(target, runtime, frameMap, asm, frameContext, compilationResult);
+    public PTXTargetMethodAssembler(TargetDescription target,
+                                    CodeCacheProvider codeCache,
+                                    FrameMap frameMap,
+                                    AbstractAssembler asm,
+                                    FrameContext frameContext,
+                                    CompilationResult compilationResult) {
+        super(target, codeCache, frameMap, asm, frameContext, compilationResult);
     }
 
     @Override
     public CompilationResult finishTargetMethod(StructuredGraph graph) {
         ResolvedJavaMethod method = graph.method();
         assert method != null : graph + " is not associated wth a method";
-        ExternalCompilationResult graalCompile = (ExternalCompilationResult) super.finishTargetMethod(graph);
+
+        ExternalCompilationResult graalCompile =
+            (ExternalCompilationResult) super.finishTargetMethod(graph);
 
         try {
             if ((validDevice) && (graalCompile.getTargetCode() != null)) {
-                long kernel = toGPU.generateKernel(graalCompile.getTargetCode(), method.getName());
+                long kernel = toGPU.generateKernel(graalCompile.getTargetCode(),
+                                                   method.getName());
                 graalCompile.setEntryPoint(kernel);
             }
         } catch (Throwable th) {
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -77,8 +77,8 @@
         }
     }
 
-    public SPARCLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, runtime, target, frameMap, cc, lir);
+    public SPARCLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, metaAccess, codeCache, target, frameMap, cc, lir);
         lir.spillMoveFactory = new SPARCSpillMoveFactory();
     }
 
@@ -98,9 +98,9 @@
     public boolean canInlineConstant(Constant c) {
         switch (c.getKind()) {
             case Int:
-                return SPARCAssembler.isSimm13(c.asInt()) && !runtime.needsDataPatch(c);
+                return SPARCAssembler.isSimm13(c.asInt()) && !codeCache.needsDataPatch(c);
             case Long:
-                return SPARCAssembler.isSimm13(c.asLong()) && !runtime.needsDataPatch(c);
+                return SPARCAssembler.isSimm13(c.asLong()) && !codeCache.needsDataPatch(c);
             case Object:
                 return c.isNull();
             default:
@@ -837,7 +837,7 @@
     }
 
     @Override
-    public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) {
+    public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) {
         append(new ReturnOp(Value.ILLEGAL));
     }
 
@@ -850,7 +850,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(runtime);
+            sig[i] = node.arguments().get(i).stamp().javaType(metaAccess);
         }
 
         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/BoxingEliminationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/BoxingEliminationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -307,7 +307,7 @@
     private void processMethod(final String snippet) {
         graph = parse(snippet);
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new PartialEscapePhase(false, new CanonicalizerPhase(true)).apply(graph, context);
     }
@@ -324,7 +324,7 @@
                 graph = parse(snippet);
 
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 if (loopPeeling) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CompareCanonicalizerTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -36,7 +36,7 @@
 
     private StructuredGraph getCanonicalizedGraph(String name) {
         StructuredGraph graph = parse(name);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         return graph;
     }
 
@@ -54,7 +54,7 @@
             assertEquals(referenceGraph, graph);
         }
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(runtime(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
         for (int i = 1; i < 4; i++) {
             StructuredGraph graph = getCanonicalizedGraph("canonicalCompare" + i);
             assertEquals(referenceGraph, graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ConditionalEliminationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -141,8 +141,8 @@
         test("testNullnessSnippet", new Object(), new Object());
 
         StructuredGraph graph = parse("testNullnessSnippet");
-        new ConditionalEliminationPhase(runtime()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
+        new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) {
             assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0);
         }
@@ -164,7 +164,7 @@
     @Test
     public void testDisjunction() {
         StructuredGraph graph = parse("testDisjunctionSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         IfNode ifNode = (IfNode) graph.start().next();
         InstanceOfNode instanceOf = (InstanceOfNode) ifNode.condition();
         IsNullNode x = graph.unique(new IsNullNode(graph.getLocal(0)));
@@ -172,9 +172,9 @@
         ShortCircuitOrNode disjunction = graph.unique(new ShortCircuitOrNode(x, false, y, false, NOT_FREQUENT_PROBABILITY));
         LogicNegationNode negation = graph.unique(new LogicNegationNode(disjunction));
         ifNode.setCondition(negation);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
-        new ConditionalEliminationPhase(runtime()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
+        new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         for (ConstantNode constant : graph.getNodes().filter(ConstantNode.class)) {
             assertTrue("unexpected constant: " + constant, constant.asConstant().isNull() || constant.asConstant().asInt() > 0);
         }
@@ -192,8 +192,8 @@
     public void testInvoke() {
         test("testInvokeSnippet", new Integer(16));
         StructuredGraph graph = parse("testInvokeSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
-        new ConditionalEliminationPhase(runtime()).apply(graph);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
+        new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
 
         InvokeNode invoke = graph.getNodes().filter(InvokeNode.class).first();
         assertEquals(InvokeKind.Special, ((MethodCallTargetNode) invoke.callTarget()).invokeKind());
@@ -222,9 +222,9 @@
     @Test
     public void testTypeMerging() {
         StructuredGraph graph = parse("testTypeMergingSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
-        new ConditionalEliminationPhase(runtime()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
+        new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
 
         assertEquals(0, graph.getNodes().filter(StoreFieldNode.class).count());
     }
@@ -239,9 +239,9 @@
     @Test
     public void testInstanceOfCheckCast() {
         StructuredGraph graph = parse("testInstanceOfCheckCastSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
-        new ConditionalEliminationPhase(runtime()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
+        new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
 
         assertEquals(0, graph.getNodes().filter(CheckCastNode.class).count());
     }
@@ -252,11 +252,11 @@
         StructuredGraph graph = parse("testInstanceOfCheckCastSnippet");
 
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
-        PhaseContext context = new PhaseContext(runtime(), null, replacements);
+        PhaseContext context = new PhaseContext(getProviders(), null);
 
         new LoweringPhase(canonicalizer).apply(graph, context);
         canonicalizer.apply(graph, context);
-        new ConditionalEliminationPhase(runtime()).apply(graph);
+        new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
         canonicalizer.apply(graph, context);
 
         assertEquals(0, graph.getNodes().filter(GuardNode.class).count());
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/DegeneratedLoopsTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -82,7 +82,7 @@
 
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new CanonicalizerPhase(true).apply(graph, context);
                 Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/EliminateNestedCheckCastsTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -114,7 +114,7 @@
             public StructuredGraph call() throws Exception {
                 Debug.dump(graph, "After parsing: " + snippet);
                 Assert.assertEquals(checkcasts, graph.getNodes().filter(CheckCastNode.class).count());
-                new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements));
+                new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
                 Assert.assertEquals(afterCanon, graph.getNodes().filter(CheckCastNode.class).count());
                 return graph;
             }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -63,12 +63,12 @@
     private StructuredGraph parseAndProcess(Class cl, Assumptions assumptions) {
         Constructor<?>[] constructors = cl.getConstructors();
         Assert.assertTrue(constructors.length == 1);
-        final ResolvedJavaMethod javaMethod = runtime.lookupJavaConstructor(constructors[0]);
+        final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaConstructor(constructors[0]);
         StructuredGraph graph = new StructuredGraph(javaMethod);
 
         GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault();
-        new GraphBuilderPhase(runtime, conf, OptimisticOptimizations.ALL).apply(graph);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        new GraphBuilderPhase(getMetaAccess(), conf, OptimisticOptimizations.ALL).apply(graph);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         return graph;
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FloatingReadTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -58,7 +58,7 @@
 
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                PhaseContext context = new PhaseContext(runtime(), new Assumptions(false), replacements);
+                PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new FloatingReadPhase().apply(graph);
 
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -52,6 +52,7 @@
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.test.*;
 
@@ -76,14 +77,20 @@
  */
 public abstract class GraalCompilerTest extends GraalTest {
 
-    protected final GraalCodeCacheProvider runtime;
-    protected final Replacements replacements;
+    private final CodeCacheProvider codeCache;
+    private final MetaAccessProvider metaAccess;
+    private final ConstantReflectionProvider constantReflection;
+    private final LoweringProvider lowerer;
+    private final Replacements replacements;
     protected final Backend backend;
     protected final Suites suites;
 
     public GraalCompilerTest() {
         this.replacements = Graal.getRequiredCapability(Replacements.class);
-        this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
+        this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
+        this.constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class);
+        this.codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
+        this.lowerer = Graal.getRequiredCapability(LoweringProvider.class);
         this.backend = Graal.getRequiredCapability(Backend.class);
         this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
     }
@@ -158,8 +165,24 @@
         return result.toString();
     }
 
-    protected GraalCodeCacheProvider runtime() {
-        return runtime;
+    protected Providers getProviders() {
+        return new Providers(metaAccess, codeCache, constantReflection, lowerer, getReplacements());
+    }
+
+    protected CodeCacheProvider getCodeCache() {
+        return codeCache;
+    }
+
+    protected ConstantReflectionProvider getConstantReflection() {
+        return constantReflection;
+    }
+
+    protected MetaAccessProvider getMetaAccess() {
+        return metaAccess;
+    }
+
+    protected LoweringProvider getLowerer() {
+        return lowerer;
     }
 
     /**
@@ -324,7 +347,7 @@
         before(method);
         Object[] executeArgs = argsWithReceiver(receiver, args);
 
-        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method);
         checkArgs(javaMethod, executeArgs);
 
         InstalledCode compiledMethod = getCode(javaMethod, parse(method));
@@ -347,7 +370,7 @@
             if (kind == Kind.Object) {
                 if (arg != null && javaType instanceof ResolvedJavaType) {
                     ResolvedJavaType resolvedJavaType = (ResolvedJavaType) javaType;
-                    Assert.assertTrue(resolvedJavaType + " from " + runtime.lookupJavaType(arg.getClass()), resolvedJavaType.isAssignableFrom(runtime.lookupJavaType(arg.getClass())));
+                    Assert.assertTrue(resolvedJavaType + " from " + metaAccess.lookupJavaType(arg.getClass()), resolvedJavaType.isAssignableFrom(metaAccess.lookupJavaType(arg.getClass())));
                 }
             } else {
                 Assert.assertNotNull(arg);
@@ -384,7 +407,7 @@
 
     protected void test(Method method, Object receiver, Object... args) {
         Result expect = executeExpected(method, receiver, args);
-        if (runtime == null) {
+        if (getCodeCache() == null) {
             return;
         }
         testAgainstExpected(method, expect, receiver, args);
@@ -396,7 +419,7 @@
 
     protected Result executeActualCheckDeopt(Method method, Set<DeoptimizationReason> shouldNotDeopt, Object receiver, Object... args) {
         Map<DeoptimizationReason, Integer> deoptCounts = new EnumMap<>(DeoptimizationReason.class);
-        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method);
         ProfilingInfo profile = javaMethod.getProfilingInfo();
         for (DeoptimizationReason reason : shouldNotDeopt) {
             deoptCounts.put(reason, profile.getDeoptimizationCount(reason));
@@ -456,7 +479,7 @@
 
         final int id = compilationId.incrementAndGet();
 
-        InstalledCode installedCode = Debug.scope("Compiling", new Object[]{runtime, new DebugDumpScope(String.valueOf(id), true)}, new Callable<InstalledCode>() {
+        InstalledCode installedCode = Debug.scope("Compiling", new Object[]{new DebugDumpScope(String.valueOf(id), true)}, new Callable<InstalledCode>() {
 
             public InstalledCode call() throws Exception {
                 final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
@@ -465,15 +488,15 @@
                 }
                 long start = System.currentTimeMillis();
                 PhasePlan phasePlan = new PhasePlan();
-                GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
+                GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
                 phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-                CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
-                final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
-                                new SpeculationLog(), suites, new CompilationResult());
+                CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
+                final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), backend, getCodeCache().getTarget(), null, phasePlan,
+                                OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult());
                 if (printCompilation) {
                     TTY.println(String.format("@%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, compResult.getTargetCodeSize()));
                 }
-                return Debug.scope("CodeInstall", new Object[]{runtime, method}, new Callable<InstalledCode>() {
+                return Debug.scope("CodeInstall", new Object[]{getCodeCache(), method}, new Callable<InstalledCode>() {
 
                     @Override
                     public InstalledCode call() throws Exception {
@@ -507,7 +530,7 @@
     }
 
     protected InstalledCode addMethod(final ResolvedJavaMethod method, final CompilationResult compResult) {
-        return runtime.addMethod(method, compResult);
+        return getCodeCache().addMethod(method, compResult);
     }
 
     /**
@@ -544,9 +567,9 @@
 
     private StructuredGraph parse0(Method m, GraphBuilderConfiguration conf) {
         assert m.getAnnotation(Test.class) == null : "shouldn't parse method with @Test annotation: " + m;
-        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(m);
+        ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(m);
         StructuredGraph graph = new StructuredGraph(javaMethod);
-        new GraphBuilderPhase(runtime, conf, OptimisticOptimizations.ALL).apply(graph);
+        new GraphBuilderPhase(metaAccess, conf, OptimisticOptimizations.ALL).apply(graph);
         return graph;
     }
 
@@ -558,7 +581,11 @@
         PhasePlan plan = new PhasePlan();
         GraphBuilderConfiguration gbConf = GraphBuilderConfiguration.getEagerDefault();
         gbConf.setEagerInfopointMode(eagerInfopointMode);
-        plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, gbConf, OptimisticOptimizations.ALL));
+        plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(metaAccess, gbConf, OptimisticOptimizations.ALL));
         return plan;
     }
+
+    protected Replacements getReplacements() {
+        return replacements;
+    }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/IfCanonicalizerTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -145,7 +145,7 @@
             n.replaceFirstInput(local, constant);
         }
         Debug.dump(graph, "Graph");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         for (FrameState fs : local.usages().filter(FrameState.class).snapshot()) {
             fs.replaceFirstInput(local, null);
         }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InfopointReasonTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -58,8 +58,8 @@
     public void callInfopoints() {
         final Method method = getMethod("testMethod");
         final StructuredGraph graph = parse(method);
-        CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
-        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, getDefaultPhasePlan(),
+        CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
+        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(),
                         OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult());
         for (Infopoint sp : cr.getInfopoints()) {
             assertNotNull(sp.reason);
@@ -80,8 +80,8 @@
             }
         }
         assertTrue(graphLineSPs > 0);
-        CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
-        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, getDefaultPhasePlan(true),
+        CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
+        final CompilationResult cr = GraalCompiler.compileGraph(graph, cc, graph.method(), getProviders(), backend, getCodeCache().getTarget(), null, getDefaultPhasePlan(true),
                         OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult());
         int lineSPs = 0;
         for (Infopoint sp : cr.getInfopoints()) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeExceptionTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -66,7 +66,7 @@
             hints.put(invoke, 1000d);
         }
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/InvokeHintsTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -77,7 +77,7 @@
         }
 
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -61,7 +61,7 @@
         test("testSynchronizedSnippet", new A(), new A());
 
         StructuredGraph graph = getGraph("testSynchronizedSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         new LockEliminationPhase().apply(graph);
         assertEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
         assertEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -79,7 +79,7 @@
         test("testSynchronizedMethodSnippet", new A());
 
         StructuredGraph graph = getGraph("testSynchronizedMethodSnippet");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), null, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), null));
         new LockEliminationPhase().apply(graph);
         assertEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
         assertEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
@@ -90,7 +90,7 @@
         StructuredGraph graph = parse(method);
         PhasePlan phasePlan = getDefaultPhasePlan();
         Assumptions assumptions = new Assumptions(true);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL);
         new CanonicalizerPhase(true).apply(graph, context);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LoopUnswitchTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -134,8 +134,8 @@
         }
 
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements));
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(runtime(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
         Debug.scope("Test", new DebugDumpScope("Test:" + snippet), new Runnable() {
 
             @Override
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -94,7 +94,7 @@
     /**
      * In this case the read should be scheduled in the first block.
      */
-    public static int testSplitSnippet1(int a) {
+    public static int testSplit1Snippet(int a) {
         try {
             return container.a;
         } finally {
@@ -109,7 +109,7 @@
     @Test
     public void testSplit1() {
         for (TestMode mode : TestMode.values()) {
-            SchedulePhase schedule = getFinalSchedule("testSplitSnippet1", mode, MemoryScheduling.OPTIMAL);
+            SchedulePhase schedule = getFinalSchedule("testSplit1Snippet", mode, MemoryScheduling.OPTIMAL);
             assertReadWithinStartBlock(schedule, true);
             assertReadWithinReturnBlock(schedule, false);
         }
@@ -209,6 +209,42 @@
         assertReadWithinReturnBlock(schedule, false);
     }
 
+    public String testStringReplaceSnippet(String input) {
+        return input.replace('a', 'b');
+    }
+
+    @Test
+    public void testStringReplace() {
+        getFinalSchedule("testStringReplaceSnippet", TestMode.INLINED_WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL);
+        test("testStringReplaceSnippet", "acbaaa");
+    }
+
+    /**
+     * Here the read should float out of the loop.
+     */
+    public static int testLoop5Snippet(int a, int b, MemoryScheduleTest obj) {
+        int ret = 0;
+        int bb = b;
+        for (int i = 0; i < a; i++) {
+            ret = obj.hash;
+            if (a > 10) {
+                bb++;
+            } else {
+                bb--;
+            }
+            ret = ret / 10;
+        }
+        return ret + bb;
+    }
+
+    @Test
+    public void testLoop5() {
+        SchedulePhase schedule = getFinalSchedule("testLoop5Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL);
+        assertEquals(7, schedule.getCFG().getBlocks().length);
+        assertReadWithinStartBlock(schedule, false);
+        assertReadWithinReturnBlock(schedule, false);
+    }
+
     /**
      * Here the read should float to the end (into the same block as the return).
      */
@@ -312,6 +348,25 @@
     }
 
     /**
+     * Here the read should float to the end.
+     */
+    public static int testIfRead5Snippet(int a) {
+        if (a < 0) {
+            container.a = 10;
+        }
+        return container.a;
+    }
+
+    @Test
+    public void testIfRead5() {
+        SchedulePhase schedule = getFinalSchedule("testIfRead5Snippet", TestMode.WITHOUT_FRAMESTATES, MemoryScheduling.OPTIMAL);
+        assertEquals(4, schedule.getCFG().getBlocks().length);
+        assertReadWithinStartBlock(schedule, false);
+        assertReadWithinReturnBlock(schedule, true);
+        assertReadAndWriteInSameBlock(schedule, false);
+    }
+
+    /**
      * testing scheduling within a block.
      */
     public static int testBlockScheduleSnippet() {
@@ -498,7 +553,8 @@
             @Override
             public SchedulePhase call() throws Exception {
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(),
+                                OptimisticOptimizations.ALL);
                 new CanonicalizerPhase(true).apply(graph, context);
                 if (mode == TestMode.INLINED_WITHOUT_FRAMESTATES) {
                     new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
@@ -520,7 +576,8 @@
                 new FloatingReadPhase().apply(graph);
                 new RemoveValueProxyPhase().apply(graph);
 
-                MidTierContext midContext = new MidTierContext(runtime(), assumptions, replacements, runtime().getTarget(), OptimisticOptimizations.ALL);
+                MidTierContext midContext = new MidTierContext(getProviders(), assumptions, getCodeCache().getTarget(),
+                                OptimisticOptimizations.ALL);
                 new GuardLoweringPhase().apply(graph, midContext);
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext);
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, midContext);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MonitorGraphTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -94,7 +94,7 @@
             hints.put(invoke, 1000d);
         }
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(hints, new CanonicalizerPhase(true)).apply(graph, context);
         new CanonicalizerPhase(true).apply(graph, context);
         new DeadCodeEliminationPhase().apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PhiCreationTests.java	Fri Oct 11 17:21:14 2013 +0200
@@ -41,7 +41,7 @@
     @Test
     public void test1() {
         StructuredGraph graph = parse("test1Snippet");
-        Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
+        Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext());
     }
 
     public static int test1Snippet(int a) {
@@ -54,7 +54,7 @@
     @Test
     public void test2() {
         StructuredGraph graph = parse("test2Snippet");
-        Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
+        Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext());
     }
 
     public static int test2Snippet(int a) {
@@ -68,7 +68,7 @@
     public void test3() {
         StructuredGraph graph = parse("test3Snippet");
         Debug.dump(graph, "Graph");
-        Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
+        Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext());
     }
 
     public static int test3Snippet(int a) {
@@ -84,7 +84,7 @@
     public void test4() {
         StructuredGraph graph = parse("test4Snippet");
         Debug.dump(graph, "Graph");
-        Assert.assertFalse(graph.getNodes(PhiNode.class).iterator().hasNext());
+        Assert.assertFalse(graph.getNodes().filter(PhiNode.class).iterator().hasNext());
     }
 
     public static int test4Snippet(int a) {
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ProfilingInfoTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -145,8 +145,8 @@
     }
 
     private void testTypeProfile(String testSnippet, int bci) {
-        ResolvedJavaType stringType = runtime.lookupJavaType(String.class);
-        ResolvedJavaType stringBuilderType = runtime.lookupJavaType(StringBuilder.class);
+        ResolvedJavaType stringType = getMetaAccess().lookupJavaType(String.class);
+        ResolvedJavaType stringBuilderType = getMetaAccess().lookupJavaType(StringBuilder.class);
 
         ProfilingInfo info = profile(testSnippet, "ABC");
         JavaTypeProfile typeProfile = info.getTypeProfile(bci);
@@ -297,7 +297,7 @@
         Method method = getMethod(methodName);
         Assert.assertTrue(Modifier.isStatic(method.getModifiers()));
 
-        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
         if (resetProfile) {
             javaMethod.reprofile();
         }
@@ -314,7 +314,7 @@
     }
 
     private void resetProfile(String methodName) {
-        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(getMethod(methodName));
+        ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(getMethod(methodName));
         javaMethod.reprofile();
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -91,7 +91,7 @@
 
     private StructuredGraph compileTestSnippet(final String snippet) {
         StructuredGraph graph = parse(snippet);
-        PhaseContext context = new PhaseContext(runtime(), new Assumptions(false), replacements);
+        PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
         new LoweringPhase(canonicalizer).apply(graph, context);
         canonicalizer.apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -83,7 +83,7 @@
             // structure changes significantly
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                PhaseContext context = new PhaseContext(runtime(), new Assumptions(false), replacements);
+                PhaseContext context = new PhaseContext(getProviders(), new Assumptions(false));
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new FloatingReadPhase().apply(graph);
                 new EliminatePartiallyRedundantGuardsPhase(true, false).apply(graph);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReassociateAndCanonicalTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -245,9 +245,9 @@
     private <T extends Node & IterableNodeType> void test(String test, String ref) {
         StructuredGraph testGraph = parse(test);
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(runtime(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(testGraph, new PhaseContext(getProviders(), assumptions));
         StructuredGraph refGraph = parse(ref);
-        new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(runtime(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(refGraph, new PhaseContext(getProviders(), assumptions));
         assertEquals(testGraph, refGraph);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ScalarTypeSystemTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -167,9 +167,9 @@
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements));
-        new ConditionalEliminationPhase(runtime()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         StructuredGraph referenceGraph = parse(referenceSnippet);
         assertEquals(referenceGraph, graph);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StampCanonicalizerTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -110,7 +110,7 @@
 
     private void testZeroReturn(String methodName) {
         StructuredGraph graph = parse(methodName);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         new DeadCodeEliminationPhase().apply(graph);
         assertConstantReturn(graph, 0);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/StraighteningTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -90,7 +90,7 @@
         // No debug scope to reduce console noise for @Test(expected = ...) tests
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET);
         assertEquals(referenceGraph, graph);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/TypeSystemTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -185,13 +185,13 @@
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements));
-        new ConditionalEliminationPhase(runtime()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         // a second canonicalizer is needed to process nested MaterializeNodes
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         StructuredGraph referenceGraph = parse(referenceSnippet);
-        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(runtime(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(referenceGraph, new PhaseContext(getProviders(), assumptions));
         assertEquals(referenceGraph, graph);
     }
 
@@ -241,9 +241,9 @@
         StructuredGraph graph = parse(snippet);
         Debug.dump(graph, "Graph");
         Assumptions assumptions = new Assumptions(false);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements));
-        new ConditionalEliminationPhase(runtime()).apply(graph);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), assumptions, replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
+        new ConditionalEliminationPhase(getMetaAccess()).apply(graph);
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), assumptions));
         Debug.dump(graph, "Graph");
         Assert.assertFalse("shouldn't have nodes of type " + clazz, graph.getNodes().filter(clazz).iterator().hasNext());
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -47,7 +47,7 @@
 
     protected void test(String snippet, final int expectedRegisters, final int expectedRegRegMoves, final int expectedSpillMoves) {
         final StructuredGraph graph = parse(snippet);
-        Debug.scope("AllocatorTest", new Object[]{graph, graph.method(), runtime}, new Runnable() {
+        Debug.scope("AllocatorTest", new Object[]{graph, graph.method(), getCodeCache()}, new Runnable() {
 
             @Override
             public void run() {
@@ -119,7 +119,7 @@
 
             @Override
             public LIR call() {
-                return GraalCompiler.emitHIR(runtime, backend.target, graph, replacements, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites);
+                return GraalCompiler.emitHIR(getProviders(), backend.target, graph, assumptions, null, phasePlan, OptimisticOptimizations.NONE, new SpeculationLog(), suites);
             }
         });
 
@@ -127,7 +127,7 @@
 
             @Override
             public RegisterStats call() {
-                CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
+                CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
                 GraalCompiler.emitLIR(backend, backend.target, lir, graph, cc);
                 return new RegisterStats(lir);
             }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/CompiledMethodTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -56,19 +56,19 @@
     public void test1() {
         Method method = getMethod("testMethod");
         final StructuredGraph graph = parse(method);
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime(), new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         new DeadCodeEliminationPhase().apply(graph);
 
         for (Node node : graph.getNodes()) {
             if (node instanceof ConstantNode) {
                 ConstantNode constant = (ConstantNode) node;
                 if (constant.kind() == Kind.Object && " ".equals(constant.value.asObject())) {
-                    graph.replaceFloating(constant, ConstantNode.forObject("-", runtime, graph));
+                    graph.replaceFloating(constant, ConstantNode.forObject("-", getMetaAccess(), graph));
                 }
             }
         }
 
-        final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
         InstalledCode compiledMethod = getCode(javaMethod, graph);
         try {
             Object result = compiledMethod.execute("1", "2", "3");
@@ -82,7 +82,7 @@
     public void test3() {
         Method method = getMethod("testMethod");
         final StructuredGraph graph = parse(method);
-        final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
         InstalledCode compiledMethod = getCode(javaMethod, graph);
         try {
             Object result = compiledMethod.executeVarargs("1", "2", "3");
@@ -96,7 +96,7 @@
     public void test4() {
         Method method = getMethod("testMethodVirtual");
         final StructuredGraph graph = parse(method);
-        final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
         InstalledCode compiledMethod = getCode(javaMethod, graph);
         try {
             f1 = "0";
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -53,7 +53,7 @@
             Assert.assertEquals(testString, testMethodSynchronized(testString));
         }
         final StructuredGraph graph = parseProfiled(method);
-        final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
         InstalledCode compiledMethod = getCode(javaMethod, graph);
         try {
             Object result = compiledMethod.executeVarargs(testString);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EarlyReadEliminationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -41,7 +41,7 @@
     protected void processMethod(final String snippet) {
         graph = parse(snippet);
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new EarlyReadEliminationPhase(new CanonicalizerPhase(true)).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/EscapeAnalysisTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -224,16 +224,16 @@
     }
 
     private ReturnNode testEscapeAnalysis(String snippet, final Constant expectedConstantResult, final boolean iterativeEscapeAnalysis) {
-        ResolvedJavaMethod method = runtime.lookupJavaMethod(getMethod(snippet));
+        ResolvedJavaMethod method = getMetaAccess().lookupJavaMethod(getMethod(snippet));
         final StructuredGraph graph = new StructuredGraph(method);
 
-        return Debug.scope("GraalCompiler", new Object[]{graph, method, runtime}, new Callable<ReturnNode>() {
+        return Debug.scope("GraalCompiler", new Object[]{graph, method, getCodeCache()}, new Callable<ReturnNode>() {
 
             public ReturnNode call() {
-                new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+                new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
 
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new DeadCodeEliminationPhase().apply(graph);
                 new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/IterativeInliningTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -76,7 +76,7 @@
     @Test
     public void testSimple() {
         ValueNode result = getReturn("testSimpleSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
+        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
         assertEquals(graph.getLocal(0), result);
     }
 
@@ -88,7 +88,7 @@
 
     private void processMethod(final String snippet) {
         graph = parse(snippet);
-        HighTierContext context = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new IterativeInliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
     }
 }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PEAReadEliminationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -83,7 +83,7 @@
     @Test
     public void testSimple() {
         ValueNode result = getReturn("testSimpleSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
+        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
         assertTrue(result.isConstant());
         assertEquals(2, result.asConstant().asInt());
     }
@@ -112,7 +112,7 @@
     @Test
     public void testParam() {
         ValueNode result = getReturn("testParamSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
+        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
         assertEquals(graph.getLocal(1), result);
     }
 
@@ -126,7 +126,7 @@
     @Test
     public void testMaterialized() {
         ValueNode result = getReturn("testMaterializedSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
+        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
         assertEquals(graph.getLocal(0), result);
     }
 
@@ -142,7 +142,7 @@
     @Test
     public void testSimpleLoop() {
         ValueNode result = getReturn("testSimpleLoopSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
+        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
         assertEquals(graph.getLocal(1), result);
     }
 
@@ -160,7 +160,7 @@
     @Test
     public void testBadLoop() {
         ValueNode result = getReturn("testBadLoopSnippet").result();
-        assertEquals(0, graph.getNodes(LoadFieldNode.class).count());
+        assertEquals(0, graph.getNodes().filter(LoadFieldNode.class).count());
         assertTrue(result instanceof ProxyNode);
         assertTrue(((ProxyNode) result).value() instanceof PhiNode);
     }
@@ -178,7 +178,7 @@
     @Test
     public void testBadLoop2() {
         ValueNode result = getReturn("testBadLoop2Snippet").result();
-        assertEquals(1, graph.getNodes(LoadFieldNode.class).count());
+        assertEquals(1, graph.getNodes().filter(LoadFieldNode.class).count());
         assertTrue(result instanceof LoadFieldNode);
     }
 
@@ -195,7 +195,7 @@
     @Test
     public void testPhi() {
         ValueNode result = getReturn("testPhiSnippet").result();
-        assertTrue(graph.getNodes(LoadFieldNode.class).isEmpty());
+        assertTrue(graph.getNodes().filter(LoadFieldNode.class).isEmpty());
         assertTrue(result instanceof PhiNode);
         PhiNode phi = (PhiNode) result;
         assertTrue(phi.valueAt(0).isConstant());
@@ -243,7 +243,7 @@
     protected void processMethod(final String snippet) {
         graph = parse(snippet);
         Assumptions assumptions = new Assumptions(false);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
         new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
         new PartialEscapePhase(false, true, new CanonicalizerPhase(true)).apply(graph, context);
     }
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ea/PartialEscapeAnalysisTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -198,7 +198,7 @@
                 StructuredGraph graph = parse(snippet);
 
                 Assumptions assumptions = new Assumptions(false);
-                HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 new DeadCodeEliminationPhase().apply(graph);
                 new CanonicalizerPhase(true).apply(graph, context);
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/inlining/InliningTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -237,7 +237,7 @@
                 StructuredGraph graph = eagerInfopointMode ? parseDebug(method) : parse(method);
                 PhasePlan phasePlan = getDefaultPhasePlan(eagerInfopointMode);
                 Assumptions assumptions = new Assumptions(true);
-                HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan, OptimisticOptimizations.ALL);
                 Debug.dump(graph, "Graph");
                 new CanonicalizerPhase(true).apply(graph, context);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Fri Oct 11 17:21:14 2013 +0200
@@ -32,6 +32,7 @@
 import com.oracle.graal.alloc.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.alloc.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
@@ -50,6 +51,7 @@
 import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * Static methods for orchestrating the compilation of a {@linkplain StructuredGraph graph}.
@@ -86,7 +88,7 @@
          */
         @Option(help = "Pattern for method(s) to which intrinsification will not be applied. " +
                        "See MethodFilter class for pattern syntax.")
-        public static final OptionValue<String> IntrinsificationsDisabled = new OptionValue<>("Object.clone");
+        public static final OptionValue<String> IntrinsificationsDisabled = new OptionValue<>(null);
         // @formatter:on
 
     }
@@ -131,10 +133,10 @@
      *            argument can be null.
      * @return the result of the compilation
      */
-    public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final GraalCodeCacheProvider runtime,
-                    final Replacements replacements, final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts,
+    public static CompilationResult compileGraph(final StructuredGraph graph, final CallingConvention cc, final ResolvedJavaMethod installedCodeOwner, final Providers providers,
+                    final Backend backend, final TargetDescription target, final GraphCache cache, final PhasePlan plan, final OptimisticOptimizations optimisticOpts,
                     final SpeculationLog speculationLog, final Suites suites, final CompilationResult compilationResult) {
-        Debug.scope("GraalCompiler", new Object[]{graph, runtime}, new Runnable() {
+        Debug.scope("GraalCompiler", new Object[]{graph, providers.getCodeCache()}, new Runnable() {
 
             public void run() {
                 final Assumptions assumptions = new Assumptions(OptAssumptions.getValue());
@@ -142,7 +144,7 @@
 
                     public LIR call() {
                         try (TimerCloseable a = FrontEnd.start()) {
-                            return emitHIR(runtime, target, graph, replacements, assumptions, cache, plan, optimisticOpts, speculationLog, suites);
+                            return emitHIR(providers, target, graph, assumptions, cache, plan, optimisticOpts, speculationLog, suites);
                         }
                     }
                 });
@@ -179,13 +181,9 @@
 
     /**
      * Builds the graph, optimizes it.
-     * 
-     * @param runtime
-     * 
-     * @param target
      */
-    public static LIR emitHIR(GraalCodeCacheProvider runtime, TargetDescription target, final StructuredGraph graph, Replacements replacements, Assumptions assumptions, GraphCache cache,
-                    PhasePlan plan, OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites) {
+    public static LIR emitHIR(Providers providers, TargetDescription target, final StructuredGraph graph, Assumptions assumptions, GraphCache cache, PhasePlan plan,
+                    OptimisticOptimizations optimisticOpts, final SpeculationLog speculationLog, final Suites suites) {
 
         if (speculationLog != null) {
             speculationLog.snapshot();
@@ -198,13 +196,13 @@
             Debug.dump(graph, "initial state");
         }
 
-        HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements, cache, plan, optimisticOpts);
+        HighTierContext highTierContext = new HighTierContext(providers, assumptions, cache, plan, optimisticOpts);
         suites.getHighTier().apply(graph, highTierContext);
 
-        MidTierContext midTierContext = new MidTierContext(runtime, assumptions, replacements, target, optimisticOpts);
+        MidTierContext midTierContext = new MidTierContext(providers, assumptions, target, optimisticOpts);
         suites.getMidTier().apply(graph, midTierContext);
 
-        LowTierContext lowTierContext = new LowTierContext(runtime, assumptions, replacements, target);
+        LowTierContext lowTierContext = new LowTierContext(providers, assumptions, target);
         suites.getLowTier().apply(graph, lowTierContext);
 
         // we do not want to store statistics about OSR compilations because it may prevent inlining
@@ -229,7 +227,7 @@
                 List<Block> codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock, nodeProbabilities);
                 List<Block> linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock, nodeProbabilities);
 
-                LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder, speculationLog);
+                LIR lir = new LIR(schedule.getCFG(), schedule.getBlockToNodesMap(), linearScanOrder, codeEmittingOrder);
                 Debug.dump(lir, "After linear scan order");
                 return lir;
 
@@ -288,4 +286,16 @@
 
         Debug.dump(result, "After code generation");
     }
+
+    /**
+     * Creates a set of providers via {@link Graal#getRequiredCapability(Class)}.
+     */
+    public static Providers getGraalProviders() {
+        MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
+        CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
+        ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class);
+        LoweringProvider lowerer = Graal.getRequiredCapability(LoweringProvider.class);
+        Replacements replacements = Graal.getRequiredCapability(Replacements.class);
+        return new Providers(metaAccess, codeCache, constantReflection, lowerer, replacements);
+    }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Fri Oct 11 17:21:14 2013 +0200
@@ -48,7 +48,7 @@
     protected HashMap<VirtualObjectNode, VirtualObject> virtualObjects = new HashMap<>();
     protected IdentityHashMap<VirtualObjectNode, EscapeObjectState> objectStates = new IdentityHashMap<>();
 
-    public LIRFrameState build(FrameState topState, short reason, LabelRef exceptionEdge) {
+    public LIRFrameState build(FrameState topState, LabelRef exceptionEdge) {
         assert virtualObjects.size() == 0;
         assert objectStates.size() == 0;
 
@@ -101,11 +101,11 @@
         }
         objectStates.clear();
 
-        return newLIRFrameState(reason, exceptionEdge, frame, virtualObjectsArray);
+        return newLIRFrameState(exceptionEdge, frame, virtualObjectsArray);
     }
 
-    protected LIRFrameState newLIRFrameState(short reason, LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) {
-        return new LIRFrameState(frame, virtualObjectsArray, exceptionEdge, reason);
+    protected LIRFrameState newLIRFrameState(LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) {
+        return new LIRFrameState(frame, virtualObjectsArray, exceptionEdge);
     }
 
     protected BytecodeFrame computeFrameForState(FrameState state) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -60,7 +60,8 @@
     public final LIR lir;
 
     protected final StructuredGraph graph;
-    protected final CodeCacheProvider runtime;
+    protected final MetaAccessProvider metaAccess;
+    protected final CodeCacheProvider codeCache;
     protected final TargetDescription target;
     protected final CallingConvention cc;
 
@@ -85,16 +86,17 @@
      */
     public abstract boolean canStoreConstant(Constant c);
 
-    public LIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
+    public LIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
         this.graph = graph;
-        this.runtime = runtime;
+        this.metaAccess = metaAccess;
+        this.codeCache = codeCache;
         this.target = target;
         this.frameMap = frameMap;
         if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) {
             this.cc = cc;
         } else {
-            JavaType[] parameterTypes = new JavaType[]{runtime.lookupJavaType(long.class)};
-            CallingConvention tmp = frameMap.registerConfig.getCallingConvention(JavaCallee, runtime.lookupJavaType(void.class), parameterTypes, target, false);
+            JavaType[] parameterTypes = new JavaType[]{metaAccess.lookupJavaType(long.class)};
+            CallingConvention tmp = frameMap.registerConfig.getCallingConvention(JavaCallee, metaAccess.lookupJavaType(void.class), parameterTypes, target, false);
             this.cc = new CallingConvention(cc.getStackSize(), cc.getReturn(), tmp.getArgument(0));
         }
         this.nodeOperands = graph.createNodeMap();
@@ -113,8 +115,13 @@
     }
 
     @Override
-    public CodeCacheProvider getRuntime() {
-        return runtime;
+    public MetaAccessProvider getMetaAccess() {
+        return metaAccess;
+    }
+
+    @Override
+    public CodeCacheProvider getCodeCache() {
+        return codeCache;
     }
 
     public StructuredGraph getGraph() {
@@ -228,26 +235,26 @@
         if (!deopt.canDeoptimize()) {
             return null;
         }
-        return stateFor(deopt.getDeoptimizationState(), deopt.getDeoptimizationReason());
+        return stateFor(deopt.getDeoptimizationState());
     }
 
     public LIRFrameState stateWithExceptionEdge(DeoptimizingNode deopt, LabelRef exceptionEdge) {
         if (!deopt.canDeoptimize()) {
             return null;
         }
-        return stateForWithExceptionEdge(deopt.getDeoptimizationState(), deopt.getDeoptimizationReason(), exceptionEdge);
+        return stateForWithExceptionEdge(deopt.getDeoptimizationState(), exceptionEdge);
     }
 
-    public LIRFrameState stateFor(FrameState state, DeoptimizationReason reason) {
-        return stateForWithExceptionEdge(state, reason, null);
+    public LIRFrameState stateFor(FrameState state) {
+        return stateForWithExceptionEdge(state, null);
     }
 
-    public LIRFrameState stateForWithExceptionEdge(FrameState state, DeoptimizationReason reason, LabelRef exceptionEdge) {
+    public LIRFrameState stateForWithExceptionEdge(FrameState state, LabelRef exceptionEdge) {
         if (needOnlyOopMaps()) {
-            return new LIRFrameState(null, null, null, (short) -1);
+            return new LIRFrameState(null, null, null);
         }
         assert state != null;
-        return debugInfoBuilder.build(state, lir.getDeoptimizationReasons().addSpeculation(reason), exceptionEdge);
+        return debugInfoBuilder.build(state, exceptionEdge);
     }
 
     /**
@@ -288,7 +295,7 @@
         assert lir.lir(block) == null : "LIR list already computed for this block";
         lir.setLir(block, new ArrayList<LIRInstruction>());
 
-        append(new LabelOp(new Label(), block.isAligned()));
+        append(new LabelOp(new Label(block.getId()), block.isAligned()));
 
         if (TraceLIRGeneratorLevel.getValue() >= 1) {
             TTY.println("BEGIN Generating LIR for block B" + block.getId());
@@ -551,7 +558,7 @@
     @Override
     public void emitInvoke(Invoke x) {
         LoweredCallTargetNode callTarget = (LoweredCallTargetNode) x.callTarget();
-        CallingConvention invokeCc = frameMap.registerConfig.getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(runtime), callTarget.signature(), target(), false);
+        CallingConvention invokeCc = frameMap.registerConfig.getCallingConvention(callTarget.callType(), x.asNode().stamp().javaType(metaAccess), callTarget.signature(), target(), false);
         frameMap.callsMethod(invokeCc);
 
         Value[] parameters = visitInvokeArguments(invokeCc, callTarget.arguments());
@@ -619,10 +626,10 @@
         LIRFrameState state = null;
         if (linkage.canDeoptimize()) {
             if (info != null) {
-                state = stateFor(info.getDeoptimizationState(), info.getDeoptimizationReason());
+                state = stateFor(info.getDeoptimizationState());
             } else {
                 assert needOnlyOopMaps();
-                state = new LIRFrameState(null, null, null, (short) -1);
+                state = new LIRFrameState(null, null, null);
             }
         }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/Backend.java	Fri Oct 11 17:21:14 2013 +0200
@@ -35,16 +35,22 @@
  */
 public abstract class Backend {
 
-    private final CodeCacheProvider runtime;
+    private final MetaAccessProvider metaAccess;
+    private final CodeCacheProvider codeCache;
     public final TargetDescription target;
 
-    protected Backend(CodeCacheProvider runtime, TargetDescription target) {
-        this.runtime = runtime;
+    protected Backend(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target) {
+        this.metaAccess = metaAccess;
+        this.codeCache = codeCache;
         this.target = target;
     }
 
-    public CodeCacheProvider runtime() {
-        return runtime;
+    public MetaAccessProvider getMetaAccess() {
+        return metaAccess;
+    }
+
+    public CodeCacheProvider getCodeCache() {
+        return codeCache;
     }
 
     public abstract FrameMap newFrameMap();
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Fri Oct 11 17:21:14 2013 +0200
@@ -31,6 +31,7 @@
 import com.oracle.graal.graph.NodeClass.NodeClassIterator;
 import com.oracle.graal.graph.NodeClass.Position;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.graph.spi.*;
 
 /**
  * This class is the base class for all nodes, it represent a node which can be inserted in a
@@ -594,12 +595,32 @@
         return newNode;
     }
 
-    static int count = 0;
-
     public final Node clone(Graph into) {
         return clone(into, true);
     }
 
+    /**
+     * Must be overridden by subclasses that implement {@link Canonicalizable}. The implementation
+     * in {@link Node} exists to obviate the need to cast a node before invoking
+     * {@link Canonicalizable#canonical(CanonicalizerTool)}.
+     * 
+     * @param tool
+     */
+    public Node canonical(CanonicalizerTool tool) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Must be overridden by subclasses that implement {@link Simplifiable}. The implementation in
+     * {@link Node} exists to obviate the need to cast a node before invoking
+     * {@link Simplifiable#simplify(SimplifierTool)}.
+     * 
+     * @param tool
+     */
+    public void simplify(SimplifierTool tool) {
+        throw new UnsupportedOperationException();
+    }
+
     final Node clone(Graph into, boolean clearInputsAndSuccessors) {
         NodeClass nodeClass = getNodeClass();
         if (nodeClass.valueNumberable() && nodeClass.isLeafNode()) {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Fri Oct 11 17:21:14 2013 +0200
@@ -33,6 +33,7 @@
 import com.oracle.graal.graph.Node.Input;
 import com.oracle.graal.graph.Node.Successor;
 import com.oracle.graal.graph.Node.Verbosity;
+import com.oracle.graal.graph.spi.*;
 
 /**
  * Lazily associated metadata for every {@link Node} type. The metadata includes:
@@ -148,9 +149,21 @@
     private static final DebugMetric ITERABLE_NODE_TYPES = Debug.metric("IterableNodeTypes");
     private final DebugMetric nodeIterableCount;
 
+    /**
+     * Determines if this node type implements {@link Canonicalizable}.
+     */
+    private final boolean isCanonicalizable;
+
+    /**
+     * Determines if this node type implements {@link Simplifiable}.
+     */
+    private final boolean isSimplifiable;
+
     private NodeClass(Class<?> clazz) {
         super(clazz);
         assert NODE_CLASS.isAssignableFrom(clazz);
+        this.isCanonicalizable = Canonicalizable.class.isAssignableFrom(clazz);
+        this.isSimplifiable = Simplifiable.class.isAssignableFrom(clazz);
 
         FieldScanner scanner = new FieldScanner(new DefaultCalcOffset());
         scanner.scan(clazz);
@@ -259,6 +272,20 @@
         return isLeafNode;
     }
 
+    /**
+     * Determines if this node type implements {@link Canonicalizable}.
+     */
+    public boolean isCanonicalizable() {
+        return isCanonicalizable;
+    }
+
+    /**
+     * Determines if this node type implements {@link Simplifiable}.
+     */
+    public boolean isSimplifiable() {
+        return isSimplifiable;
+    }
+
     public static int cacheSize() {
         return nextIterableId;
     }
@@ -418,22 +445,19 @@
     }
 
     /**
-     * An iterator that will iterate over the fields given in {@link #offsets}. The first
-     * {@link #directCount} offsets are treated as fields of type {@link Node}, while the rest of
-     * the fields are treated as {@link NodeList}s. All elements of these NodeLists will be visited
-     * by the iterator as well. This iterator can be used to iterate over the inputs or successors
-     * of a node.
+     * An iterator that will iterate over the fields given in {@link #getOffsets()}. The first
+     * {@link #getDirectCount()} offsets are treated as fields of type {@link Node}, while the rest
+     * of the fields are treated as {@link NodeList}s. All elements of these NodeLists will be
+     * visited by the iterator as well. This iterator can be used to iterate over the inputs or
+     * successors of a node.
      * 
      * An iterator of this type will not return null values, unless the field values are modified
      * concurrently. Concurrent modifications are detected by an assertion on a best-effort basis.
      */
-    public static final class NodeClassIterator implements Iterator<Node> {
+    public abstract static class NodeClassIterator implements Iterator<Node> {
 
         private final NodeClass nodeClass;
-        private final Node node;
-        private final int modCount;
-        private final int directCount;
-        private final long[] offsets;
+        protected final Node node;
         private int index;
         private int subIndex;
 
@@ -441,26 +465,19 @@
          * Creates an iterator that will iterate over fields in the given node.
          * 
          * @param node the node which contains the fields.
-         * @param offsets the offsets of the fields.
-         * @param directCount the number of fields that should be treated as fields of type
-         *            {@link Node}, the rest are treated as {@link NodeList}s.
          */
-        private NodeClassIterator(Node node, long[] offsets, int directCount) {
+        NodeClassIterator(Node node) {
             this.node = node;
             this.nodeClass = node.getNodeClass();
-            this.modCount = MODIFICATION_COUNTS_ENABLED ? node.modCount() : 0;
-            this.offsets = offsets;
-            this.directCount = directCount;
             index = NOT_ITERABLE;
             subIndex = 0;
-            forward();
         }
 
-        private void forward() {
-            if (index < directCount) {
+        void forward() {
+            if (index < getDirectCount()) {
                 index++;
-                while (index < directCount) {
-                    Node element = getNode(node, offsets[index]);
+                while (index < getDirectCount()) {
+                    Node element = getNode(node, getOffsets()[index]);
                     if (element != null) {
                         return;
                     }
@@ -469,8 +486,8 @@
             } else {
                 subIndex++;
             }
-            while (index < offsets.length) {
-                NodeList<Node> list = getNodeList(node, offsets[index]);
+            while (index < getOffsets().length) {
+                NodeList<Node> list = getNodeList(node, getOffsets()[index]);
                 while (subIndex < list.size()) {
                     if (list.get(subIndex) != null) {
                         return;
@@ -483,10 +500,10 @@
         }
 
         private Node nextElement() {
-            if (index < directCount) {
-                return getNode(node, offsets[index]);
-            } else if (index < offsets.length) {
-                NodeList<Node> list = getNodeList(node, offsets[index]);
+            if (index < getDirectCount()) {
+                return getNode(node, getOffsets()[index]);
+            } else if (index < getOffsets().length) {
+                NodeList<Node> list = getNodeList(node, getOffsets()[index]);
                 return list.get(subIndex);
             }
             throw new NoSuchElementException();
@@ -494,8 +511,77 @@
 
         @Override
         public boolean hasNext() {
+            return index < getOffsets().length;
+        }
+
+        @Override
+        public Node next() {
             try {
-                return index < offsets.length;
+                return nextElement();
+            } finally {
+                forward();
+            }
+        }
+
+        public Position nextPosition() {
+            try {
+                if (index < getDirectCount()) {
+                    return new Position(getOffsets() == nodeClass.inputOffsets, index, NOT_ITERABLE);
+                } else {
+                    return new Position(getOffsets() == nodeClass.inputOffsets, index, subIndex);
+                }
+            } finally {
+                forward();
+            }
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        protected abstract int getDirectCount();
+
+        protected abstract long[] getOffsets();
+    }
+
+    private class NodeClassInputsIterator extends NodeClassIterator {
+        NodeClassInputsIterator(Node node) {
+            this(node, true);
+        }
+
+        NodeClassInputsIterator(Node node, boolean forward) {
+            super(node);
+            if (forward) {
+                forward();
+            }
+        }
+
+        @Override
+        protected int getDirectCount() {
+            return directInputCount;
+        }
+
+        @Override
+        protected long[] getOffsets() {
+            return inputOffsets;
+        }
+    }
+
+    private final class NodeClassInputsWithModCountIterator extends NodeClassInputsIterator {
+        private final int modCount;
+
+        private NodeClassInputsWithModCountIterator(Node node) {
+            super(node, false);
+            assert MODIFICATION_COUNTS_ENABLED;
+            this.modCount = node.modCount();
+            forward();
+        }
+
+        @Override
+        public boolean hasNext() {
+            try {
+                return super.hasNext();
             } finally {
                 assert modCount == node.modCount() : "must not be modified";
             }
@@ -504,29 +590,80 @@
         @Override
         public Node next() {
             try {
-                return nextElement();
+                return super.next();
             } finally {
-                forward();
-                assert modCount == node.modCount();
+                assert modCount == node.modCount() : "must not be modified";
             }
         }
 
+        @Override
         public Position nextPosition() {
             try {
-                if (index < directCount) {
-                    return new Position(offsets == nodeClass.inputOffsets, index, NOT_ITERABLE);
-                } else {
-                    return new Position(offsets == nodeClass.inputOffsets, index, subIndex);
-                }
+                return super.nextPosition();
             } finally {
+                assert modCount == node.modCount();
+            }
+        }
+    }
+
+    private class NodeClassSuccessorsIterator extends NodeClassIterator {
+        NodeClassSuccessorsIterator(Node node) {
+            this(node, true);
+        }
+
+        NodeClassSuccessorsIterator(Node node, boolean forward) {
+            super(node);
+            if (forward) {
                 forward();
-                assert modCount == node.modCount();
             }
         }
 
         @Override
-        public void remove() {
-            throw new UnsupportedOperationException();
+        protected int getDirectCount() {
+            return directSuccessorCount;
+        }
+
+        @Override
+        protected long[] getOffsets() {
+            return successorOffsets;
+        }
+    }
+
+    private final class NodeClassSuccessorsWithModCountIterator extends NodeClassSuccessorsIterator {
+        private final int modCount;
+
+        private NodeClassSuccessorsWithModCountIterator(Node node) {
+            super(node, false);
+            assert MODIFICATION_COUNTS_ENABLED;
+            this.modCount = node.modCount();
+            forward();
+        }
+
+        @Override
+        public boolean hasNext() {
+            try {
+                return super.hasNext();
+            } finally {
+                assert modCount == node.modCount() : "must not be modified";
+            }
+        }
+
+        @Override
+        public Node next() {
+            try {
+                return super.next();
+            } finally {
+                assert modCount == node.modCount() : "must not be modified";
+            }
+        }
+
+        @Override
+        public Position nextPosition() {
+            try {
+                return super.nextPosition();
+            } finally {
+                assert modCount == node.modCount();
+            }
         }
     }
 
@@ -781,7 +918,11 @@
 
             @Override
             public NodeClassIterator iterator() {
-                return new NodeClassIterator(node, inputOffsets, directInputCount);
+                if (MODIFICATION_COUNTS_ENABLED) {
+                    return new NodeClassInputsWithModCountIterator(node);
+                } else {
+                    return new NodeClassInputsIterator(node);
+                }
             }
 
             @Override
@@ -797,7 +938,11 @@
 
             @Override
             public NodeClassIterator iterator() {
-                return new NodeClassIterator(node, successorOffsets, directSuccessorCount);
+                if (MODIFICATION_COUNTS_ENABLED) {
+                    return new NodeClassSuccessorsWithModCountIterator(node);
+                } else {
+                    return new NodeClassSuccessorsIterator(node);
+                }
             }
 
             @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Canonicalizable.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graph.spi;
+
+import com.oracle.graal.graph.*;
+
+public interface Canonicalizable {
+
+    Node canonical(CanonicalizerTool tool);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/CanonicalizerTool.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graph.spi;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+
+public interface CanonicalizerTool {
+
+    Assumptions assumptions();
+
+    MetaAccessProvider getMetaAccess();
+
+    ConstantReflectionProvider getConstantReflection();
+
+    boolean canonicalizeReads();
+
+    void removeIfUnused(Node node);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/Simplifiable.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * 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.graph.spi;
+
+/**
+ * This interface allows nodes to perform more complicated simplifications, in contrast to
+ * {@link Canonicalizable}, which supports only replacing the current node.
+ * 
+ * Implementors of this interface need to be aware that they need to call
+ * {@link SimplifierTool#addToWorkList(com.oracle.graal.graph.Node)} for each node that might be
+ * influenced (in terms of simplification and canonicalization) by the actions performed in
+ * simplify.
+ */
+public interface Simplifiable {
+
+    void simplify(SimplifierTool tool);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/spi/SimplifierTool.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * 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.graph.spi;
+
+import com.oracle.graal.graph.*;
+
+/**
+ * @see Simplifiable
+ */
+public interface SimplifierTool extends CanonicalizerTool {
+
+    void deleteBranch(Node branch);
+
+    /**
+     * Adds a node to the worklist independent of whether it has already been on the worklist.
+     */
+    void addToWorkList(Node node);
+}
--- a/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/AMD64HotSpotFrameOmissionTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -31,7 +31,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.compiler.test.*;
 
@@ -98,12 +97,11 @@
 
     private void testHelper(String name, CodeGenerator gen) {
         Method method = getMethod(name);
-        ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method);
         InstalledCode installedCode = getCode(javaMethod, parse(method));
 
-        CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
-        TargetDescription target = codeCache.getTarget();
-        RegisterConfig registerConfig = codeCache.lookupRegisterConfig();
+        TargetDescription target = getCodeCache().getTarget();
+        RegisterConfig registerConfig = getCodeCache().getRegisterConfig();
         AMD64Assembler asm = new AMD64Assembler(target, registerConfig);
 
         gen.generateCode(asm);
@@ -117,7 +115,7 @@
     }
 
     private Register getArgumentRegister(int index, Kind kind) {
-        Register[] regs = runtime.lookupRegisterConfig().getCallingConventionRegisters(CallingConvention.Type.JavaCall, kind);
+        Register[] regs = getCodeCache().getRegisterConfig().getCallingConventionRegisters(CallingConvention.Type.JavaCall, kind);
         return regs[index];
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64DeoptimizeOp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,12 +23,8 @@
 package com.oracle.graal.hotspot.amd64;
 
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
@@ -36,21 +32,14 @@
 @Opcode("DEOPT")
 final class AMD64DeoptimizeOp extends AMD64LIRInstruction {
 
-    private DeoptimizationAction action;
-    private DeoptimizationReason reason;
     @State private LIRFrameState info;
 
-    AMD64DeoptimizeOp(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) {
-        this.action = action;
-        this.reason = reason;
+    AMD64DeoptimizeOp(LIRFrameState info) {
         this.info = info;
     }
 
     @Override
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-        HotSpotGraalRuntime runtime = graalRuntime();
-        Register thread = runtime.getRuntime().threadRegister();
-        masm.movl(new AMD64Address(thread, runtime.getConfig().pendingDeoptimizationOffset), tasm.runtime.encodeDeoptActionAndReason(action, reason));
-        AMD64Call.directCall(tasm, masm, tasm.runtime.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
+        AMD64Call.directCall(tasm, masm, tasm.codeCache.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Fri Oct 11 17:21:14 2013 +0200
@@ -69,12 +69,12 @@
 
     @Override
     public FrameMap newFrameMap() {
-        return new AMD64FrameMap(runtime(), target, runtime().lookupRegisterConfig());
+        return new AMD64FrameMap(getCodeCache(), target, getCodeCache().getRegisterConfig());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new AMD64HotSpotLIRGenerator(graph, runtime(), target, frameMap, cc, lir);
+        return new AMD64HotSpotLIRGenerator(graph, getMetaAccess(), getCodeCache(), target, frameMap, cc, lir);
     }
 
     /**
@@ -174,7 +174,7 @@
         Stub stub = gen.getStub();
         AbstractAssembler masm = createAssembler(frameMap);
         HotSpotFrameContext frameContext = omitFrame ? null : new HotSpotFrameContext(stub != null);
-        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, getCodeCache(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(frameMap.frameSize());
         StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot;
         if (deoptimizationRescueSlot != null && stub == null) {
@@ -235,21 +235,20 @@
         AMD64MacroAssembler asm = (AMD64MacroAssembler) tasm.asm;
         FrameMap frameMap = tasm.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
-        HotSpotVMConfig config = runtime().config;
-        Label unverifiedStub = installedCodeOwner == null || isStatic(installedCodeOwner.getModifiers()) ? null : new Label();
+        HotSpotVMConfig config = getRuntime().config;
+        Label verifiedStub = new Label();
 
         // Emit the prefix
-
-        if (unverifiedStub != null) {
+        if (installedCodeOwner != null && !isStatic(installedCodeOwner.getModifiers())) {
             tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
-            CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{runtime().lookupJavaType(Object.class)}, target, false);
+            CallingConvention cc = regConfig.getCallingConvention(JavaCallee, null, new JavaType[]{getRuntime().lookupJavaType(Object.class)}, target, false);
             Register inlineCacheKlass = rax; // see definition of IC_Klass in
                                              // c1_LIRAssembler_x86.cpp
             Register receiver = asRegister(cc.getArgument(0));
             AMD64Address src = new AMD64Address(receiver, config.hubOffset);
 
             AMD64HotSpotLIRGenerator gen = (AMD64HotSpotLIRGenerator) lirGen;
-            AMD64HotSpotRuntime hr = ((AMD64HotSpotRuntime) gen.getRuntime());
+            AMD64HotSpotRuntime hr = ((AMD64HotSpotRuntime) gen.getCodeCache());
             if (hr.useCompressedKlassPointers()) {
                 Register register = r10;
                 AMD64HotSpotMove.decodeKlassPointer(asm, register, hr.heapBaseRegister(), src, config.narrowKlassBase, config.narrowKlassShift, config.logKlassAlignment);
@@ -257,11 +256,12 @@
             } else {
                 asm.cmpq(inlineCacheKlass, src);
             }
-            asm.jcc(ConditionFlag.NotEqual, unverifiedStub);
+            AMD64Call.directConditionalJmp(tasm, asm, getCodeCache().lookupForeignCall(IC_MISS_HANDLER), ConditionFlag.NotEqual);
         }
 
         asm.align(config.codeEntryAlignment);
         tasm.recordMark(Marks.MARK_OSR_ENTRY);
+        asm.bind(verifiedStub);
         tasm.recordMark(Marks.MARK_VERIFIED_ENTRY);
 
         // Emit code for the LIR
@@ -270,18 +270,13 @@
         HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext;
         if (frameContext != null && !frameContext.isStub) {
             tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
-            AMD64Call.directCall(tasm, asm, runtime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
+            AMD64Call.directCall(tasm, asm, getRuntime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
             tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
-            AMD64Call.directCall(tasm, asm, runtime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
+            AMD64Call.directCall(tasm, asm, getRuntime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
             assert !frameMap.accessesCallerFrame() : lirGen.getGraph();
         }
-
-        if (unverifiedStub != null) {
-            asm.bind(unverifiedStub);
-            AMD64Call.directJmp(tasm, asm, runtime().lookupForeignCall(IC_MISS_HANDLER));
-        }
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotDeoptimizeCallerOp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,12 +23,8 @@
 package com.oracle.graal.hotspot.amd64;
 
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
@@ -39,21 +35,9 @@
 @Opcode("DEOPT_CALLER")
 final class AMD64HotSpotDeoptimizeCallerOp extends AMD64HotSpotEpilogueOp {
 
-    private final DeoptimizationAction action;
-    private final DeoptimizationReason reason;
-
-    AMD64HotSpotDeoptimizeCallerOp(DeoptimizationAction action, DeoptimizationReason reason) {
-        this.action = action;
-        this.reason = reason;
-    }
-
     @Override
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
         leaveFrameAndRestoreRbp(tasm, masm);
-
-        HotSpotGraalRuntime runtime = graalRuntime();
-        Register thread = runtime.getRuntime().threadRegister();
-        masm.movl(new AMD64Address(thread, runtime.getConfig().pendingDeoptimizationOffset), tasm.runtime.encodeDeoptActionAndReason(action, reason));
-        AMD64Call.directJmp(tasm, masm, tasm.runtime.lookupForeignCall(UNCOMMON_TRAP));
+        AMD64Call.directJmp(tasm, masm, tasm.codeCache.lookupForeignCall(UNCOMMON_TRAP));
     }
 }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime.java	Fri Oct 11 17:21:14 2013 +0200
@@ -82,7 +82,7 @@
     @Override
     protected Value[] getNativeABICallerSaveRegisters() {
         if (nativeABICallerSaveRegisters == null) {
-            List<Register> callerSave = new ArrayList<>(Arrays.asList(getRuntime().lookupRegisterConfig().getAllocatableRegisters()));
+            List<Register> callerSave = new ArrayList<>(Arrays.asList(getRuntime().getRegisterConfig().getAllocatableRegisters()));
             if (getConfig().windowsOs) {
                 // http://msdn.microsoft.com/en-us/library/9z1stfyw.aspx
                 callerSave.remove(AMD64.rdi);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,6 +25,7 @@
 import static com.oracle.graal.amd64.AMD64.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -66,11 +67,11 @@
 public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSpotLIRGenerator {
 
     private HotSpotRuntime runtime() {
-        return (HotSpotRuntime) runtime;
+        return (HotSpotRuntime) codeCache;
     }
 
-    protected AMD64HotSpotLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, runtime, target, frameMap, cc, lir);
+    protected AMD64HotSpotLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, metaAccess, codeCache, target, frameMap, cc, lir);
     }
 
     /**
@@ -304,7 +305,7 @@
         AMD64AddressValue address;
         Value index = operand(x.offset());
         if (ValueUtil.isConstant(index) && NumUtil.isInt(ValueUtil.asConstant(index).asLong() + disp)) {
-            assert !runtime.needsDataPatch(asConstant(index));
+            assert !codeCache.needsDataPatch(asConstant(index));
             disp += (int) ValueUtil.asConstant(index).asLong();
             address = new AMD64AddressValue(kind, load(operand(x.object())), disp);
         } else {
@@ -354,7 +355,7 @@
 
     @Override
     public void emitUnwind(Value exception) {
-        ForeignCallLinkage linkage = getRuntime().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER);
+        ForeignCallLinkage linkage = getCodeCache().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER);
         CallingConvention outgoingCc = linkage.getOutgoingCallingConvention();
         assert outgoingCc.getArgumentCount() == 2;
         RegisterValue exceptionParameter = (RegisterValue) outgoingCc.getArgument(0);
@@ -362,14 +363,29 @@
         append(new AMD64HotSpotUnwindOp(exceptionParameter));
     }
 
+    private void moveDeoptimizationActionAndReasonToThread(Value actionAndReason) {
+        int pendingDeoptimizationOffset = graalRuntime().getConfig().pendingDeoptimizationOffset;
+        RegisterValue thread = runtime().threadRegister().asValue(HotSpotGraalRuntime.wordKind());
+        AMD64AddressValue pendingDeoptAddress = new AMD64AddressValue(actionAndReason.getKind(), thread, pendingDeoptimizationOffset);
+        if (actionAndReason instanceof Constant && !codeCache.needsDataPatch((Constant) actionAndReason)) {
+            Constant constantActionAndReason = (Constant) actionAndReason;
+            assert !codeCache.needsDataPatch(constantActionAndReason);
+            append(new StoreConstantOp(constantActionAndReason.getKind(), pendingDeoptAddress, constantActionAndReason, null));
+        } else {
+            append(new StoreOp(actionAndReason.getKind(), pendingDeoptAddress, load(actionAndReason), null));
+        }
+    }
+
     @Override
-    public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) {
-        append(new AMD64DeoptimizeOp(action, deopting.getDeoptimizationReason(), state(deopting)));
+    public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) {
+        moveDeoptimizationActionAndReasonToThread(actionAndReason);
+        append(new AMD64DeoptimizeOp(state(deopting)));
     }
 
     @Override
     public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) {
-        append(new AMD64HotSpotDeoptimizeCallerOp(action, reason));
+        moveDeoptimizationActionAndReasonToThread(metaAccess.encodeDeoptActionAndReason(action, reason));
+        append(new AMD64HotSpotDeoptimizeCallerOp());
     }
 
     @Override
@@ -380,7 +396,7 @@
     @Override
     public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) {
         Variable handler = load(operand(handlerInCallerPc));
-        ForeignCallLinkage linkage = getRuntime().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER);
+        ForeignCallLinkage linkage = getCodeCache().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER);
         CallingConvention outgoingCc = linkage.getOutgoingCallingConvention();
         assert outgoingCc.getArgumentCount() == 2;
         RegisterValue exceptionFixed = (RegisterValue) outgoingCc.getArgument(0);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Fri Oct 11 17:21:14 2013 +0200
@@ -120,7 +120,7 @@
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
-            Register heapBase = ((HotSpotRuntime) tasm.runtime).heapBaseRegister();
+            Register heapBase = ((HotSpotRuntime) tasm.codeCache).heapBaseRegister();
             masm.movq(asRegister(scratch), asRegister(input));
             if (kind == Kind.Object) {
                 encodePointer(masm, asRegister(scratch), heapBase, base, shift, alignment);
@@ -172,7 +172,7 @@
         final Register scratchRegister = asRegister(scratch);
         final Register cmpRegister = asRegister(cmpValue);
         final Register newRegister = asRegister(newValue);
-        Register heapBase = ((HotSpotRuntime) tasm.runtime).heapBaseRegister();
+        Register heapBase = ((HotSpotRuntime) tasm.codeCache).heapBaseRegister();
         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	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotReturnOp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -50,7 +50,7 @@
     }
 
     private static Register findPollOnReturnScratchRegister() {
-        RegisterConfig config = HotSpotGraalRuntime.graalRuntime().getRuntime().lookupRegisterConfig();
+        RegisterConfig config = HotSpotGraalRuntime.graalRuntime().getRuntime().getRegisterConfig();
         for (Register r : config.getAllocatableRegisters(Kind.Long)) {
             if (r != config.getReturnRegister(Kind.Long) && r != AMD64.rbp) {
                 return r;
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRuntime.java	Fri Oct 11 17:21:14 2013 +0200
@@ -41,6 +41,7 @@
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.amd64.*;
 
 public class AMD64HotSpotRuntime extends HotSpotRuntime {
@@ -72,7 +73,8 @@
         registerForeignCall(DECRYPT, config.cipherBlockChainingDecryptAESCryptStub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
         registerForeignCall(UPDATE_BYTES_CRC32, config.updateBytesCRC32Stub, NativeCall, PRESERVES_REGISTERS, LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
 
-        convertSnippets = new AMD64ConvertSnippets.Templates(this, replacements, graalRuntime.getTarget());
+        Providers providers = new Providers(this, this, this, this, replacements);
+        convertSnippets = new AMD64ConvertSnippets.Templates(providers, graalRuntime.getTarget());
         super.registerReplacements(replacements);
     }
 
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotUnwindOp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -50,7 +50,7 @@
     public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) {
         leaveFrameAndRestoreRbp(tasm, masm);
 
-        ForeignCallLinkage linkage = tasm.runtime.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
+        ForeignCallLinkage linkage = tasm.codeCache.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
         CallingConvention cc = linkage.getOutgoingCallingConvention();
         assert cc.getArgumentCount() == 2;
         assert exception.equals(cc.getArgument(0));
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java	Fri Oct 11 17:21:14 2013 +0200
@@ -104,7 +104,14 @@
         int currentStackOffset = 0;
 
         Kind returnKind = returnType == null ? Kind.Void : returnType.getKind();
-        AllocatableValue returnLocation = returnKind == Kind.Void ? Value.ILLEGAL : new Variable(returnKind, currentGeneral++);
+
+        AllocatableValue returnLocation;
+        if (returnKind == Kind.Void) {
+            returnLocation = Value.ILLEGAL;
+        } else {
+            returnLocation = new Variable(returnKind, currentGeneral++);
+        }
+
         AllocatableValue[] locations = new AllocatableValue[parameterTypes.length];
 
         for (int i = 0; i < parameterTypes.length; i++) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCDeoptimizeOp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,39 +22,24 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
-import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static com.oracle.graal.sparc.SPARC.*;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.asm.*;
 
 @Opcode("DEOPT")
 final class SPARCDeoptimizeOp extends SPARCLIRInstruction {
 
-    private DeoptimizationAction action;
-    private DeoptimizationReason reason;
     @State private LIRFrameState info;
 
-    SPARCDeoptimizeOp(DeoptimizationAction action, DeoptimizationReason reason, LIRFrameState info) {
-        this.action = action;
-        this.reason = reason;
+    SPARCDeoptimizeOp(LIRFrameState info) {
         this.info = info;
     }
 
     @Override
     public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
-        HotSpotGraalRuntime runtime = graalRuntime();
-        Register thread = runtime.getRuntime().threadRegister();
-        Register scratch = g3;
-        new Mov(tasm.runtime.encodeDeoptActionAndReason(action, reason), scratch).emit(masm);
-        new Stw(scratch, new SPARCAddress(thread, runtime.getConfig().pendingDeoptimizationOffset)).emit(masm);
         // TODO the patched call address looks odd (and is invalid) compared to other runtime calls:
 // 0xffffffff749bb5fc: call 0xffffffff415a720c ; {runtime_call}
 // [Exception Handler]
@@ -63,6 +48,6 @@
 // [Deopt Handler Code]
 // 0xffffffff749bb60c: call 0xffffffff748da540 ; {runtime_call}
 // 0xffffffff749bb610: nop
-        SPARCCall.directCall(tasm, masm, tasm.runtime.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
+        SPARCCall.directCall(tasm, masm, tasm.codeCache.lookupForeignCall(UNCOMMON_TRAP), null, false, info);
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java	Fri Oct 11 17:21:14 2013 +0200
@@ -66,12 +66,12 @@
 
     @Override
     public FrameMap newFrameMap() {
-        return new SPARCFrameMap(runtime(), target, runtime().lookupRegisterConfig());
+        return new SPARCFrameMap(getRuntime(), target, getRuntime().getRegisterConfig());
     }
 
     @Override
     public LIRGenerator newLIRGenerator(StructuredGraph graph, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        return new SPARCHotSpotLIRGenerator(graph, runtime(), target, frameMap, cc, lir);
+        return new SPARCHotSpotLIRGenerator(graph, getRuntime(), getRuntime(), target, frameMap, cc, lir);
     }
 
     /**
@@ -155,7 +155,7 @@
         AbstractAssembler masm = createAssembler(frameMap);
         // On SPARC we always use stack frames.
         HotSpotFrameContext frameContext = new HotSpotFrameContext(stub != null);
-        TargetMethodAssembler tasm = new TargetMethodAssembler(target, runtime(), frameMap, masm, frameContext, compilationResult);
+        TargetMethodAssembler tasm = new TargetMethodAssembler(target, getRuntime(), frameMap, masm, frameContext, compilationResult);
         tasm.setFrameSize(frameMap.frameSize());
         StackSlot deoptimizationRescueSlot = gen.deoptimizationRescueSlot;
         if (deoptimizationRescueSlot != null && stub == null) {
@@ -176,7 +176,7 @@
         SPARCMacroAssembler masm = (SPARCMacroAssembler) tasm.asm;
         FrameMap frameMap = tasm.frameMap;
         RegisterConfig regConfig = frameMap.registerConfig;
-        HotSpotVMConfig config = runtime().config;
+        HotSpotVMConfig config = getRuntime().config;
         Label unverifiedStub = installedCodeOwner == null || isStatic(installedCodeOwner.getModifiers()) ? null : new Label();
 
         // Emit the prefix
@@ -184,7 +184,7 @@
         if (unverifiedStub != null) {
             tasm.recordMark(Marks.MARK_UNVERIFIED_ENTRY);
             // We need to use JavaCall here because we haven't entered the frame yet.
-            CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{runtime().lookupJavaType(Object.class)}, target, false);
+            CallingConvention cc = regConfig.getCallingConvention(JavaCall, null, new JavaType[]{getRuntime().lookupJavaType(Object.class)}, target, false);
             Register inlineCacheKlass = g5; // see MacroAssembler::ic_call
             Register scratch = g3;
             Register receiver = asRegister(cc.getArgument(0));
@@ -206,9 +206,9 @@
         HotSpotFrameContext frameContext = (HotSpotFrameContext) tasm.frameContext;
         if (frameContext != null && !frameContext.isStub) {
             tasm.recordMark(Marks.MARK_EXCEPTION_HANDLER_ENTRY);
-            SPARCCall.directCall(tasm, masm, runtime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
+            SPARCCall.directCall(tasm, masm, getRuntime().lookupForeignCall(EXCEPTION_HANDLER), null, false, null);
             tasm.recordMark(Marks.MARK_DEOPT_HANDLER_ENTRY);
-            SPARCCall.directCall(tasm, masm, runtime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
+            SPARCCall.directCall(tasm, masm, getRuntime().lookupForeignCall(DEOPT_HANDLER), null, false, null);
         } else {
             // No need to emit the stubs for entries back into the method since
             // it has no calls that can cause such "return" entries
@@ -218,7 +218,7 @@
         if (unverifiedStub != null) {
             masm.bind(unverifiedStub);
             Register scratch = g3;
-            SPARCCall.indirectJmp(tasm, masm, scratch, runtime().lookupForeignCall(IC_MISS_HANDLER));
+            SPARCCall.indirectJmp(tasm, masm, scratch, getRuntime().lookupForeignCall(IC_MISS_HANDLER));
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotDeoptimizeCallerOp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,18 +22,14 @@
  */
 package com.oracle.graal.hotspot.sparc;
 
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
-import static com.oracle.graal.hotspot.HotSpotBackend.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.lir.sparc.*;
-import com.oracle.graal.lir.asm.*;
 
 /**
  * Removes the current frame and tail calls the uncommon trap routine.
@@ -41,14 +37,6 @@
 @Opcode("DEOPT_CALLER")
 final class SPARCHotSpotDeoptimizeCallerOp extends SPARCHotSpotEpilogueOp {
 
-    private final DeoptimizationAction action;
-    private final DeoptimizationReason reason;
-
-    SPARCHotSpotDeoptimizeCallerOp(DeoptimizationAction action, DeoptimizationReason reason) {
-        this.action = action;
-        this.reason = reason;
-    }
-
     @Override
     public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
         leaveFrame(tasm);
@@ -58,15 +46,8 @@
 // final boolean isStub = true;
 // HotSpotFrameContext frameContext = backend.new HotSpotFrameContext(isStub);
 // frameContext.enter(tasm);
-
-        HotSpotGraalRuntime runtime = graalRuntime();
-        Register thread = runtime.getRuntime().threadRegister();
-
-        Register scratch = g5;
-        new Mov(tasm.runtime.encodeDeoptActionAndReason(action, reason), scratch).emit(masm);
-        new Stw(scratch, new SPARCAddress(thread, runtime.getConfig().pendingDeoptimizationOffset)).emit(masm);
-
-        SPARCCall.indirectJmp(tasm, masm, scratch, tasm.runtime.lookupForeignCall(UNCOMMON_TRAP));
+        Register scratch = g3;
+        SPARCCall.indirectJmp(tasm, masm, scratch, tasm.codeCache.lookupForeignCall(UNCOMMON_TRAP));
 
 // frameContext.leave(tasm);
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.hotspot.HotSpotBackend.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.sparc.SPARC.*;
 
 import java.lang.reflect.*;
@@ -49,11 +50,11 @@
 public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator {
 
     private HotSpotRuntime runtime() {
-        return (HotSpotRuntime) runtime;
+        return (HotSpotRuntime) codeCache;
     }
 
-    public SPARCHotSpotLIRGenerator(StructuredGraph graph, CodeCacheProvider runtime, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
-        super(graph, runtime, target, frameMap, cc, lir);
+    public SPARCHotSpotLIRGenerator(StructuredGraph graph, MetaAccessProvider metaAccess, CodeCacheProvider codeCache, TargetDescription target, FrameMap frameMap, CallingConvention cc, LIR lir) {
+        super(graph, metaAccess, codeCache, target, frameMap, cc, lir);
     }
 
     /**
@@ -127,7 +128,7 @@
         Variable newValue = load(operand(x.newValue()));
 
         if (ValueUtil.isConstant(offset)) {
-            assert !runtime.needsDataPatch(asConstant(offset));
+            assert !codeCache.needsDataPatch(asConstant(offset));
             Variable longAddress = newVariable(Kind.Long);
             emitMove(longAddress, address);
             address = emitAdd(longAddress, asConstant(offset));
@@ -175,7 +176,7 @@
 
     @Override
     public void emitUnwind(Value exception) {
-        ForeignCallLinkage linkage = getRuntime().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER);
+        ForeignCallLinkage linkage = getCodeCache().lookupForeignCall(HotSpotBackend.UNWIND_EXCEPTION_TO_CALLER);
         CallingConvention linkageCc = linkage.getOutgoingCallingConvention();
         assert linkageCc.getArgumentCount() == 2;
         RegisterValue exceptionParameter = (RegisterValue) linkageCc.getArgument(0);
@@ -183,14 +184,23 @@
         append(new SPARCHotSpotUnwindOp(exceptionParameter));
     }
 
+    private void moveDeoptimizationActionAndReasonToThread(Value actionAndReason) {
+        int pendingDeoptimizationOffset = graalRuntime().getConfig().pendingDeoptimizationOffset;
+        RegisterValue thread = runtime().threadRegister().asValue(HotSpotGraalRuntime.wordKind());
+        SPARCAddressValue pendingDeoptAddress = new SPARCAddressValue(actionAndReason.getKind(), thread, pendingDeoptimizationOffset);
+        append(new StoreOp(actionAndReason.getKind(), pendingDeoptAddress, emitMove(actionAndReason), null));
+    }
+
     @Override
-    public void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting) {
-        append(new SPARCDeoptimizeOp(action, deopting.getDeoptimizationReason(), state(deopting)));
+    public void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting) {
+        moveDeoptimizationActionAndReasonToThread(actionAndReason);
+        append(new SPARCDeoptimizeOp(state(deopting)));
     }
 
     @Override
     public void emitDeoptimizeCaller(DeoptimizationAction action, DeoptimizationReason reason) {
-        append(new SPARCHotSpotDeoptimizeCallerOp(action, reason));
+        moveDeoptimizationActionAndReasonToThread(metaAccess.encodeDeoptActionAndReason(action, reason));
+        append(new SPARCHotSpotDeoptimizeCallerOp());
     }
 
     @Override
@@ -201,7 +211,7 @@
     @Override
     public void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc) {
         Variable handler = load(operand(handlerInCallerPc));
-        ForeignCallLinkage linkage = getRuntime().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER);
+        ForeignCallLinkage linkage = getCodeCache().lookupForeignCall(EXCEPTION_HANDLER_IN_CALLER);
         CallingConvention linkageCc = linkage.getOutgoingCallingConvention();
         assert linkageCc.getArgumentCount() == 2;
         RegisterValue exceptionFixed = (RegisterValue) linkageCc.getArgument(0);
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotUnwindOp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -51,7 +51,7 @@
     public void emitCode(TargetMethodAssembler tasm, SPARCMacroAssembler masm) {
         leaveFrame(tasm);
 
-        ForeignCallLinkage linkage = tasm.runtime.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
+        ForeignCallLinkage linkage = tasm.codeCache.lookupForeignCall(UNWIND_EXCEPTION_TO_CALLER);
         CallingConvention cc = linkage.getOutgoingCallingConvention();
         assert cc.getArgumentCount() == 2;
         assert exception.equals(cc.getArgument(0));
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -64,7 +64,7 @@
     public void testStaticFinalObjectAOT() {
         StructuredGraph result = compile("getStaticFinalObject", true);
         assertEquals(1, result.getNodes().filter(ConstantNode.class).count());
-        assertEquals(runtime.getTarget().wordKind, result.getNodes().filter(ConstantNode.class).first().kind());
+        assertEquals(getCodeCache().getTarget().wordKind, result.getNodes().filter(ConstantNode.class).first().kind());
         assertEquals(2, result.getNodes(FloatingReadNode.class).count());
         assertEquals(0, result.getNodes().filter(ReadNode.class).count());
     }
@@ -88,7 +88,7 @@
 
         NodeIterable<ConstantNode> filter = result.getNodes().filter(ConstantNode.class);
         assertEquals(1, filter.count());
-        HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) runtime.lookupJavaType(AheadOfTimeCompilationTest.class);
+        HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(AheadOfTimeCompilationTest.class);
         assertEquals(type.klass(), filter.first().asConstant());
 
         assertEquals(1, result.getNodes(FloatingReadNode.class).count());
@@ -118,7 +118,7 @@
         StructuredGraph result = compile("getPrimitiveClassObject", true);
         NodeIterable<ConstantNode> filter = result.getNodes().filter(ConstantNode.class);
         assertEquals(1, filter.count());
-        assertEquals(runtime.getTarget().wordKind, filter.first().kind());
+        assertEquals(getCodeCache().getTarget().wordKind, filter.first().kind());
 
         assertEquals(2, result.getNodes(FloatingReadNode.class).count());
         assertEquals(0, result.getNodes().filter(ReadNode.class).count());
@@ -179,7 +179,7 @@
         assertEquals(1, result.getNodes().filter(ConstantNode.class).count());
         ConstantNode constant = result.getNodes().filter(ConstantNode.class).first();
         assertEquals(Kind.Long, constant.kind());
-        assertEquals(((HotSpotResolvedObjectType) runtime.lookupJavaType(Boolean.class)).klass(), constant.asConstant());
+        assertEquals(((HotSpotResolvedObjectType) getMetaAccess().lookupJavaType(Boolean.class)).klass(), constant.asConstant());
     }
 
     @Test
@@ -200,12 +200,12 @@
         boolean originalSetting = AOTCompilation.getValue();
         AOTCompilation.setValue(compileAOT);
         PhasePlan phasePlan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-        CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
+        CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graph.method(), false);
         // create suites everytime, as we modify options for the compiler
         final Suites suitesLocal = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
-        final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
+        final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, method, getProviders(), backend, getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL,
                         new SpeculationLog(), suitesLocal, new CompilationResult());
         addMethod(method, compResult);
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ArrayCopyIntrinsificationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ArrayCopyIntrinsificationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -54,8 +54,8 @@
                         LoweredCallTargetNode directCall = (LoweredCallTargetNode) invoke.callTarget();
                         JavaMethod callee = directCall.target();
                         Assert.assertTrue(callee.getName().equals("<init>"));
-                        Assert.assertTrue(runtime.lookupJavaType(ArrayIndexOutOfBoundsException.class).equals(callee.getDeclaringClass()) ||
-                                        runtime.lookupJavaType(NullPointerException.class).equals(callee.getDeclaringClass()));
+                        Assert.assertTrue(getMetaAccess().lookupJavaType(ArrayIndexOutOfBoundsException.class).equals(callee.getDeclaringClass()) ||
+                                        getMetaAccess().lookupJavaType(NullPointerException.class).equals(callee.getDeclaringClass()));
                     }
                 }
             } else {
@@ -65,7 +65,7 @@
                         Invoke invoke = (Invoke) node;
                         LoweredCallTargetNode directCall = (LoweredCallTargetNode) invoke.callTarget();
                         JavaMethod callee = directCall.target();
-                        if (callee.getDeclaringClass().equals(runtime.lookupJavaType(System.class)) && callee.getName().equals("arraycopy")) {
+                        if (callee.getDeclaringClass().equals(getMetaAccess().lookupJavaType(System.class)) && callee.getName().equals("arraycopy")) {
                             found = true;
                         } else {
                             fail("found invoke to some method other than arraycopy: " + callee);
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompressedOopTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -40,15 +40,15 @@
  */
 public class CompressedOopTest extends GraalCompilerTest {
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
 
     public CompressedOopTest() {
-        this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
+        this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
     }
 
     private HotSpotInstalledCode getInstalledCode(String name) throws Exception {
         final Method method = CompressedOopTest.class.getMethod(name, Object.class, Object.class, Object.class);
-        final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(method);
+        final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method);
         final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(javaMethod, parse(method));
         return installedBenchmarkCode;
     }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -48,42 +48,54 @@
     @Override
     protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
         HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true, null);
+        HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, true);
         HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(hsMethod, StructuredGraph.INVOCATION_ENTRY_BCI, compResult);
         CodeInstallResult result = graalRuntime().getCompilerToVM().installCode(compiledNmethod, installedCode, null);
         Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK);
 
-        // HotSpotRuntime hsRuntime = (HotSpotRuntime) runtime;
+        // HotSpotRuntime hsRuntime = (HotSpotRuntime) getCodeCache();
         // TTY.println(hsMethod.toString());
         // TTY.println(hsRuntime.disassemble(installedCode));
         return installedCode;
     }
 
     @Test
-    public void testAESEncryptSubstitution() throws Exception {
+    public void testEncryptSubstitution() throws Exception {
         byte[] seed = {0x4, 0x7, 0x1, 0x1};
         SecureRandom random = new SecureRandom(seed);
         KeyGenerator aesKeyGen = KeyGenerator.getInstance("AES");
+        KeyGenerator desKeyGen = KeyGenerator.getInstance("DESede");
         aesKeyGen.init(128, random);
+        desKeyGen.init(168, random);
         SecretKey aesKey = aesKeyGen.generateKey();
+        SecretKey desKey = desKeyGen.generateKey();
         byte[] input = readClassfile16(getClass());
 
-        ByteArrayOutputStream expected = new ByteArrayOutputStream();
-        expected.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input));
-        expected.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input));
+        ByteArrayOutputStream aesExpected = new ByteArrayOutputStream();
+        aesExpected.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input));
+        aesExpected.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input));
 
         if (compiledAndInstall("com.sun.crypto.provider.AESCrypt", "encryptBlock", "decryptBlock")) {
             ByteArrayOutputStream actual = new ByteArrayOutputStream();
             actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input));
             actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input));
-            Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
+            Assert.assertArrayEquals(aesExpected.toByteArray(), actual.toByteArray());
         }
 
+        ByteArrayOutputStream desExpected = new ByteArrayOutputStream();
+        desExpected.write(runEncryptDecrypt(desKey, "DESede/CBC/NoPadding", input));
+        desExpected.write(runEncryptDecrypt(desKey, "DESede/CBC/PKCS5Padding", input));
+
         if (compiledAndInstall("com.sun.crypto.provider.CipherBlockChaining", "encrypt", "decrypt")) {
             ByteArrayOutputStream actual = new ByteArrayOutputStream();
             actual.write(runEncryptDecrypt(aesKey, "AES/CBC/NoPadding", input));
             actual.write(runEncryptDecrypt(aesKey, "AES/CBC/PKCS5Padding", input));
-            Assert.assertArrayEquals(expected.toByteArray(), actual.toByteArray());
+            Assert.assertArrayEquals(aesExpected.toByteArray(), actual.toByteArray());
+
+            actual.reset();
+            actual.write(runEncryptDecrypt(desKey, "DESede/CBC/NoPadding", input));
+            actual.write(runEncryptDecrypt(desKey, "DESede/CBC/PKCS5Padding", input));
+            Assert.assertArrayEquals(desExpected.toByteArray(), actual.toByteArray());
         }
     }
 
@@ -100,8 +112,8 @@
         for (String methodName : methodNames) {
             Method method = lookup(className, methodName);
             if (method != null) {
-                ResolvedJavaMethod installedCodeOwner = runtime.lookupJavaMethod(method);
-                StructuredGraph graph = replacements.getMethodSubstitution(installedCodeOwner);
+                ResolvedJavaMethod installedCodeOwner = getMetaAccess().lookupJavaMethod(method);
+                StructuredGraph graph = getReplacements().getMethodSubstitution(installedCodeOwner);
                 if (graph != null) {
                     Assert.assertNotNull(getCode(installedCodeOwner, graph, true));
                     atLeastOneCompiled = true;
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNmethodTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotNmethodTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -36,7 +36,7 @@
 
     @Test
     public void testInstallCodeInvalidation() {
-        final ResolvedJavaMethod testJavaMethod = runtime.lookupJavaMethod(getMethod("foo"));
+        final ResolvedJavaMethod testJavaMethod = getMetaAccess().lookupJavaMethod(getMethod("foo"));
         final StructuredGraph graph = parse("otherFoo");
         final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, graph);
         Assert.assertTrue(nmethod.isValid());
@@ -60,7 +60,7 @@
 
     @Test
     public void testInstallCodeInvalidationWhileRunning() {
-        final ResolvedJavaMethod testJavaMethod = runtime.lookupJavaMethod(getMethod("foo"));
+        final ResolvedJavaMethod testJavaMethod = getMetaAccess().lookupJavaMethod(getMethod("foo"));
         final StructuredGraph graph = parse("otherFoo");
         final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, graph);
         Object result;
@@ -75,7 +75,7 @@
 
     @Test
     public void testInstalledCodeCalledFromCompiledCode() {
-        final ResolvedJavaMethod testJavaMethod = runtime.lookupJavaMethod(getMethod("foo"));
+        final ResolvedJavaMethod testJavaMethod = getMetaAccess().lookupJavaMethod(getMethod("foo"));
         final StructuredGraph graph = parse("otherFoo");
         final HotSpotNmethod nmethod = (HotSpotNmethod) getCode(testJavaMethod, graph);
         Assert.assertTrue(nmethod.isValid());
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/InstalledCodeExecuteHelperTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -39,23 +39,23 @@
 public class InstalledCodeExecuteHelperTest extends GraalCompilerTest {
 
     private static final int ITERATIONS = 100000;
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
     Object[] argsToBind;
 
     public InstalledCodeExecuteHelperTest() {
-        this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
+        this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
     }
 
     @Test
     public void test1() throws NoSuchMethodException, SecurityException, InvalidInstalledCodeException {
         final Method fooMethod = InstalledCodeExecuteHelperTest.class.getMethod("foo", Object.class, Object.class, Object.class);
-        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(fooMethod);
+        final HotSpotResolvedJavaMethod fooJavaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(fooMethod);
         final HotSpotInstalledCode fooCode = (HotSpotInstalledCode) getCode(fooJavaMethod, parse(fooMethod));
 
         argsToBind = new Object[]{fooCode};
 
         final Method benchmarkMethod = InstalledCodeExecuteHelperTest.class.getMethod("benchmark", HotSpotInstalledCode.class);
-        final ResolvedJavaMethod benchmarkJavaMethod = metaAccessProvider.lookupJavaMethod(benchmarkMethod);
+        final ResolvedJavaMethod benchmarkJavaMethod = metaAccess.lookupJavaMethod(benchmarkMethod);
         final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(benchmarkJavaMethod, parse(benchmarkMethod));
 
         Assert.assertEquals(Integer.valueOf(42), benchmark(fooCode));
@@ -84,12 +84,12 @@
         if (argsToBind != null) {
             Object receiver = isStatic(m.getModifiers()) ? null : this;
             Object[] args = argsWithReceiver(receiver, argsToBind);
-            JavaType[] parameterTypes = signatureToTypes(runtime.lookupJavaMethod(m));
+            JavaType[] parameterTypes = signatureToTypes(getMetaAccess().lookupJavaMethod(m));
             assert parameterTypes.length == args.length;
             for (int i = 0; i < argsToBind.length; i++) {
                 LocalNode local = graph.getLocal(i);
                 Constant c = Constant.forBoxed(parameterTypes[i].getKind(), argsToBind[i]);
-                ConstantNode replacement = ConstantNode.forConstant(c, runtime, graph);
+                ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
                 local.replaceAtUsages(replacement);
             }
         }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -53,13 +53,12 @@
  * offsets) passed as input parameters can be checked against printed output from the G1 write
  * barrier snippets. The runtime checks have been validated offline.
  */
-
 public class WriteBarrierAdditionTest extends GraalCompilerTest {
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
 
     public WriteBarrierAdditionTest() {
-        this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
+        this.metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
     }
 
     public static class Container {
@@ -175,7 +174,7 @@
     }
 
     public static Object test5Snippet() throws Exception {
-        return UnsafeLoadNode.load(wr, 0, useCompressedOops() ? 12 : 16, Kind.Object);
+        return UnsafeLoadNode.load(wr, useCompressedOops() ? 12 : 16, Kind.Object);
     }
 
     /**
@@ -250,12 +249,12 @@
     public static Object testUnsafeLoad(Object a, Object b, Object c) throws Exception {
         final int offset = (c == null ? 0 : ((Integer) c).intValue());
         final long displacement = (b == null ? 0 : ((Long) b).longValue());
-        return UnsafeLoadNode.load(a, offset, displacement, Kind.Object);
+        return UnsafeLoadNode.load(a, offset + displacement, Kind.Object);
     }
 
     private HotSpotInstalledCode getInstalledCode(String name) throws Exception {
         final Method method = WriteBarrierAdditionTest.class.getMethod(name, Object.class, Object.class, Object.class);
-        final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccessProvider.lookupJavaMethod(method);
+        final HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method);
         final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(javaMethod, parse(method));
         return installedBenchmarkCode;
     }
@@ -265,8 +264,8 @@
 
             public void run() {
                 StructuredGraph graph = parse(snippet);
-                HighTierContext highContext = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
-                MidTierContext midContext = new MidTierContext(runtime(), new Assumptions(false), replacements, runtime().getTarget(), OptimisticOptimizations.ALL);
+                HighTierContext highContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                MidTierContext midContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
                 new InliningPhase(new InliningPhase.InlineEverythingPolicy(), new CanonicalizerPhase(true)).apply(graph, highContext);
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highContext);
                 new GuardLoweringPhase().apply(graph, midContext);
@@ -276,9 +275,10 @@
 
                 int barriers = 0;
                 if (useG1GC()) {
-                    barriers = graph.getNodes(G1ReferentFieldReadBarrier.class).count() + graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count();
+                    barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() +
+                                    graph.getNodes().filter(G1PostWriteBarrier.class).count();
                 } else {
-                    barriers = graph.getNodes(SerialWriteBarrier.class).count();
+                    barriers = graph.getNodes().filter(SerialWriteBarrier.class).count();
                 }
                 Assert.assertEquals(expectedBarriers, barriers);
                 for (WriteNode write : graph.getNodes().filter(WriteNode.class)) {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -615,10 +615,10 @@
 
             public AssertionError call() {
                 final StructuredGraph graph = parse(snippet);
-                HighTierContext highTierContext = new HighTierContext(runtime(), new Assumptions(false), replacements, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
+                HighTierContext highTierContext = new HighTierContext(getProviders(), new Assumptions(false), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL);
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
 
-                MidTierContext midTierContext = new MidTierContext(runtime(), new Assumptions(false), replacements, runtime().getTarget(), OptimisticOptimizations.ALL);
+                MidTierContext midTierContext = new MidTierContext(getProviders(), new Assumptions(false), getCodeCache().getTarget(), OptimisticOptimizations.ALL);
 
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(graph, highTierContext);
                 new GuardLoweringPhase().apply(graph, midTierContext);
@@ -629,12 +629,12 @@
 
                 int barriers = 0;
                 // First, the total number of expected barriers is checked.
-                if (((HotSpotRuntime) runtime()).config.useG1GC) {
-                    barriers = graph.getNodes(G1PreWriteBarrier.class).count() + graph.getNodes(G1PostWriteBarrier.class).count() + graph.getNodes(G1ArrayRangePreWriteBarrier.class).count() +
-                                    graph.getNodes(G1ArrayRangePostWriteBarrier.class).count();
+                if (((HotSpotRuntime) getMetaAccess()).config.useG1GC) {
+                    barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() +
+                                    graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count();
                     Assert.assertTrue(expectedBarriers * 2 == barriers);
                 } else {
-                    barriers = graph.getNodes(SerialWriteBarrier.class).count() + graph.getNodes(SerialArrayRangeWriteBarrier.class).count();
+                    barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count();
                     Assert.assertTrue(expectedBarriers == barriers);
                 }
                 // Iterate over all write nodes and remove barriers according to input indices.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Fri Oct 11 17:21:14 2013 +0200
@@ -42,6 +42,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 public final class CompilationTask implements Runnable {
 
@@ -128,8 +129,7 @@
             CompilationStatistics stats = CompilationStatistics.create(method, entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI);
             final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed();
             if (printCompilation) {
-                TTY.println(String.format("%-6d Graal %-70s %-45s %-50s %s...", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature(),
-                                entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") "));
+                TTY.println(getMethodDescription() + "...");
             }
             if (HotSpotPrintCompilation.getValue()) {
                 printCompilation();
@@ -155,13 +155,17 @@
                         InliningUtil.InlinedBytecodes.add(method.getCodeSize());
                         HotSpotRuntime runtime = graalRuntime.getRuntime();
                         CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
-                        return GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, graalRuntime.getBackend(), graalRuntime.getTarget(), graalRuntime.getCache(), plan, optimisticOpts,
+                        Providers providers = new Providers(runtime, runtime, runtime, runtime, replacements);
+                        return GraalCompiler.compileGraph(graph, cc, method, providers, graalRuntime.getBackend(), graalRuntime.getTarget(), graalRuntime.getCache(), plan, optimisticOpts,
                                         method.getSpeculationLog(), suitesProvider.getDefaultSuites(), new CompilationResult());
                     }
                 });
             } finally {
                 filter.remove();
-                if (printCompilation) {
+                final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed();
+                if (printAfterCompilation) {
+                    TTY.println(getMethodDescription() + String.format(" | %4dms %5dB", System.currentTimeMillis() - start, (result != null ? result.getTargetCodeSize() : -1)));
+                } else if (printCompilation) {
                     TTY.println(String.format("%-6d Graal %-70s %-45s %-50s | %4dms %5dB", id, "", "", "", System.currentTimeMillis() - start, (result != null ? result.getTargetCodeSize() : -1)));
                 }
             }
@@ -193,6 +197,11 @@
         }
     }
 
+    private String getMethodDescription() {
+        return String.format("%-6d Graal %-70s %-45s %-50s %s", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature().getMethodDescriptor(),
+                        entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") ");
+    }
+
     /**
      * Print a HotSpot-style compilation message to the console.
      */
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Fri Oct 11 17:21:14 2013 +0200
@@ -69,11 +69,10 @@
     public static final ForeignCallDescriptor EXCEPTION_HANDLER_IN_CALLER = new ForeignCallDescriptor("exceptionHandlerInCaller", void.class, Object.class, Word.class);
 
     public HotSpotBackend(HotSpotRuntime runtime, TargetDescription target) {
-        super(runtime, target);
+        super(runtime, runtime, target);
     }
 
-    @Override
-    public HotSpotRuntime runtime() {
-        return (HotSpotRuntime) super.runtime();
+    public HotSpotRuntime getRuntime() {
+        return (HotSpotRuntime) getCodeCache();
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugInfoBuilder.java	Fri Oct 11 17:21:14 2013 +0200
@@ -61,7 +61,7 @@
     }
 
     @Override
-    protected LIRFrameState newLIRFrameState(short reason, LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) {
-        return new HotSpotLIRFrameState(frame, virtualObjectsArray, exceptionEdge, reason);
+    protected LIRFrameState newLIRFrameState(LabelRef exceptionEdge, BytecodeFrame frame, VirtualObject[] virtualObjectsArray) {
+        return new HotSpotLIRFrameState(frame, virtualObjectsArray, exceptionEdge);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotForeignCallLinkage.java	Fri Oct 11 17:21:14 2013 +0200
@@ -144,7 +144,7 @@
         }
         TargetDescription target = graalRuntime().getTarget();
         JavaType returnType = asJavaType(descriptor.getResultType(), runtime);
-        return runtime.lookupRegisterConfig().getCallingConvention(ccType, returnType, parameterTypes, target, false);
+        return runtime.getRegisterConfig().getCallingConvention(ccType, returnType, parameterTypes, target, false);
     }
 
     private static JavaType asJavaType(Class type, HotSpotRuntime runtime) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Fri Oct 11 17:21:14 2013 +0200
@@ -349,7 +349,7 @@
     @SuppressWarnings("unchecked")
     @Override
     public <T> T getCapability(Class<T> clazz) {
-        if (clazz == GraalCodeCacheProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class) {
+        if (clazz == LoweringProvider.class || clazz == CodeCacheProvider.class || clazz == MetaAccessProvider.class || clazz == ConstantReflectionProvider.class) {
             return (T) getRuntime();
         }
         if (clazz == DisassemblerProvider.class || clazz == BytecodeDisassemblerProvider.class || clazz == SuitesProvider.class) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -34,8 +34,8 @@
  */
 class HotSpotLIRFrameState extends LIRFrameState {
 
-    public HotSpotLIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge, short deoptimizationReason) {
-        super(topFrame, virtualObjects, exceptionEdge, deoptimizationReason);
+    public HotSpotLIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge) {
+        super(topFrame, virtualObjects, exceptionEdge);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -131,6 +131,14 @@
         OptionDescriptor desc = options.get(optionName);
         if (desc == null) {
             Logger.info("Could not find option " + optionName + " (use -G:+PrintFlags to see Graal options)");
+            List<OptionDescriptor> matches = fuzzyMatch(optionName);
+            if (!matches.isEmpty()) {
+                Logger.info("Did you mean one of the following?");
+                for (OptionDescriptor match : matches) {
+                    boolean isBoolean = match.getType() == boolean.class;
+                    Logger.info(String.format("    %s%s%s", isBoolean ? "(+/-)" : "", match.getName(), isBoolean ? "" : "=<value>"));
+                }
+            }
             return false;
         }
 
@@ -210,7 +218,7 @@
                 if (line.length() != 0) {
                     line.append(' ');
                 }
-                String[] embeddedLines = chunk.split("%n");
+                String[] embeddedLines = chunk.split("%n", -2);
                 if (embeddedLines.length == 1) {
                     line.append(chunk);
                 } else {
@@ -246,4 +254,38 @@
 
         System.exit(0);
     }
+
+    /**
+     * Compute string similarity based on Dice's coefficient.
+     * 
+     * Ported from str_similar() in globals.cpp.
+     */
+    static float stringSimiliarity(String str1, String str2) {
+        int hit = 0;
+        for (int i = 0; i < str1.length() - 1; ++i) {
+            for (int j = 0; j < str2.length() - 1; ++j) {
+                if ((str1.charAt(i) == str2.charAt(j)) && (str1.charAt(i + 1) == str2.charAt(j + 1))) {
+                    ++hit;
+                    break;
+                }
+            }
+        }
+        return 2.0f * hit / (str1.length() + str2.length());
+    }
+
+    private static final float FUZZY_MATCH_THRESHOLD = 0.7F;
+
+    /**
+     * Returns the set of options that fuzzy match a given option name.
+     */
+    private static List<OptionDescriptor> fuzzyMatch(String optionName) {
+        List<OptionDescriptor> matches = new ArrayList<>();
+        for (Map.Entry<String, OptionDescriptor> e : options.entrySet()) {
+            float score = stringSimiliarity(e.getKey(), optionName);
+            if (score >= FUZZY_MATCH_THRESHOLD) {
+                matches.add(e.getValue());
+            }
+        }
+        return matches;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Fri Oct 11 17:21:14 2013 +0200
@@ -40,7 +40,7 @@
     private final HotSpotVMConfig config;
 
     public HotSpotReplacementsImpl(HotSpotRuntime runtime, Assumptions assumptions, TargetDescription target) {
-        super(runtime, assumptions, target);
+        super(runtime, runtime, runtime, runtime, assumptions, target);
         this.config = runtime.config;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Fri Oct 11 17:21:14 2013 +0200
@@ -247,6 +247,16 @@
     public final int osThreadOffset = getUninitializedInt();
 
     /**
+     * The value of JavaThread::graal_counters_offset().
+     */
+    public final int graalCountersThreadOffset = getUninitializedInt();
+
+    /**
+     * The length of the JavaThread::_graal_counters array.
+     */
+    public final int graalCountersSize = getUninitializedInt();
+
+    /**
      * The value of OSThread::interrupted_offset().
      */
     public final int osThreadInterruptedOffset = getUninitializedInt();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPU.java	Fri Oct 11 17:21:14 2013 +0200
@@ -45,6 +45,8 @@
      */
     boolean deviceDetach();
 
+    int availableProcessors();
+
     /**
      * Attempts to generate and return a bound function to the
      * loaded method kernel on the GPU.
@@ -55,4 +57,8 @@
     long generateKernel(byte[] code, String name) throws InvalidInstalledCodeException;
 
     Object executeExternalMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
+
+
+    Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ,
+                                        Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToGPUImpl.java	Fri Oct 11 17:21:14 2013 +0200
@@ -38,5 +38,12 @@
 
     public native boolean deviceDetach();
 
-    public native Object executeExternalMethodVarargs(Object[] args, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
+    public native int availableProcessors();
+
+    public native Object executeExternalMethodVarargs(Object[] args,
+                                                      HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
+
+    public native Object executeParallelMethodVarargs(int dimX, int dimY, int dimZ,
+                                                      Object[] args,
+                                                      HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Fri Oct 11 17:21:14 2013 +0200
@@ -228,4 +228,9 @@
     void invalidateInstalledCode(HotSpotInstalledCode hotspotInstalledCode);
 
     boolean isTypeLinked(HotSpotResolvedObjectType hotSpotResolvedObjectType);
+
+    /**
+     * Collects the current values of all Graal benchmark counters, summed up over all threads.
+     */
+    long[] collectCounters();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Fri Oct 11 17:21:14 2013 +0200
@@ -190,4 +190,6 @@
      * verified entry point of the given native method.
      */
     public static native Object executeCompiledMethodIntrinsic(Object arg1, Object arg2, Object arg3, HotSpotInstalledCode hotspotInstalledCode) throws InvalidInstalledCodeException;
+
+    public native long[] collectCounters();
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java	Fri Oct 11 17:21:14 2013 +0200
@@ -47,7 +47,6 @@
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.debug.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
@@ -79,11 +78,6 @@
         }
     };
 
-    @Option(help = "")
-    private static final OptionValue<Boolean> GenericDynamicCounters = new OptionValue<>(false);
-
-    @Option(help = "")
-    private static final OptionValue<String> BenchmarkDynamicCounters = new OptionValue<>(null);
     //@formatter:on
 
     private final HotSpotGraalRuntime graalRuntime;
@@ -185,10 +179,10 @@
             }
         }
 
-        assert VerifyHotSpotOptionsPhase.checkOptions();
+        final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class);
+        assert VerifyOptionsPhase.checkOptions(runtime);
 
         // Install intrinsics.
-        final HotSpotRuntime runtime = graalRuntime.getCapability(HotSpotRuntime.class);
         final Replacements replacements = graalRuntime.getCapability(Replacements.class);
         if (Intrinsify.getValue()) {
             Debug.scope("RegisterReplacements", new Object[]{new DebugDumpScope("RegisterReplacements")}, new Runnable() {
@@ -234,28 +228,8 @@
             t.start();
         }
 
-        if (BenchmarkDynamicCounters.getValue() != null) {
-            String[] arguments = BenchmarkDynamicCounters.getValue().split(",");
-            if (arguments.length == 0 || (arguments.length % 3) != 0) {
-                throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: (err|out),start,end,(err|out),start,end,... (~ matches multiple digits)");
-            }
-            for (int i = 0; i < arguments.length; i += 3) {
-                if (arguments[i].equals("err")) {
-                    System.setErr(new PrintStream(new BenchmarkCountersOutputStream(System.err, arguments[i + 1], arguments[i + 2])));
-                } else if (arguments[i].equals("out")) {
-                    System.setOut(new PrintStream(new BenchmarkCountersOutputStream(System.out, arguments[i + 1], arguments[i + 2])));
-                } else {
-                    throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: err|out");
-                }
-                // dacapo: "err, starting =====, PASSED in "
-                // specjvm2008: "out,Iteration ~ (~s) begins: ,Iteration ~ (~s) ends:   "
-            }
-            DynamicCounterNode.excludedClassPrefix = "Lcom/oracle/graal/";
-            DynamicCounterNode.enabled = true;
-        }
-        if (GenericDynamicCounters.getValue()) {
-            DynamicCounterNode.enabled = true;
-        }
+        BenchmarkCounters.initialize(graalRuntime.getCompilerToVM());
+
         compilerStartTime = System.nanoTime();
     }
 
@@ -284,84 +258,6 @@
         }
     }
 
-    private final class BenchmarkCountersOutputStream extends CallbackOutputStream {
-
-        private long startTime;
-        private boolean waitingForEnd;
-
-        private BenchmarkCountersOutputStream(PrintStream delegate, String start, String end) {
-            super(delegate, new String[]{start, end, "\n"});
-        }
-
-        @Override
-        protected void patternFound(int index) {
-            switch (index) {
-                case 0:
-                    startTime = System.nanoTime();
-                    DynamicCounterNode.clear();
-                    break;
-                case 1:
-                    waitingForEnd = true;
-                    break;
-                case 2:
-                    if (waitingForEnd) {
-                        waitingForEnd = false;
-                        DynamicCounterNode.dump(delegate, (System.nanoTime() - startTime) / 1000000000d);
-                    }
-                    break;
-            }
-        }
-    }
-
-    public abstract static class CallbackOutputStream extends OutputStream {
-
-        protected final PrintStream delegate;
-        private final byte[][] patterns;
-        private final int[] positions;
-
-        public CallbackOutputStream(PrintStream delegate, String... patterns) {
-            this.delegate = delegate;
-            this.positions = new int[patterns.length];
-            this.patterns = new byte[patterns.length][];
-            for (int i = 0; i < patterns.length; i++) {
-                this.patterns[i] = patterns[i].getBytes();
-            }
-        }
-
-        protected abstract void patternFound(int index);
-
-        @Override
-        public void write(int b) throws IOException {
-            try {
-                delegate.write(b);
-                for (int i = 0; i < patterns.length; i++) {
-                    int j = positions[i];
-                    byte[] cs = patterns[i];
-                    byte patternChar = cs[j];
-                    if (patternChar == '~' && Character.isDigit(b)) {
-                        // nothing to do...
-                    } else {
-                        if (patternChar == '~') {
-                            patternChar = cs[++positions[i]];
-                        }
-                        if (b == patternChar) {
-                            positions[i]++;
-                        } else {
-                            positions[i] = 0;
-                        }
-                    }
-                    if (positions[i] == patterns[i].length) {
-                        positions[i] = 0;
-                        patternFound(i);
-                    }
-                }
-            } catch (RuntimeException e) {
-                e.printStackTrace(delegate);
-                throw e;
-            }
-        }
-    }
-
     /**
      * Take action related to entering a new execution phase.
      * 
@@ -528,9 +424,7 @@
         }
 
         SnippetCounter.printGroups(TTY.out().out());
-        if (GenericDynamicCounters.getValue()) {
-            DynamicCounterNode.dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d);
-        }
+        BenchmarkCounters.shutdown(graalRuntime.getCompilerToVM(), compilerStartTime);
     }
 
     private void flattenChildren(DebugValueMap map, DebugValueMap globalMap) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,347 @@
+/*
+ * 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.debug;
+
+import java.io.*;
+import java.text.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.bridge.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.hotspot.replacements.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.HeapAccess.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.debug.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.options.*;
+import com.oracle.graal.replacements.nodes.*;
+
+/**
+ * This class contains infrastructure to maintain counters based on {@link DynamicCounterNode}s. The
+ * infrastructure is enabled by specifying either the GenericDynamicCounters or
+ * BenchmarkDynamicCounters option.<br/>
+ * 
+ * The counters are kept in a special area in the native JavaThread object, and the number of
+ * counters is configured in {@code thread.hpp (GRAAL_COUNTERS_SIZE)}. This file also contains an
+ * option to exclude compiler threads ({@code GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS}, which
+ * defaults to true).
+ * 
+ * The subsystems that use the logging need to have their own options to turn on the counters, and
+ * insert DynamicCounterNodes when they're enabled.
+ * 
+ * Counters will be displayed as a rate (per second) if their group name starts with "~", otherwise
+ * they will be displayed as a total number.
+ * 
+ * <h1>Example</h1> In order to create statistics about allocations within the DaCapo pmd benchmark
+ * the following steps are necessary:
+ * <ul>
+ * <li>Modify {@code thread.hpp}: increase GRAAL_COUNTER_SIZE. The actual required value depends on
+ * the granularity of the profiling, 10000 should be enough for most cases. This will increase the
+ * JavaThread structure by 80kb.</li>
+ * <li>Also in {@code thread.hpp}: GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS specifies whether the
+ * numbers generated by compiler threads should be excluded (default: true).</li>
+ * <li>Build the Graal VM.</li>
+ * <li>Start the DaCapo pmd benchmark with
+ * {@code "-G:BenchmarkDynamicCounters=err, starting ====, PASSED in "} and
+ * {@code -G:+ProfileAllocations}.</li>
+ * <li>The numbers will only include allocation from compiled code!</li>
+ * <li>The counters can be further configured by modifying the
+ * {@link NewObjectSnippets#PROFILE_MODE} field.</li>
+ * </ul>
+ */
+public class BenchmarkCounters {
+
+    static class Options {
+
+        //@formatter:off
+        @Option(help = "Turn on the benchmark counters, and displays the results on VM shutdown")
+        private static final OptionValue<Boolean> GenericDynamicCounters = new OptionValue<>(false);
+
+        @Option(help = "Turn on the benchmark counters, and listen for specific patterns on System.out/System.err:%n" +
+                       "Format: (err|out),start pattern,end pattern (~ matches multiple digits)%n" +
+                       "Examples:%n" +
+                       "  dacapo = 'err, starting =====, PASSED in'%n" +
+                       "  specjvm2008 = 'out,Iteration ~ (~s) begins:,Iteration ~ (~s) ends:'")
+        private static final OptionValue<String> BenchmarkDynamicCounters = new OptionValue<>(null);
+        //@formatter:on
+    }
+
+    private static final boolean DUMP_STATIC = false;
+
+    public static String excludedClassPrefix = null;
+    public static boolean enabled = false;
+
+    public static final ConcurrentHashMap<String, Integer> indexes = new ConcurrentHashMap<>();
+    public static final ArrayList<String> groups = new ArrayList<>();
+    public static long[] delta;
+    public static final ArrayList<AtomicLong> staticCounters = new ArrayList<>();
+
+    public static int getIndex(DynamicCounterNode counter) {
+        if (!enabled) {
+            throw new GraalInternalError("counter nodes shouldn't exist when counters are not enabled");
+        }
+        String name = counter.getName();
+        String group = counter.getGroup();
+        name = counter.isWithContext() ? name + " @ " + counter.graph().graphId() + ":" + MetaUtil.format("%h.%n", counter.graph().method()) + "#" + group : name + "#" + group;
+        Integer index = indexes.get(name);
+        if (index == null) {
+            synchronized (BenchmarkCounters.class) {
+                index = indexes.get(name);
+                if (index == null) {
+                    index = indexes.size();
+                    indexes.put(name, index);
+                    groups.add(group);
+                    staticCounters.add(new AtomicLong());
+                }
+            }
+        }
+        assert groups.get(index).equals(group) : "mismatching groups: " + groups.get(index) + " vs. " + group;
+        if (counter.getIncrement().isConstant()) {
+            staticCounters.get(index).addAndGet(counter.getIncrement().asConstant().asLong());
+        }
+        return index;
+    }
+
+    public static synchronized void dump(PrintStream out, double seconds, long[] counters) {
+        if (!groups.isEmpty()) {
+            out.println("====== dynamic counters (" + staticCounters.size() + " in total) ======");
+            for (String group : new TreeSet<>(groups)) {
+                if (group != null) {
+                    if (DUMP_STATIC) {
+                        dumpCounters(out, seconds, counters, true, group);
+                    }
+                    dumpCounters(out, seconds, counters, false, group);
+                }
+            }
+            out.println("============================");
+
+            clear(counters);
+        }
+    }
+
+    public static synchronized void clear(long[] counters) {
+        delta = counters;
+    }
+
+    private static synchronized void dumpCounters(PrintStream out, double seconds, long[] counters, boolean staticCounter, String group) {
+        TreeMap<Long, String> sorted = new TreeMap<>();
+
+        long[] array;
+        if (staticCounter) {
+            array = new long[indexes.size()];
+            for (int i = 0; i < array.length; i++) {
+                array[i] = staticCounters.get(i).get();
+            }
+        } else {
+            array = counters.clone();
+            for (int i = 0; i < array.length; i++) {
+                array[i] -= delta[i];
+            }
+        }
+        long sum = 0;
+        for (Map.Entry<String, Integer> entry : indexes.entrySet()) {
+            int index = entry.getValue();
+            if (groups.get(index).equals(group)) {
+                sum += array[index];
+                sorted.put(array[index] * array.length + index, entry.getKey().substring(0, entry.getKey().length() - group.length() - 1));
+            }
+        }
+
+        if (sum > 0) {
+            NumberFormat format = NumberFormat.getInstance(Locale.US);
+            long cutoff = sorted.size() < 10 ? 1 : Math.max(1, sum / 100);
+            if (staticCounter) {
+                out.println("=========== " + group + " (static counters):");
+                for (Map.Entry<Long, String> entry : sorted.entrySet()) {
+                    long counter = entry.getKey() / array.length;
+                    if (counter >= cutoff) {
+                        out.println(format.format(counter) + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue());
+                    }
+                }
+                out.println(sum + ": total");
+            } else {
+                if (group.startsWith("~")) {
+                    out.println("=========== " + group + " (dynamic counters), time = " + seconds + " s:");
+                    for (Map.Entry<Long, String> entry : sorted.entrySet()) {
+                        long counter = entry.getKey() / array.length;
+                        if (counter >= cutoff) {
+                            out.println(format.format((long) (counter / seconds)) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue());
+                        }
+                    }
+                    out.println(format.format((long) (sum / seconds)) + "/s: total");
+                } else {
+                    out.println("=========== " + group + " (dynamic counters):");
+                    for (Map.Entry<Long, String> entry : sorted.entrySet()) {
+                        long counter = entry.getKey() / array.length;
+                        if (counter >= cutoff) {
+                            out.println(format.format(counter) + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue());
+                        }
+                    }
+                    out.println(format.format(sum) + ": total");
+                }
+            }
+        }
+    }
+
+    public abstract static class CallbackOutputStream extends OutputStream {
+
+        protected final PrintStream delegate;
+        private final byte[][] patterns;
+        private final int[] positions;
+
+        public CallbackOutputStream(PrintStream delegate, String... patterns) {
+            this.delegate = delegate;
+            this.positions = new int[patterns.length];
+            this.patterns = new byte[patterns.length][];
+            for (int i = 0; i < patterns.length; i++) {
+                this.patterns[i] = patterns[i].getBytes();
+            }
+        }
+
+        protected abstract void patternFound(int index);
+
+        @Override
+        public void write(int b) throws IOException {
+            try {
+                delegate.write(b);
+                for (int i = 0; i < patterns.length; i++) {
+                    int j = positions[i];
+                    byte[] cs = patterns[i];
+                    byte patternChar = cs[j];
+                    if (patternChar == '~' && Character.isDigit(b)) {
+                        // nothing to do...
+                    } else {
+                        if (patternChar == '~') {
+                            patternChar = cs[++positions[i]];
+                        }
+                        if (b == patternChar) {
+                            positions[i]++;
+                        } else {
+                            positions[i] = 0;
+                        }
+                    }
+                    if (positions[i] == patterns[i].length) {
+                        positions[i] = 0;
+                        patternFound(i);
+                    }
+                }
+            } catch (RuntimeException e) {
+                e.printStackTrace(delegate);
+                throw e;
+            }
+        }
+    }
+
+    public static void initialize(final CompilerToVM compilerToVM) {
+        final class BenchmarkCountersOutputStream extends CallbackOutputStream {
+
+            private long startTime;
+            private boolean waitingForEnd;
+
+            private BenchmarkCountersOutputStream(PrintStream delegate, String start, String end) {
+                super(delegate, new String[]{start, end, "\n"});
+            }
+
+            @Override
+            protected void patternFound(int index) {
+                switch (index) {
+                    case 0:
+                        startTime = System.nanoTime();
+                        BenchmarkCounters.clear(compilerToVM.collectCounters());
+                        break;
+                    case 1:
+                        waitingForEnd = true;
+                        break;
+                    case 2:
+                        if (waitingForEnd) {
+                            waitingForEnd = false;
+                            BenchmarkCounters.dump(delegate, (System.nanoTime() - startTime) / 1000000000d, compilerToVM.collectCounters());
+                        }
+                        break;
+                }
+            }
+        }
+
+        if (Options.BenchmarkDynamicCounters.getValue() != null) {
+            String[] arguments = Options.BenchmarkDynamicCounters.getValue().split(",");
+            if (arguments.length == 0 || (arguments.length % 3) != 0) {
+                throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: (err|out),start,end,(err|out),start,end,... (~ matches multiple digits)");
+            }
+            for (int i = 0; i < arguments.length; i += 3) {
+                if (arguments[i].equals("err")) {
+                    System.setErr(new PrintStream(new BenchmarkCountersOutputStream(System.err, arguments[i + 1], arguments[i + 2])));
+                } else if (arguments[i].equals("out")) {
+                    System.setOut(new PrintStream(new BenchmarkCountersOutputStream(System.out, arguments[i + 1], arguments[i + 2])));
+                } else {
+                    throw new GraalInternalError("invalid arguments to BenchmarkDynamicCounters: err|out");
+                }
+            }
+            excludedClassPrefix = "Lcom/oracle/graal/";
+            enabled = true;
+        }
+        if (Options.GenericDynamicCounters.getValue()) {
+            enabled = true;
+        }
+        if (Options.GenericDynamicCounters.getValue() || Options.BenchmarkDynamicCounters.getValue() != null) {
+            clear(compilerToVM.collectCounters());
+        }
+    }
+
+    public static void shutdown(CompilerToVM compilerToVM, long compilerStartTime) {
+        if (Options.GenericDynamicCounters.getValue()) {
+            dump(System.out, (System.nanoTime() - compilerStartTime) / 1000000000d, compilerToVM.collectCounters());
+        }
+    }
+
+    public static void lower(DynamicCounterNode counter, HotSpotRuntime runtime) {
+        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));
+
+            int index = BenchmarkCounters.getIndex(counter);
+            if (index >= config.graalCountersSize) {
+                throw new GraalInternalError("too many counters, reduce number of counters or increase GRAAL_COUNTERS_SIZE (current value: " + config.graalCountersSize + ")");
+            }
+            ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, config.graalCountersThreadOffset + Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph);
+            ReadNode read = graph.add(new ReadNode(thread, location, StampFactory.forKind(Kind.Long), BarrierType.NONE, false));
+            IntegerAddNode add = graph.unique(new IntegerAddNode(Kind.Long, read, counter.getIncrement()));
+            WriteNode write = graph.add(new WriteNode(thread, add, location, BarrierType.NONE, false));
+
+            graph.addBeforeFixed(counter, thread);
+            graph.addBeforeFixed(counter, read);
+            graph.addBeforeFixed(counter, write);
+        }
+        graph.removeFixed(counter);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Fri Oct 11 17:21:14 2013 +0200
@@ -28,7 +28,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.bridge.*;
 
 /**
@@ -47,20 +46,17 @@
     private final HotSpotResolvedJavaMethod method;
     private final boolean isDefault;
     private final boolean isExternal;
-    private final Graph graph;
 
-    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, Graph graph) {
+    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault) {
         this.method = method;
         this.isDefault = isDefault;
         this.isExternal = false;
-        this.graph = graph;
     }
 
-    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, boolean isExternal, Graph graph) {
+    public HotSpotNmethod(HotSpotResolvedJavaMethod method, boolean isDefault, boolean isExternal) {
         this.method = method;
         this.isDefault = isDefault;
         this.isExternal = isExternal;
-        this.graph = graph;
     }
 
     public boolean isDefault() {
@@ -71,10 +67,6 @@
         return isExternal;
     }
 
-    public Graph getGraph() {
-        return graph;
-    }
-
     @Override
     public ResolvedJavaMethod getMethod() {
         return method;
@@ -123,6 +115,15 @@
         return true;
     }
 
+    public Object executeParallel(int dimX, int dimY, int dimZ, Object... args) throws InvalidInstalledCodeException {
+        assert checkArgs(args);
+
+        assert isExternal(); // for now
+
+        return graalRuntime().getCompilerToGPU().executeParallelMethodVarargs(dimX, dimY, dimZ, args, this);
+
+    }
+
     @Override
     public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
         assert checkArgs(args);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Fri Oct 11 17:21:14 2013 +0200
@@ -99,7 +99,7 @@
         ResolvedJavaMethod initMethod = null;
         try {
             Class<?> rjm = ResolvedJavaMethod.class;
-            makeGraphMethod = runtime.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, rjm, SnippetInliningPolicy.class));
+            makeGraphMethod = runtime.lookupJavaMethod(ReplacementsImpl.class.getDeclaredMethod("makeGraph", rjm, rjm, SnippetInliningPolicy.class, boolean.class));
             initMethod = runtime.lookupJavaMethod(SnippetTemplate.AbstractTemplates.class.getDeclaredMethod("template", Arguments.class));
         } catch (NoSuchMethodException | SecurityException e) {
             throw new GraalInternalError(e);
@@ -169,6 +169,12 @@
 
     private static final String SystemClassName = "Ljava/lang/System;";
 
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The {@code value} field in {@link OptionValue} is considered constant if the type of
+     * {@code receiver} is (assignable to) {@link StableOptionValue}.
+     */
     @Override
     public Constant readConstantValue(Constant receiver) {
         assert !AOTCompilation.getValue() || isCalledForSnippets() : receiver;
@@ -198,6 +204,7 @@
             } else {
                 Class<?> clazz = object.getClass();
                 if (StableOptionValue.class.isAssignableFrom(clazz)) {
+                    assert getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this;
                     StableOptionValue<?> option = (StableOptionValue<?>) object;
                     return Constant.forObject(option.getValue());
                 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Fri Oct 11 17:21:14 2013 +0200
@@ -345,7 +345,11 @@
     @Override
     public ResolvedJavaMethod resolveMethod(ResolvedJavaMethod method) {
         assert method instanceof HotSpotMethod;
-        return (ResolvedJavaMethod) graalRuntime().getCompilerToVM().resolveMethod(this, method.getName(), ((HotSpotSignature) method.getSignature()).getMethodDescriptor());
+        ResolvedJavaMethod res = (ResolvedJavaMethod) graalRuntime().getCompilerToVM().resolveMethod(this, method.getName(), ((HotSpotSignature) method.getSignature()).getMethodDescriptor());
+        if (res == null || isAbstract(res.getModifiers())) {
+            return null;
+        }
+        return res;
     }
 
     @Override
@@ -557,13 +561,14 @@
         return result;
     }
 
-    /**
-     * Gets all methods and constructors declared by this class, including the {@code <clinit>}
-     * method if there is one. The latter is not made accessible via standard Java reflection.
-     */
-    public ResolvedJavaMethod[] getMethods() {
-        HotSpotResolvedJavaMethod[] methods = graalRuntime().getCompilerToVM().getMethods(this);
-        return methods;
+    public ResolvedJavaMethod getClassInitializer() {
+        ResolvedJavaMethod[] methods = graalRuntime().getCompilerToVM().getMethods(this);
+        for (ResolvedJavaMethod m : methods) {
+            if (m.isClassInitializer()) {
+                return m;
+            }
+        }
+        return null;
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedPrimitiveType.java	Fri Oct 11 17:21:14 2013 +0200
@@ -227,6 +227,11 @@
     }
 
     @Override
+    public ResolvedJavaMethod getClassInitializer() {
+        return null;
+    }
+
+    @Override
     public Constant newArray(int length) {
         return Constant.forObject(Array.newInstance(javaMirror, length));
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,8 +23,8 @@
 package com.oracle.graal.hotspot.meta;
 
 import static com.oracle.graal.api.code.CallingConvention.Type.*;
-import static com.oracle.graal.api.code.DeoptimizationAction.*;
 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.*;
@@ -74,6 +74,7 @@
 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.*;
@@ -82,6 +83,7 @@
 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;
@@ -89,14 +91,15 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.word.*;
 
 /**
- * HotSpot implementation of {@link GraalCodeCacheProvider}.
+ * HotSpot implementation of {@link LoweringProvider}.
  */
-public abstract class HotSpotRuntime implements GraalCodeCacheProvider, DisassemblerProvider, BytecodeDisassemblerProvider, SuitesProvider {
+public abstract class HotSpotRuntime implements MetaAccessProvider, ConstantReflectionProvider, CodeCacheProvider, LoweringProvider, DisassemblerProvider, BytecodeDisassemblerProvider, SuitesProvider {
 
     public static final ForeignCallDescriptor OSR_MIGRATION_END = new ForeignCallDescriptor("OSR_migration_end", void.class, long.class);
     public static final ForeignCallDescriptor IDENTITY_HASHCODE = new ForeignCallDescriptor("identity_hashcode", int.class, Object.class);
@@ -250,9 +253,9 @@
      *            cannot be re-executed.
      * @param killedLocations the memory locations killed by the foreign call
      */
-    private void linkForeignCall(Replacements replacements, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable,
+    private void linkForeignCall(Providers providers, ForeignCallDescriptor descriptor, long address, boolean prependThread, Transition transition, boolean reexecutable,
                     LocationIdentity... killedLocations) {
-        ForeignCallStub stub = new ForeignCallStub(this, replacements, address, descriptor, prependThread, transition, reexecutable, killedLocations);
+        ForeignCallStub stub = new ForeignCallStub(providers, address, descriptor, prependThread, transition, reexecutable, killedLocations);
         HotSpotForeignCallLinkage linkage = stub.getLinkage();
         HotSpotForeignCallLinkage targetLinkage = stub.getTargetLinkage();
         linkage.setCompiledStub(stub);
@@ -289,29 +292,31 @@
         registerForeignCall(NEW_INSTANCE_C, c.newInstanceAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
         registerForeignCall(VM_MESSAGE_C, c.vmMessageAddress, NativeCall, DESTROYS_REGISTERS, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
 
-        link(new NewInstanceStub(this, r, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, NOT_LEAF, ANY_LOCATION)));
-        link(new NewArrayStub(this, r, target, registerStubCall(NEW_ARRAY, REEXECUTABLE, NOT_LEAF, INIT_LOCATION)));
-        link(new ExceptionHandlerStub(this, r, target, foreignCalls.get(EXCEPTION_HANDLER)));
-        link(new UnwindExceptionToCallerStub(this, r, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, NOT_LEAF, ANY_LOCATION)));
-        link(new VerifyOopStub(this, r, target, registerStubCall(VERIFY_OOP, REEXECUTABLE, LEAF, NO_LOCATIONS)));
+        Providers providers = new Providers(this, this, this, this, r);
+
+        link(new NewInstanceStub(providers, target, registerStubCall(NEW_INSTANCE, REEXECUTABLE, NOT_LEAF, ANY_LOCATION)));
+        link(new NewArrayStub(providers, target, registerStubCall(NEW_ARRAY, REEXECUTABLE, NOT_LEAF, INIT_LOCATION)));
+        link(new ExceptionHandlerStub(providers, target, foreignCalls.get(EXCEPTION_HANDLER)));
+        link(new UnwindExceptionToCallerStub(providers, target, registerStubCall(UNWIND_EXCEPTION_TO_CALLER, NOT_REEXECUTABLE, NOT_LEAF, ANY_LOCATION)));
+        link(new VerifyOopStub(providers, target, registerStubCall(VERIFY_OOP, REEXECUTABLE, LEAF, NO_LOCATIONS)));
 
-        linkForeignCall(r, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, MARK_WORD_LOCATION);
-        linkForeignCall(r, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);
-        linkForeignCall(r, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);
-        linkForeignCall(r, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
-        linkForeignCall(r, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF, NOT_REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
-        linkForeignCall(r, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, IDENTITY_HASHCODE, c.identityHashCodeAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, MARK_WORD_LOCATION);
+        linkForeignCall(providers, REGISTER_FINALIZER, c.registerFinalizerAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, CREATE_NULL_POINTER_EXCEPTION, c.createNullPointerExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, CREATE_OUT_OF_BOUNDS_EXCEPTION, c.createOutOfBoundsExceptionAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, MONITORENTER, c.monitorenterAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, MONITOREXIT, c.monitorexitAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, NEW_MULTI_ARRAY, c.newMultiArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);
+        linkForeignCall(providers, DYNAMIC_NEW_ARRAY, c.dynamicNewArrayAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, INIT_LOCATION);
+        linkForeignCall(providers, LOG_PRINTF, c.logPrintfAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, LOG_OBJECT, c.logObjectAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, LOG_PRIMITIVE, c.logPrimitiveAddress, PREPEND_THREAD, NOT_LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, THREAD_IS_INTERRUPTED, c.threadIsInterruptedAddress, PREPEND_THREAD, NOT_LEAF, NOT_REEXECUTABLE, ANY_LOCATION);
+        linkForeignCall(providers, VM_ERROR, c.vmErrorAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, OSR_MIGRATION_END, c.osrMigrationEndAddress, DONT_PREPEND_THREAD, LEAF, NOT_REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, G1WBPRECALL, c.writeBarrierPreAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, G1WBPOSTCALL, c.writeBarrierPostAddress, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
+        linkForeignCall(providers, VALIDATE_OBJECT, c.validateObject, PREPEND_THREAD, LEAF, REEXECUTABLE, NO_LOCATIONS);
 
         r.registerSubstitutions(ObjectSubstitutions.class);
         r.registerSubstitutions(SystemSubstitutions.class);
@@ -323,16 +328,16 @@
         r.registerSubstitutions(CRC32Substitutions.class);
         r.registerSubstitutions(ReflectionSubstitutions.class);
 
-        checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(this, r, graalRuntime.getTarget());
-        instanceofSnippets = new InstanceOfSnippets.Templates(this, r, graalRuntime.getTarget());
-        newObjectSnippets = new NewObjectSnippets.Templates(this, r, graalRuntime.getTarget());
-        monitorSnippets = new MonitorSnippets.Templates(this, r, graalRuntime.getTarget(), c.useFastLocking);
-        writeBarrierSnippets = new WriteBarrierSnippets.Templates(this, r, graalRuntime.getTarget());
-        boxingSnippets = new BoxingSnippets.Templates(this, r, graalRuntime.getTarget());
-        exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(this, r, graalRuntime.getTarget());
-        unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(this, r, graalRuntime.getTarget());
+        checkcastDynamicSnippets = new CheckCastDynamicSnippets.Templates(providers, graalRuntime.getTarget());
+        instanceofSnippets = new InstanceOfSnippets.Templates(providers, graalRuntime.getTarget());
+        newObjectSnippets = new NewObjectSnippets.Templates(providers, graalRuntime.getTarget());
+        monitorSnippets = new MonitorSnippets.Templates(providers, graalRuntime.getTarget(), c.useFastLocking);
+        writeBarrierSnippets = new WriteBarrierSnippets.Templates(providers, graalRuntime.getTarget());
+        boxingSnippets = new BoxingSnippets.Templates(providers, graalRuntime.getTarget());
+        exceptionObjectSnippets = new LoadExceptionObjectSnippets.Templates(providers, graalRuntime.getTarget());
+        unsafeLoadSnippets = new UnsafeLoadSnippets.Templates(providers, graalRuntime.getTarget());
 
-        r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(this, r, graalRuntime.getTarget()));
+        r.registerSnippetTemplateCache(new UnsafeArrayCopySnippets.Templates(providers, graalRuntime.getTarget()));
     }
 
     public HotSpotGraalRuntime getGraalRuntime() {
@@ -467,7 +472,7 @@
     }
 
     @Override
-    public RegisterConfig lookupRegisterConfig() {
+    public RegisterConfig getRegisterConfig() {
         return regConfig;
     }
 
@@ -554,7 +559,7 @@
             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), loadField.stamp(), barrierType, (loadField.kind() == Kind.Object)));
+            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);
 
@@ -569,7 +574,7 @@
             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), barrierType, storeField.field().getKind() == Kind.Object));
+            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);
@@ -594,7 +599,7 @@
             LoadIndexedNode loadIndexed = (LoadIndexedNode) n;
             GuardingNode boundsCheck = createBoundsCheck(loadIndexed, tool);
             Kind elementKind = loadIndexed.elementKind();
-            LocationNode arrayLocation = createArrayLocation(graph, elementKind, loadIndexed.index());
+            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);
@@ -602,7 +607,7 @@
             StoreIndexedNode storeIndexed = (StoreIndexedNode) n;
             GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool);
             Kind elementKind = storeIndexed.elementKind();
-            LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index());
+            LocationNode arrayLocation = createArrayLocation(graph, elementKind, storeIndexed.index(), false);
             ValueNode value = storeIndexed.value();
             ValueNode array = storeIndexed.array();
 
@@ -645,14 +650,22 @@
                 checkcastDynamicSnippets.lower(checkcastDynamicNode);
             }
         } else if (n instanceof UnsafeLoadNode) {
-            if (graph.getGuardsStage().ordinal() > StructuredGraph.GuardsStage.FLOATING_GUARDS.ordinal()) {
-                UnsafeLoadNode load = (UnsafeLoadNode) n;
+            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 {
-                    IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, 1);
+                    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.
@@ -662,7 +675,7 @@
             }
         } else if (n instanceof UnsafeStoreNode) {
             UnsafeStoreNode store = (UnsafeStoreNode) n;
-            IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, 1);
+            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));
@@ -717,7 +730,7 @@
                                 value = allocations[commit.getVirtualObjects().indexOf(value)];
                             }
                             if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                WriteNode write = new WriteNode(newObject, value, createFieldLocation(graph, (HotSpotResolvedJavaField) virtualInstance.field(i)),
+                                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));
@@ -735,7 +748,7 @@
                                 value = allocations[indexOf];
                             }
                             if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
-                                WriteNode write = new WriteNode(newObject, value, createArrayLocation(graph, element.getKind(), ConstantNode.forInt(i, graph)),
+                                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));
                             }
@@ -788,6 +801,10 @@
                 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) {
@@ -851,6 +868,43 @@
         }
     }
 
+    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())) {
@@ -941,8 +995,9 @@
         return barrierType;
     }
 
-    protected static ConstantLocationNode createFieldLocation(StructuredGraph graph, HotSpotResolvedJavaField field) {
-        return ConstantLocationNode.create(field, field.getKind(), field.offset(), graph);
+    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) {
@@ -953,9 +1008,10 @@
         }
     }
 
-    protected IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) {
+    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(NamedLocationIdentity.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale);
+        return IndexedLocationNode.create(loc, elementKind, getArrayBaseOffset(elementKind), index, graph, scale);
     }
 
     @Override
@@ -999,7 +1055,7 @@
     private GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) {
         StructuredGraph g = n.graph();
         ValueNode array = n.array();
-        ValueNode arrayLength = readArrayLength(array, tool.getRuntime());
+        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));
@@ -1012,6 +1068,9 @@
     }
 
     public ResolvedJavaType lookupJavaType(Class<?> clazz) {
+        if (clazz == null) {
+            throw new IllegalArgumentException("Class parameter was null");
+        }
         return HotSpotResolvedObjectType.fromClass(clazz);
     }
 
@@ -1043,20 +1102,15 @@
     }
 
     public HotSpotInstalledCode installMethod(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult compResult) {
-        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true, null);
+        HotSpotInstalledCode installedCode = new HotSpotNmethod(method, true);
         graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, entryBCI, compResult), installedCode, method.getSpeculationLog());
         return installedCode;
     }
 
     @Override
     public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
-        return addMethod(method, compResult, null);
-    }
-
-    @Override
-    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) {
         HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false, graph);
+        HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, false);
         CodeInstallResult result = graalRuntime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, -1, compResult), code, null);
         if (result != CodeInstallResult.OK) {
             return null;
@@ -1064,12 +1118,10 @@
         return code;
     }
 
-    public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) {
-
-        // compResult.getTargetCode() == assembled PTX method string
+    public InstalledCode addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
 
         HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
-        HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, false, true, graph);
+        HotSpotInstalledCode icode = new HotSpotNmethod(javaMethod, false, true);
         HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, -1, compResult);
         CompilerToVM vm = graalRuntime.getCompilerToVM();
         CodeInstallResult result = vm.installCode(compiled, icode, null);
@@ -1080,13 +1132,13 @@
     }
 
     @Override
-    public int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) {
+    public Constant encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason) {
         final int actionShift = 0;
         final int reasonShift = 3;
 
         int actionValue = convertDeoptAction(action);
         int reasonValue = convertDeoptReason(reason);
-        return (~(((reasonValue) << reasonShift) + ((actionValue) << actionShift)));
+        return Constant.forInt(~(((reasonValue) << reasonShift) + ((actionValue) << actionShift)));
     }
 
     public int convertDeoptAction(DeoptimizationAction action) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassCastNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,11 +22,12 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
@@ -48,7 +49,8 @@
         return arguments.get(1);
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             ValueNode object = getObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetComponentTypeNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
@@ -42,13 +43,14 @@
         return arguments.get(0);
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             Class c = (Class) javaClass.asConstant().asObject();
             if (c != null) {
                 Class componentType = c.getComponentType();
-                return ConstantNode.forObject(componentType, tool.runtime(), graph());
+                return ConstantNode.forObject(componentType, tool.getMetaAccess(), graph());
             }
         }
         return this;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetModifiersNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
@@ -42,7 +43,8 @@
         return arguments.get(0);
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             Class c = (Class) javaClass.asConstant().asObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassGetSuperclassNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
@@ -42,13 +43,14 @@
         return arguments.get(0);
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             Class c = (Class) javaClass.asConstant().asObject();
             if (c != null) {
                 Class superclass = c.getSuperclass();
-                return ConstantNode.forObject(superclass, tool.runtime(), graph());
+                return ConstantNode.forObject(superclass, tool.getMetaAccess(), graph());
             }
         }
         return this;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsArrayNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
@@ -42,7 +43,8 @@
         return arguments.get(0);
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             Class c = (Class) javaClass.asConstant().asObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInstanceNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,12 +22,13 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 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.replacements.nodes.*;
 
 /**
@@ -49,7 +50,8 @@
         return arguments.get(1);
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             ValueNode object = getObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsInterfaceNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
@@ -42,7 +43,8 @@
         return arguments.get(0);
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             Class c = (Class) javaClass.asConstant().asObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ClassIsPrimitiveNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
 /**
@@ -42,7 +43,8 @@
         return arguments.get(0);
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode javaClass = getJavaClass();
         if (javaClass.isConstant()) {
             Class c = (Class) javaClass.asConstant().asObject();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizeCallerNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizingStubCall.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -36,9 +35,4 @@
     public boolean canDeoptimize() {
         return true;
     }
-
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return null;
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 
@@ -66,11 +65,6 @@
         deoptimizationState = state;
     }
 
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return DeoptimizationReason.NullCheckException;
-    }
-
     public FrameState getState() {
         return deoptimizationState;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/MonitorExitStubCall.java	Fri Oct 11 17:21:14 2013 +0200
@@ -51,7 +51,7 @@
         assert lockDepth != -1;
         HotSpotLIRGenerator hsGen = (HotSpotLIRGenerator) gen;
         StackSlot slot = hsGen.getLockSlot(lockDepth);
-        ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(MonitorExitStubCall.MONITOREXIT);
+        ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(MonitorExitStubCall.MONITOREXIT);
         gen.emitForeignCall(linkage, this, gen.operand(object), gen.emitAddress(slot));
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewArrayStubCall.java	Fri Oct 11 17:21:14 2013 +0200
@@ -62,7 +62,7 @@
 
     @Override
     public void generate(LIRGenerator gen) {
-        ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(NEW_ARRAY);
+        ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(NEW_ARRAY);
         Variable result = gen.emitForeignCall(linkage, this, gen.operand(hub), gen.operand(length));
         gen.setResult(this, result);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewInstanceStubCall.java	Fri Oct 11 17:21:14 2013 +0200
@@ -60,7 +60,7 @@
 
     @Override
     public void generate(LIRGenerator gen) {
-        ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(NEW_INSTANCE);
+        ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(NEW_INSTANCE);
         Variable result = gen.emitForeignCall(linkage, this, gen.operand(hub));
         gen.setResult(this, result);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/NewMultiArrayStubCall.java	Fri Oct 11 17:21:14 2013 +0200
@@ -43,8 +43,8 @@
 
     public static final ForeignCallDescriptor NEW_MULTI_ARRAY = new ForeignCallDescriptor("new_multi_array", Object.class, Word.class, int.class, Word.class);
 
-    public NewMultiArrayStubCall(MetaAccessProvider runtime, ValueNode hub, int rank, ValueNode dims) {
-        super(runtime, NEW_MULTI_ARRAY, defaultStamp);
+    public NewMultiArrayStubCall(MetaAccessProvider metaAccess, ValueNode hub, int rank, ValueNode dims) {
+        super(metaAccess, NEW_MULTI_ARRAY, defaultStamp);
         this.hub = hub;
         this.rank = rank;
         this.dims = dims;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/StubForeignCallNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -37,15 +37,15 @@
 public class StubForeignCallNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Multi {
 
     @Input private final NodeInputList<ValueNode> arguments;
-    private final MetaAccessProvider runtime;
+    private final MetaAccessProvider metaAccess;
 
     private final ForeignCallDescriptor descriptor;
 
-    public StubForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, ValueNode... arguments) {
+    public StubForeignCallNode(MetaAccessProvider metaAccess, ForeignCallDescriptor descriptor, ValueNode... arguments) {
         super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())));
         this.arguments = new NodeInputList<>(this, arguments);
         this.descriptor = descriptor;
-        this.runtime = runtime;
+        this.metaAccess = metaAccess;
     }
 
     public ForeignCallDescriptor getDescriptor() {
@@ -54,7 +54,7 @@
 
     @Override
     public LocationIdentity[] getLocationIdentities() {
-        return runtime.getKilledLocations(descriptor);
+        return metaAccess.getKilledLocations(descriptor);
     }
 
     protected Value[] operands(LIRGeneratorTool gen) {
@@ -68,7 +68,7 @@
     @Override
     public void generate(LIRGeneratorTool gen) {
         assert graph().start() instanceof StubStartNode;
-        ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(descriptor);
+        ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(descriptor);
         Value[] operands = operands(gen);
         Value result = gen.emitForeignCall(linkage, null, operands);
         if (result != null) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/VMErrorNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -57,7 +57,7 @@
         Constant whereArg = Constant.forObject(whereString.intern());
         Constant formatArg = Constant.forObject(format.intern());
 
-        ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(VMErrorNode.VM_ERROR);
+        ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(VMErrorNode.VM_ERROR);
         gen.emitForeignCall(linkage, null, whereArg, formatArg, gen.operand(value));
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,13 +22,12 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
-public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable, IterableNodeType {
+public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable {
 
     @Input private ValueNode object;
     @Input private ValueNode value;
@@ -62,6 +61,6 @@
     @Override
     public void lower(LoweringTool tool) {
         assert graph().getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA;
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -51,10 +51,10 @@
         for (ConstantNode node : graph.getNodes().filter(ConstantNode.class)) {
             Constant constant = node.asConstant();
             if (constant.getKind() == Kind.Object && constant.asObject() instanceof Class<?>) {
-                ResolvedJavaType type = context.getRuntime().lookupJavaType((Class<?>) constant.asObject());
+                ResolvedJavaType type = context.getMetaAccess().lookupJavaType((Class<?>) constant.asObject());
                 assert type instanceof HotSpotResolvedObjectType;
 
-                HotSpotRuntime runtime = (HotSpotRuntime) context.getRuntime();
+                HotSpotRuntime runtime = (HotSpotRuntime) context.getMetaAccess();
 
                 Constant klass = ((HotSpotResolvedObjectType) type).klass();
                 ConstantNode klassNode = ConstantNode.forConstant(klass, runtime, graph);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/VerifyHotSpotOptionsPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.oracle.graal.hotspot.phases;
-
-import static com.oracle.graal.api.meta.MetaUtil.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-import static java.lang.reflect.Modifier.*;
-
-import java.util.*;
-
-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.java.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.util.*;
-import com.oracle.graal.options.*;
-import com.oracle.graal.phases.*;
-
-/**
- * Verifies that a class that declares one or more HotSpot {@linkplain OptionValue options} has a
- * class initializer that only initializes the option(s). This sanity check prevents an option being
- * read to initialize some global state before it is parsed on the command line. The latter occurs
- * if an option declaring class has a class initializer that reads options or triggers other class
- * initializers that read options.
- */
-public class VerifyHotSpotOptionsPhase extends Phase {
-
-    public static boolean checkOptions() {
-        HotSpotRuntime runtime = graalRuntime().getRuntime();
-        ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class);
-        Set<HotSpotResolvedObjectType> checked = new HashSet<>();
-        for (Options opts : sl) {
-            for (OptionDescriptor desc : opts) {
-                if (HotSpotOptions.isHotSpotOption(desc)) {
-                    HotSpotResolvedObjectType holder = (HotSpotResolvedObjectType) runtime.lookupJavaType(desc.getDeclaringClass());
-                    checkType(holder, desc, runtime, checked);
-                }
-            }
-        }
-        return true;
-    }
-
-    private static void checkType(HotSpotResolvedObjectType type, OptionDescriptor option, HotSpotRuntime runtime, Set<HotSpotResolvedObjectType> checked) {
-        if (!checked.contains(type)) {
-            checked.add(type);
-            HotSpotResolvedObjectType superType = type.getSupertype();
-            if (superType != null && !MetaUtil.isJavaLangObject(superType)) {
-                checkType(superType, option, runtime, checked);
-            }
-            for (ResolvedJavaMethod method : type.getMethods()) {
-                if (method.isClassInitializer()) {
-                    StructuredGraph graph = new StructuredGraph(method);
-                    new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
-                    new VerifyHotSpotOptionsPhase(type, runtime, option).apply(graph);
-                }
-            }
-        }
-    }
-
-    private final HotSpotRuntime runtime;
-    private final ResolvedJavaType declaringClass;
-    private final ResolvedJavaType optionValueType;
-    private final Set<ResolvedJavaType> boxingTypes;
-    private final OptionDescriptor option;
-
-    public VerifyHotSpotOptionsPhase(ResolvedJavaType declaringClass, HotSpotRuntime runtime, OptionDescriptor option) {
-        this.runtime = runtime;
-        this.declaringClass = declaringClass;
-        this.optionValueType = runtime.lookupJavaType(OptionValue.class);
-        this.option = option;
-        this.boxingTypes = new HashSet<>();
-        for (Class c : new Class[]{Boolean.class, Byte.class, Short.class, Character.class, Integer.class, Float.class, Long.class, Double.class}) {
-            this.boxingTypes.add(runtime.lookupJavaType(c));
-        }
-    }
-
-    /**
-     * Checks whether a given method is allowed to be called.
-     */
-    private boolean checkInvokeTarget(ResolvedJavaMethod method) {
-        ResolvedJavaType holder = method.getDeclaringClass();
-        if (method.isConstructor()) {
-            if (optionValueType.isAssignableFrom(holder)) {
-                return true;
-            }
-        } else if (boxingTypes.contains(holder)) {
-            return method.getName().equals("valueOf");
-        } else if (method.getDeclaringClass() == runtime.lookupJavaType(Class.class)) {
-            return method.getName().equals("desiredAssertionStatus");
-        } else if (method.getDeclaringClass().equals(declaringClass)) {
-            return (method.getName().equals("$jacocoInit"));
-        }
-        return false;
-    }
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        for (ValueNode node : graph.getNodes().filter(ValueNode.class)) {
-            if (node instanceof StoreFieldNode) {
-                HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) ((StoreFieldNode) node).field();
-                verify(field.getDeclaringClass() == declaringClass, node, "store to field " + format("%H.%n", field));
-                verify(isStatic(field.getModifiers()), node, "store to field " + format("%H.%n", field));
-                if (optionValueType.isAssignableFrom((ResolvedJavaType) field.getType())) {
-                    verify(isFinal(field.getModifiers()), node, "option field " + format("%H.%n", field) + " not final");
-                } else {
-                    verify((field.isSynthetic()), node, "store to non-synthetic field " + format("%H.%n", field));
-                }
-            } else if (node instanceof Invoke) {
-                Invoke invoke = (Invoke) node;
-                MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
-                ResolvedJavaMethod targetMethod = callTarget.targetMethod();
-                verify(checkInvokeTarget(targetMethod), node, "invocation of " + format("%H.%n(%p)", targetMethod));
-            }
-        }
-    }
-
-    private void verify(boolean condition, Node node, String message) {
-        if (!condition) {
-            error(node, message);
-        }
-    }
-
-    private void error(Node node, String message) {
-        String loc = GraphUtil.approxSourceLocation(node);
-        throw new GraalInternalError(String.format("The " + option.getName() + " option is declared in " + option.getDeclaringClass() +
-                        " whose class hierarchy contains a class initializer (in %s) with a code pattern at or near %s implying an action other than initialization of an option:%n%n    %s%n%n" +
-                        "The recommended solution is to move " + option.getName() + " into a separate class (e.g., " + option.getDeclaringClass().getName() + ".Options).%n",
-                        toJavaName(declaringClass), loc, message));
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AESCryptSubstitutions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -66,7 +66,7 @@
     }
 
     private static void crypt(Object rcvr, byte[] in, int inOffset, byte[] out, int outOffset, boolean encrypt) {
-        Object kObject = UnsafeLoadNode.load(rcvr, 0, kOffset, Kind.Object);
+        Object kObject = UnsafeLoadNode.load(rcvr, kOffset, Kind.Object);
         Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte));
         Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
         Word outAddr = Word.unsigned(GetObjectAddressNode.get(out) + arrayBaseOffset(Kind.Byte) + outOffset);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AbstractMethodHandleNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -32,6 +32,7 @@
 import com.oracle.graal.api.meta.ResolvedJavaType;
 import com.oracle.graal.graph.GraalInternalError;
 import com.oracle.graal.graph.NodeInputList;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.meta.HotSpotResolvedJavaMethod;
 import com.oracle.graal.hotspot.meta.HotSpotResolvedObjectType;
 import com.oracle.graal.hotspot.meta.HotSpotSignature;
@@ -43,7 +44,6 @@
 import com.oracle.graal.nodes.java.MethodCallTargetNode;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.java.SelfReplacingMethodCallTargetNode;
-import com.oracle.graal.nodes.spi.Canonicalizable;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.replacements.nodes.MacroNode;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopyNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -75,7 +75,7 @@
             return null;
         }
         Kind componentKind = srcType.getComponentType().getKind();
-        final ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind));
+        final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.getSnippetForKind(componentKind));
         return Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() {
 
             @Override
@@ -93,7 +93,7 @@
         }
         // the canonicalization before loop unrolling is needed to propagate the length into
         // additions, etc.
-        PhaseContext context = new PhaseContext(tool.getRuntime(), tool.assumptions(), tool.getReplacements());
+        PhaseContext context = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getLowerer(), tool.assumptions(), tool.getReplacements());
         new CanonicalizerPhase(true).apply(snippetGraph, context);
         new LoopFullUnrollPhase(new CanonicalizerPhase(true)).apply(snippetGraph, context);
         new CanonicalizerPhase(true).apply(snippetGraph, context);
@@ -108,7 +108,7 @@
         final Replacements replacements = tool.getReplacements();
         StructuredGraph snippetGraph = selectSnippet(tool, replacements);
         if (snippetGraph == null) {
-            final ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(ArrayCopySnippets.genericArraycopySnippet);
+            final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(ArrayCopySnippets.genericArraycopySnippet);
             snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() {
 
                 @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteSubstitutions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -34,7 +34,7 @@
 public class CallSiteSubstitutions implements ReplacementsProvider {
 
     @Override
-    public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
+    public void registerReplacements(MetaAccessProvider metaAccess, 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/CallSiteTargetNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CallSiteTargetNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,6 +26,8 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
@@ -40,7 +42,7 @@
         return arguments.get(0);
     }
 
-    private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccessProvider, Assumptions assumptions) {
+    private ConstantNode getConstantCallTarget(MetaAccessProvider metaAccess, Assumptions assumptions) {
         if (getCallSite().isConstant() && !getCallSite().isNullConstant()) {
             CallSite callSite = (CallSite) getCallSite().asConstant().asObject();
             MethodHandle target = callSite.getTarget();
@@ -50,14 +52,14 @@
                 }
                 assumptions.record(new Assumptions.CallSiteTargetValue(callSite, target));
             }
-            return ConstantNode.forObject(target, metaAccessProvider, graph());
+            return ConstantNode.forObject(target, metaAccess, graph());
         }
         return null;
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        ConstantNode target = getConstantCallTarget(tool.runtime(), tool.assumptions());
+    public Node canonical(CanonicalizerTool tool) {
+        ConstantNode target = getConstantCallTarget(tool.getMetaAccess(), tool.assumptions());
         if (target != null) {
             return target;
         }
@@ -67,7 +69,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        ConstantNode target = getConstantCallTarget(tool.getRuntime(), tool.assumptions());
+        ConstantNode target = getConstantCallTarget(tool.getMetaAccess(), tool.assumptions());
 
         if (target != null) {
             graph().replaceFixedWithFloating(this, target);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CheckCastDynamicSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
 import static com.oracle.graal.hotspot.replacements.TypeCheckSnippetUtils.*;
@@ -34,8 +34,8 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -66,8 +66,8 @@
 
         private final SnippetInfo dynamic = snippet(CheckCastDynamicSnippets.class, "checkcastDynamic");
 
-        public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         public void lower(CheckCastDynamicNode checkcast) {
@@ -80,7 +80,7 @@
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering dynamic checkcast in %s: node=%s, template=%s, arguments=%s", graph, checkcast, template, args);
-            template.instantiate(runtime, checkcast, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), checkcast, DEFAULT_REPLACER, args);
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -62,7 +62,7 @@
 
     @MethodSubstitution(isStatic = false)
     static void encrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
-        Object embeddedCipher = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object);
+        Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object);
         if (getAESCryptClass().isInstance(embeddedCipher)) {
             crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, true);
         } else {
@@ -72,7 +72,7 @@
 
     @MethodSubstitution(isStatic = false)
     static void decrypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset) {
-        Object embeddedCipher = UnsafeLoadNode.load(rcvr, 0, embeddedCipherOffset, Kind.Object);
+        Object embeddedCipher = UnsafeLoadNode.load(rcvr, embeddedCipherOffset, Kind.Object);
         if (in != out && getAESCryptClass().isInstance(embeddedCipher)) {
             crypt(rcvr, in, inOffset, inLength, out, outOffset, embeddedCipher, false);
         } else {
@@ -81,8 +81,8 @@
     }
 
     private static void crypt(Object rcvr, byte[] in, int inOffset, int inLength, byte[] out, int outOffset, Object embeddedCipher, boolean encrypt) {
-        Object kObject = UnsafeLoadNode.load(embeddedCipher, 0, AESCryptSubstitutions.kOffset, Kind.Object);
-        Object rObject = UnsafeLoadNode.load(rcvr, 0, rOffset, Kind.Object);
+        Object kObject = UnsafeLoadNode.load(embeddedCipher, AESCryptSubstitutions.kOffset, Kind.Object);
+        Object rObject = UnsafeLoadNode.load(rcvr, rOffset, Kind.Object);
         Word kAddr = (Word) Word.fromObject(kObject).add(arrayBaseOffset(Kind.Byte));
         Word rAddr = (Word) Word.fromObject(rObject).add(arrayBaseOffset(Kind.Byte));
         Word inAddr = Word.unsigned(GetObjectAddressNode.get(in) + arrayBaseOffset(Kind.Byte) + inOffset);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Fri Oct 11 17:21:14 2013 +0200
@@ -486,7 +486,7 @@
 
     public static Word loadWordFromObject(Object object, int offset) {
         assert offset != hubOffset() : "Use loadHubIntrinsic instead";
-        return loadWordFromObjectIntrinsic(object, 0, offset, getWordKind());
+        return loadWordFromObjectIntrinsic(object, offset, getWordKind());
     }
 
     @NodeIntrinsic(value = ReadRegisterNode.class, setStampFromReturnType = true)
@@ -494,8 +494,8 @@
 
     @SuppressWarnings("unused")
     @NodeIntrinsic(value = UnsafeLoadNode.class, setStampFromReturnType = true)
-    private static Word loadWordFromObjectIntrinsic(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind wordKind) {
-        return Word.unsigned(unsafeReadWord(object, offset + displacement));
+    private static Word loadWordFromObjectIntrinsic(Object object, long offset, @ConstantNodeParameter Kind wordKind) {
+        return Word.unsigned(unsafeReadWord(object, offset));
     }
 
     @SuppressWarnings("unused")
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
@@ -40,6 +40,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
@@ -200,8 +201,8 @@
         private final SnippetInfo instanceofSecondary = snippet(InstanceOfSnippets.class, "instanceofSecondary");
         private final SnippetInfo instanceofDynamic = snippet(InstanceOfSnippets.class, "instanceofDynamic");
 
-        public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         @Override
@@ -211,13 +212,13 @@
                 ValueNode object = instanceOf.object();
                 TypeCheckHints hintInfo = new TypeCheckHints(instanceOf.type(), instanceOf.profile(), tool.assumptions(), InstanceOfMinHintHitProbability.getValue(), InstanceOfMaxHints.getValue());
                 final HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) instanceOf.type();
-                ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, instanceOf.graph());
+                ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), instanceOf.graph());
 
                 Arguments args;
 
                 StructuredGraph graph = hub.graph();
                 if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet()) {
-                    Hints hints = createHints(hintInfo, runtime, false, graph);
+                    Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph);
                     args = new Arguments(instanceofWithProfile, graph.getGuardsStage());
                     args.add("object", object);
                     args.addVarargs("hints", Word.class, StampFactory.forKind(wordKind()), hints.hubs);
@@ -225,14 +226,14 @@
                 } else if (hintInfo.exact != null) {
                     args = new Arguments(instanceofExact, graph.getGuardsStage());
                     args.add("object", object);
-                    args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), runtime, graph));
+                    args.add("exactHub", ConstantNode.forConstant(((HotSpotResolvedObjectType) hintInfo.exact).klass(), providers.getMetaAccess(), graph));
                 } else if (type.isPrimaryType()) {
                     args = new Arguments(instanceofPrimary, graph.getGuardsStage());
                     args.add("hub", hub);
                     args.add("object", object);
                     args.addConst("superCheckOffset", type.superCheckOffset());
                 } else {
-                    Hints hints = createHints(hintInfo, runtime, false, graph);
+                    Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph);
                     args = new Arguments(instanceofSecondary, graph.getGuardsStage());
                     args.add("hub", hub);
                     args.add("object", object);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/LoadExceptionObjectSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -32,8 +32,8 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -64,22 +64,22 @@
 
         private final SnippetInfo loadException = snippet(LoadExceptionObjectSnippets.class, "loadException");
 
-        public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         public void lower(LoadExceptionObjectNode loadExceptionObject) {
             if (USE_C_RUNTIME) {
                 StructuredGraph graph = loadExceptionObject.graph();
-                HotSpotRuntime hsRuntime = (HotSpotRuntime) runtime;
+                HotSpotRuntime hsRuntime = (HotSpotRuntime) providers.getMetaAccess();
                 ReadRegisterNode thread = graph.add(new ReadRegisterNode(hsRuntime.threadRegister(), true, false));
                 graph.addBeforeFixed(loadExceptionObject, thread);
-                ForeignCallNode loadExceptionC = graph.add(new ForeignCallNode(runtime, LOAD_AND_CLEAR_EXCEPTION, thread));
+                ForeignCallNode loadExceptionC = graph.add(new ForeignCallNode(providers.getMetaAccess(), LOAD_AND_CLEAR_EXCEPTION, thread));
                 loadExceptionC.setStateAfter(loadExceptionObject.stateAfter());
                 graph.replaceFixedWithFixed(loadExceptionObject, loadExceptionC);
             } else {
                 Arguments args = new Arguments(loadException, loadExceptionObject.graph().getGuardsStage());
-                template(args).instantiate(runtime, loadExceptionObject, DEFAULT_REPLACER, args);
+                template(args).instantiate(providers.getMetaAccess(), loadExceptionObject, DEFAULT_REPLACER, args);
             }
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleInvokeBasicNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,10 +24,9 @@
 
 import java.lang.invoke.MethodHandle;
 
-import com.oracle.graal.nodes.Invoke;
-import com.oracle.graal.nodes.InvokeNode;
-import com.oracle.graal.nodes.ValueNode;
-import com.oracle.graal.nodes.spi.CanonicalizerTool;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
 
 /**
  * Macro node for {@link MethodHandle}{@code .invokeBasic(Object...)}.
@@ -39,7 +38,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         InvokeNode invoke = getInvokeBasicTarget();
         if (invoke != null) {
             return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToInterfaceNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,10 +24,9 @@
 
 import java.lang.invoke.MethodHandle;
 
-import com.oracle.graal.nodes.Invoke;
-import com.oracle.graal.nodes.InvokeNode;
-import com.oracle.graal.nodes.ValueNode;
-import com.oracle.graal.nodes.spi.CanonicalizerTool;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
 
 /**
  * Macro node for {@link MethodHandle}{@code .linkToInterface(Object...)}.
@@ -39,7 +38,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         InvokeNode invoke = getLinkToTarget();
         if (invoke != null) {
             return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToSpecialNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,10 +24,9 @@
 
 import java.lang.invoke.MethodHandle;
 
-import com.oracle.graal.nodes.Invoke;
-import com.oracle.graal.nodes.InvokeNode;
-import com.oracle.graal.nodes.ValueNode;
-import com.oracle.graal.nodes.spi.CanonicalizerTool;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
 
 /**
  * Macro node for {@link MethodHandle}{@code .linkToSpecial(Object...)}.
@@ -39,7 +38,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         InvokeNode invoke = getLinkToTarget();
         if (invoke != null) {
             return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToStaticNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,10 +24,9 @@
 
 import java.lang.invoke.MethodHandle;
 
-import com.oracle.graal.nodes.Invoke;
-import com.oracle.graal.nodes.InvokeNode;
-import com.oracle.graal.nodes.ValueNode;
-import com.oracle.graal.nodes.spi.CanonicalizerTool;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
 
 /**
  * Macro node for {@link MethodHandle}{@code .linkToStatic(Object...)}.
@@ -39,7 +38,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         InvokeNode invoke = getLinkToTarget();
         if (invoke != null) {
             return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleLinkToVirtualNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,10 +24,9 @@
 
 import java.lang.invoke.MethodHandle;
 
-import com.oracle.graal.nodes.Invoke;
-import com.oracle.graal.nodes.InvokeNode;
-import com.oracle.graal.nodes.ValueNode;
-import com.oracle.graal.nodes.spi.CanonicalizerTool;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
 
 /**
  * Macro node for {@link MethodHandle}{@code .linkToVirtual(Object...)}.
@@ -39,7 +38,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         InvokeNode invoke = getLinkToTarget();
         if (invoke != null) {
             return invoke;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -40,14 +40,18 @@
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
+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.options.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
+import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
 import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
@@ -63,6 +67,22 @@
  */
 public class MonitorSnippets implements Snippets {
 
+    public static class Options {
+
+        //@formatter:off
+        @Option(help = "")
+        private static final OptionValue<Boolean> ProfileMonitors = new OptionValue<>(false);
+        //@formatter:on
+    }
+
+    private static final boolean PROFILE_CONTEXT = false;
+
+    @Fold
+    @SuppressWarnings("unused")
+    private static boolean doProfile(String path) {
+        return Options.ProfileMonitors.getValue();
+    }
+
     /**
      * Monitor operations on objects whose type contains this substring will be traced.
      */
@@ -118,7 +138,7 @@
                 trace(trace, "              tmp: 0x%016lx\n", tmp);
                 if (probability(FREQUENT_PROBABILITY, tmp.equal(0))) {
                     // Object is already biased to current thread -> done
-                    traceObject(trace, "+lock{bias:existing}", object);
+                    traceObject(trace, "+lock{bias:existing}", object, true);
                     return;
                 }
 
@@ -154,13 +174,13 @@
                         trace(trace, "       biasedMark: 0x%016lx\n", biasedMark);
                         if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark))) {
                             // Object is now biased to current thread -> done
-                            traceObject(trace, "+lock{bias:acquired}", object);
+                            traceObject(trace, "+lock{bias:acquired}", object, true);
                             return;
                         }
                         // If the biasing toward our thread failed, this means that another thread
                         // owns the bias and we need to revoke that bias. The revocation will occur
                         // in the interpreter runtime.
-                        traceObject(trace, "+lock{stub:revoke}", object);
+                        traceObject(trace, "+lock{stub:revoke}", object, true);
                         monitorenterStub(MONITORENTER, object, lock);
                         return;
                     } else {
@@ -174,13 +194,13 @@
                         trace(trace, "       biasedMark: 0x%016lx\n", biasedMark);
                         if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark))) {
                             // Object is now biased to current thread -> done
-                            traceObject(trace, "+lock{bias:transfer}", object);
+                            traceObject(trace, "+lock{bias:transfer}", object, true);
                             return;
                         }
                         // If the biasing toward our thread failed, then another thread
                         // succeeded in biasing it toward itself and we need to revoke that
                         // bias. The revocation will occur in the runtime in the slow case.
-                        traceObject(trace, "+lock{stub:epoch-expired}", object);
+                        traceObject(trace, "+lock{stub:epoch-expired}", object, true);
                         monitorenterStub(MONITORENTER, object, lock);
                         return;
                     }
@@ -237,16 +257,16 @@
             final Word stackPointer = stackPointer();
             if (probability(VERY_SLOW_PATH_PROBABILITY, currentMark.subtract(stackPointer).and(alignedMask.subtract(pageSize())).notEqual(0))) {
                 // Most likely not a recursive lock, go into a slow runtime call
-                traceObject(trace, "+lock{stub:failed-cas}", object);
+                traceObject(trace, "+lock{stub:failed-cas}", object, true);
                 monitorenterStub(MONITORENTER, object, lock);
                 return;
             } else {
                 // Recursively locked => write 0 to the lock slot
                 lock.writeWord(lockDisplacedMarkOffset(), Word.zero(), DISPLACED_MARK_WORD_LOCATION);
-                traceObject(trace, "+lock{recursive}", object);
+                traceObject(trace, "+lock{recursive}", object, true);
             }
         } else {
-            traceObject(trace, "+lock{cas}", object);
+            traceObject(trace, "+lock{cas}", object, true);
         }
     }
 
@@ -263,7 +283,7 @@
         // BeginLockScope nodes do not read from object so a use of object
         // cannot float about the null check above
         final Word lock = beginLockScope(lockDepth);
-        traceObject(trace, "+lock{stub}", object);
+        traceObject(trace, "+lock{stub}", object, true);
         monitorenterStub(MONITORENTER, object, lock);
     }
 
@@ -282,7 +302,7 @@
             if (probability(FREQUENT_PROBABILITY, mark.and(biasedLockMaskInPlace()).equal(Word.unsigned(biasedLockPattern())))) {
                 endLockScope();
                 decCounter();
-                traceObject(trace, "-lock{bias}", object);
+                traceObject(trace, "-lock{bias}", object, false);
                 return;
             }
         }
@@ -295,7 +315,7 @@
 
         if (displacedMark.equal(0)) {
             // Recursive locking => done
-            traceObject(trace, "-lock{recursive}", object);
+            traceObject(trace, "-lock{recursive}", object, false);
         } else {
             verifyOop(object);
             // Test if object's mark word is pointing to the displaced mark word, and if so, restore
@@ -304,10 +324,10 @@
             if (probability(VERY_SLOW_PATH_PROBABILITY, DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock))) {
                 // The object's mark word was not pointing to the displaced header,
                 // we do unlocking via runtime call.
-                traceObject(trace, "-lock{stub}", object);
+                traceObject(trace, "-lock{stub}", object, false);
                 MonitorExitStubCall.call(object, lockDepth);
             } else {
-                traceObject(trace, "-lock{cas}", object);
+                traceObject(trace, "-lock{cas}", object, false);
             }
         }
         endLockScope();
@@ -320,13 +340,16 @@
     @Snippet
     public static void monitorexitStub(Object object, @ConstantParameter int lockDepth, @ConstantParameter boolean trace) {
         verifyOop(object);
-        traceObject(trace, "-lock{stub}", object);
+        traceObject(trace, "-lock{stub}", object, false);
         MonitorExitStubCall.call(object, lockDepth);
         endLockScope();
         decCounter();
     }
 
-    private static void traceObject(boolean enabled, String action, Object object) {
+    private static void traceObject(boolean enabled, String action, Object object, boolean enter) {
+        if (doProfile(action)) {
+            DynamicCounterNode.counter(action, enter ? "number of monitor enters" : "number of monitor exits", 1, PROFILE_CONTEXT);
+        }
         if (enabled) {
             Log.print(action);
             Log.print(' ');
@@ -393,8 +416,8 @@
 
         private final boolean useFastLocking;
 
-        public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target, boolean useFastLocking) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target, boolean useFastLocking) {
+            super(providers, target);
             this.useFastLocking = useFastLocking;
         }
 
@@ -414,7 +437,7 @@
             boolean tracingEnabledForMethod = stateAfter != null && (isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
             args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || tracingEnabledForMethod);
 
-            Map<Node, Node> nodes = template(args).instantiate(runtime, monitorenterNode, DEFAULT_REPLACER, args);
+            Map<Node, Node> nodes = template(args).instantiate(providers.getMetaAccess(), monitorenterNode, DEFAULT_REPLACER, args);
 
             for (Node n : nodes.values()) {
                 if (n instanceof BeginLockScopeNode) {
@@ -438,7 +461,7 @@
             args.addConst("lockDepth", monitorexitNode.getLockDepth());
             args.addConst("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method()));
 
-            Map<Node, Node> nodes = template(args).instantiate(runtime, monitorexitNode, DEFAULT_REPLACER, args);
+            Map<Node, Node> nodes = template(args).instantiate(providers.getMetaAccess(), monitorexitNode, DEFAULT_REPLACER, args);
 
             for (Node n : nodes.values()) {
                 if (n instanceof EndLockScopeNode) {
@@ -492,14 +515,14 @@
                     invoke.setStateAfter(graph.start().stateAfter());
                     graph.addAfterFixed(graph.start(), invoke);
 
-                    StructuredGraph inlineeGraph = replacements.getSnippet(initCounter.getMethod());
+                    StructuredGraph inlineeGraph = providers.getReplacements().getSnippet(initCounter.getMethod());
                     InliningUtil.inline(invoke, inlineeGraph, false);
 
                     List<ReturnNode> rets = graph.getNodes().filter(ReturnNode.class).snapshot();
                     for (ReturnNode ret : rets) {
                         returnType = checkCounter.getMethod().getSignature().getReturnType(checkCounter.getMethod().getDeclaringClass());
                         String msg = "unbalanced monitors in " + MetaUtil.format("%H.%n(%p)", graph.method()) + ", count = %d";
-                        ConstantNode errMsg = ConstantNode.forObject(msg, runtime, graph);
+                        ConstantNode errMsg = ConstantNode.forObject(msg, providers.getMetaAccess(), graph);
                         callTarget = graph.add(new MethodCallTargetNode(InvokeKind.Static, checkCounter.getMethod(), new ValueNode[]{errMsg}, returnType));
                         invoke = graph.add(new InvokeNode(callTarget, 0));
                         List<ValueNode> stack = Collections.emptyList();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -34,17 +34,21 @@
 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.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.debug.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.options.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
+import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -58,7 +62,20 @@
 public class NewObjectSnippets implements Snippets {
 
     public static final LocationIdentity INIT_LOCATION = new NamedLocationIdentity("Initialization");
-    public static final LocationIdentity ARRAY_LENGTH_LOCATION = new NamedLocationIdentity("ArrayLength");
+
+    public static class Options {
+
+        //@formatter:off
+        @Option(help = "")
+        private static final OptionValue<Boolean> ProfileAllocations = new OptionValue<>(false);
+        //@formatter:on
+    }
+
+    static enum ProfileMode {
+        AllocatingMethods, InstanceOrArray, AllocatedTypes, AllocatedTypesInMethods, Total
+    }
+
+    public static final ProfileMode PROFILE_MODE = ProfileMode.Total;
 
     @Snippet
     public static Word allocate(int size) {
@@ -77,8 +94,41 @@
         return Word.zero();
     }
 
+    @Fold
+    private static String createName(String path, String typeContext) {
+        switch (PROFILE_MODE) {
+            case AllocatingMethods:
+                return "";
+            case InstanceOrArray:
+                return path;
+            case AllocatedTypes:
+            case AllocatedTypesInMethods:
+                return typeContext;
+            case Total:
+                return "bytes";
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    @Fold
+    @SuppressWarnings("unused")
+    private static boolean doProfile(String path, String typeContext) {
+        return Options.ProfileAllocations.getValue();
+    }
+
+    private static void profileAllocation(String path, long size, String typeContext) {
+        if (doProfile(path, typeContext)) {
+            String name = createName(path, typeContext);
+
+            boolean context = PROFILE_MODE == ProfileMode.AllocatingMethods || PROFILE_MODE == ProfileMode.AllocatedTypesInMethods;
+            DynamicCounterNode.counter(name, "number of bytes allocated", size, context);
+            DynamicCounterNode.counter(name, "number of allocations", 1, context);
+        }
+    }
+
     @Snippet
-    public static Object allocateInstance(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents) {
+    public static Object allocateInstance(@ConstantParameter int size, Word hub, Word prototypeMarkWord, @ConstantParameter boolean fillContents, @ConstantParameter String typeContext) {
         Object result;
         Word thread = thread();
         Word top = readTlabTop(thread);
@@ -91,6 +141,7 @@
             new_stub.inc();
             result = NewInstanceStubCall.call(hub);
         }
+        profileAllocation("instance", size, typeContext);
         return piCast(verifyOop(result), StampFactory.forNodeIntrinsic());
     }
 
@@ -100,15 +151,16 @@
     public static final int MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH = 0x00FFFFFF;
 
     @Snippet
-    public static Object allocateArray(Word hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize, @ConstantParameter boolean fillContents) {
+    public static Object allocateArray(Word hub, int length, Word prototypeMarkWord, @ConstantParameter int headerSize, @ConstantParameter int log2ElementSize,
+                    @ConstantParameter boolean fillContents, @ConstantParameter String typeContext) {
         if (!belowThan(length, MAX_ARRAY_FAST_PATH_ALLOCATION_LENGTH)) {
             // This handles both negative array sizes and very large array sizes
             DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
         }
-        return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents);
+        return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, typeContext);
     }
 
-    private static Object allocateArrayImpl(Word hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents) {
+    private static Object allocateArrayImpl(Word hub, int length, Word prototypeMarkWord, int headerSize, int log2ElementSize, boolean fillContents, String typeContext) {
         Object result;
         int alignment = wordSize();
         int allocationSize = computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
@@ -124,6 +176,7 @@
             newarray_stub.inc();
             result = NewArrayStubCall.call(hub, length);
         }
+        profileAllocation("array", allocationSize, typeContext);
         return piArrayCast(verifyOop(result), length, StampFactory.forNodeIntrinsic());
     }
 
@@ -157,7 +210,7 @@
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
         Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
 
-        return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents);
+        return allocateArrayImpl(hub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents, "dynamic type");
     }
 
     /**
@@ -222,7 +275,7 @@
      * Formats some allocated memory with an object header and zeroes out the rest.
      */
     public static Object formatArray(Word hub, int allocationSize, int length, int headerSize, Word memory, Word prototypeMarkWord, boolean fillContents) {
-        memory.writeInt(arrayLengthOffset(), length, ARRAY_LENGTH_LOCATION);
+        memory.writeInt(arrayLengthOffset(), length, INIT_LOCATION);
         /*
          * store hub last as the concurrent garbage collectors assume length is valid if hub field
          * is not null
@@ -243,8 +296,8 @@
         private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic");
         private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray");
 
-        public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         /**
@@ -254,7 +307,7 @@
             StructuredGraph graph = newInstanceNode.graph();
             HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newInstanceNode.instanceClass();
             assert !type.isArray();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph);
             int size = instanceSize(type);
 
             Arguments args = new Arguments(allocateInstance, graph.getGuardsStage());
@@ -262,10 +315,11 @@
             args.add("hub", hub);
             args.add("prototypeMarkWord", type.prototypeMarkWord());
             args.addConst("fillContents", newInstanceNode.fillContents());
+            args.addConst("typeContext", MetaUtil.toJavaName(type, false));
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering allocateInstance in %s: node=%s, template=%s, arguments=%s", graph, newInstanceNode, template, args);
-            template.instantiate(runtime, newInstanceNode, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), newInstanceNode, DEFAULT_REPLACER, args);
         }
 
         /**
@@ -276,9 +330,9 @@
             ResolvedJavaType elementType = newArrayNode.elementType();
             HotSpotResolvedObjectType arrayType = (HotSpotResolvedObjectType) elementType.getArrayClass();
             Kind elementKind = elementType.getKind();
-            ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), runtime, graph);
+            ConstantNode hub = ConstantNode.forConstant(arrayType.klass(), providers.getMetaAccess(), graph);
             final int headerSize = HotSpotRuntime.getArrayBaseOffset(elementKind);
-            int log2ElementSize = CodeUtil.log2(((HotSpotRuntime) runtime).getScalingFactor(elementKind));
+            int log2ElementSize = CodeUtil.log2(((HotSpotRuntime) providers.getMetaAccess()).getScalingFactor(elementKind));
 
             Arguments args = new Arguments(allocateArray, graph.getGuardsStage());
             args.add("hub", hub);
@@ -287,10 +341,11 @@
             args.addConst("headerSize", headerSize);
             args.addConst("log2ElementSize", log2ElementSize);
             args.addConst("fillContents", newArrayNode.fillContents());
+            args.addConst("typeContext", MetaUtil.toJavaName(arrayType, false));
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args);
-            template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args);
         }
 
         public void lower(DynamicNewArrayNode newArrayNode) {
@@ -300,7 +355,7 @@
             args.addConst("fillContents", newArrayNode.fillContents());
 
             SnippetTemplate template = template(args);
-            template.instantiate(runtime, newArrayNode, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), newArrayNode, DEFAULT_REPLACER, args);
         }
 
         public void lower(NewMultiArrayNode newmultiarrayNode) {
@@ -311,13 +366,13 @@
                 dims[i] = newmultiarrayNode.dimension(i);
             }
             HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) newmultiarrayNode.type();
-            ConstantNode hub = ConstantNode.forConstant(type.klass(), runtime, graph);
+            ConstantNode hub = ConstantNode.forConstant(type.klass(), providers.getMetaAccess(), graph);
 
             Arguments args = new Arguments(newmultiarray, graph.getGuardsStage());
             args.add("hub", hub);
             args.addConst("rank", rank);
             args.addVarargs("dimensions", int.class, StampFactory.forKind(Kind.Int), dims);
-            template(args).instantiate(runtime, newmultiarrayNode, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), newmultiarrayNode, DEFAULT_REPLACER, args);
         }
 
         private static int instanceSize(HotSpotResolvedObjectType type) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -59,49 +59,72 @@
         }
 
         ResolvedJavaType type = ObjectStamp.typeOrNull(getObject());
-        Method method;
-        /*
-         * The first condition tests if the parameter is an array, the second condition tests if the
-         * parameter can be an array. Otherwise, the parameter is known to be a non-array object.
-         */
-        if (type.isArray()) {
-            method = ObjectCloneSnippets.arrayCloneMethod;
-        } else if (type == null || type.isAssignableFrom(tool.getRuntime().lookupJavaType(Object[].class))) {
-            method = ObjectCloneSnippets.genericCloneMethod;
-        } else {
-            method = ObjectCloneSnippets.instanceCloneMethod;
+        if (type != null) {
+            if (type.isArray()) {
+                Method method = ObjectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getKind());
+                if (method != null) {
+                    final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(method);
+                    final Replacements replacements = tool.getReplacements();
+                    StructuredGraph snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() {
+
+                        @Override
+                        public StructuredGraph call() throws Exception {
+                            return replacements.getSnippet(snippetMethod);
+                        }
+                    });
+
+                    assert snippetGraph != null : "ObjectCloneSnippets should be installed";
+                    return lowerReplacement(snippetGraph.copy(), tool);
+                }
+            } else {
+                type = getConcreteType(getObject().stamp(), tool.assumptions(), tool.getMetaAccess());
+                if (type != null) {
+                    StructuredGraph newGraph = new StructuredGraph();
+                    LocalNode local = newGraph.add(new LocalNode(0, getObject().stamp()));
+                    NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true));
+                    newGraph.addAfterFixed(newGraph.start(), newInstance);
+                    ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance));
+                    newGraph.addAfterFixed(newInstance, returnNode);
+
+                    for (ResolvedJavaField field : type.getInstanceFields(true)) {
+                        LoadFieldNode load = newGraph.add(new LoadFieldNode(local, field));
+                        newGraph.addBeforeFixed(returnNode, load);
+                        newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load)));
+                    }
+                    return lowerReplacement(newGraph, tool);
+                }
+            }
         }
-        final ResolvedJavaMethod snippetMethod = tool.getRuntime().lookupJavaMethod(method);
-        final Replacements replacements = tool.getReplacements();
-        StructuredGraph snippetGraph = Debug.scope("ArrayCopySnippet", snippetMethod, new Callable<StructuredGraph>() {
-
-            @Override
-            public StructuredGraph call() throws Exception {
-                return replacements.getSnippet(snippetMethod);
-            }
-        });
-
-        assert snippetGraph != null : "ObjectCloneSnippets should be installed";
-        return lowerReplacement(snippetGraph.copy(), tool);
+        return null;
     }
 
     private static boolean isCloneableType(ResolvedJavaType type, MetaAccessProvider metaAccess) {
-        return type != null && metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type);
+        return metaAccess.lookupJavaType(Cloneable.class).isAssignableFrom(type);
     }
 
-    private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions) {
+    /*
+     * Looks at the given stamp and determines if it is an exact type (or can be assumed to be an
+     * exact type) and if it is a cloneable type.
+     * 
+     * If yes, then the exact type is returned, otherwise it returns null.
+     */
+    private static ResolvedJavaType getConcreteType(Stamp stamp, Assumptions assumptions, MetaAccessProvider metaAccess) {
         if (!(stamp instanceof ObjectStamp)) {
             return null;
         }
         ObjectStamp objectStamp = (ObjectStamp) stamp;
-        if (objectStamp.isExactType() || objectStamp.type() == null) {
-            return objectStamp.type();
+        if (objectStamp.type() == null) {
+            return null;
+        } else if (objectStamp.isExactType()) {
+            return isCloneableType(objectStamp.type(), metaAccess) ? objectStamp.type() : null;
         } else {
             ResolvedJavaType type = objectStamp.type().findUniqueConcreteSubtype();
-            if (type != null) {
+            if (type != null && isCloneableType(type, metaAccess)) {
                 assumptions.recordConcreteSubtype(objectStamp.type(), type);
+                return type;
+            } else {
+                return null;
             }
-            return type;
         }
     }
 
@@ -126,21 +149,19 @@
             } else {
                 obj = tool.getReplacedValue(getObject());
             }
-            ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions());
-            if (isCloneableType(type, tool.getMetaAccessProvider())) {
-                if (!type.isArray()) {
-                    VirtualInstanceNode newVirtual = new VirtualInstanceNode(type, true);
-                    ResolvedJavaField[] fields = newVirtual.getFields();
+            ResolvedJavaType type = getConcreteType(obj.stamp(), tool.getAssumptions(), tool.getMetaAccessProvider());
+            if (type != null && !type.isArray()) {
+                VirtualInstanceNode newVirtual = new VirtualInstanceNode(type, true);
+                ResolvedJavaField[] fields = newVirtual.getFields();
 
-                    ValueNode[] state = new ValueNode[fields.length];
-                    final LoadFieldNode[] loads = new LoadFieldNode[fields.length];
-                    for (int i = 0; i < fields.length; i++) {
-                        state[i] = loads[i] = new LoadFieldNode(obj, fields[i]);
-                        tool.addNode(loads[i]);
-                    }
-                    tool.createVirtualObject(newVirtual, state, null);
-                    tool.replaceWithVirtual(newVirtual);
+                ValueNode[] state = new ValueNode[fields.length];
+                final LoadFieldNode[] loads = new LoadFieldNode[fields.length];
+                for (int i = 0; i < fields.length; i++) {
+                    state[i] = loads[i] = new LoadFieldNode(obj, fields[i]);
+                    tool.addNode(loads[i]);
                 }
+                tool.createVirtualObject(newVirtual, state, null);
+                tool.replaceWithVirtual(newVirtual);
             }
         }
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -22,114 +22,77 @@
  */
 package com.oracle.graal.hotspot.replacements;
 
-import static com.oracle.graal.api.meta.LocationIdentity.*;
-import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
-import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
-import static com.oracle.graal.phases.GraalOptions.*;
+import java.lang.reflect.*;
+import java.util.*;
 
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.replacements.*;
-import com.oracle.graal.word.*;
 
 public class ObjectCloneSnippets implements Snippets {
 
-    public static final Method instanceCloneMethod = getCloneMethod("instanceClone");
-    public static final Method arrayCloneMethod = getCloneMethod("arrayClone");
-    public static final Method genericCloneMethod = getCloneMethod("genericClone");
+    public static final EnumMap<Kind, Method> arrayCloneMethods = new EnumMap<>(Kind.class);
 
-    private static Method getCloneMethod(String name) {
+    static {
+        arrayCloneMethods.put(Kind.Byte, getCloneMethod("byteArrayClone", byte[].class));
+        arrayCloneMethods.put(Kind.Char, getCloneMethod("charArrayClone", char[].class));
+        arrayCloneMethods.put(Kind.Int, getCloneMethod("intArrayClone", int[].class));
+        arrayCloneMethods.put(Kind.Long, getCloneMethod("longArrayClone", long[].class));
+        arrayCloneMethods.put(Kind.Object, getCloneMethod("objectArrayClone", Object[].class));
+    }
+
+    private static Method getCloneMethod(String name, Class<?> param) {
         try {
-            return ObjectCloneSnippets.class.getDeclaredMethod(name, Object.class);
+            return ObjectCloneSnippets.class.getDeclaredMethod(name, param);
         } catch (SecurityException | NoSuchMethodException e) {
             throw new GraalInternalError(e);
         }
     }
 
-    private static Object instanceClone(Object src, Word hub, int layoutHelper) {
-        int instanceSize = layoutHelper;
-        Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
-        Object result = NewObjectSnippets.allocateInstance(instanceSize, hub, prototypeMarkWord, false);
-
-        for (int offset = instanceHeaderSize(); offset < instanceSize; offset += wordSize()) {
-            /*
-             * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values
-             * to be copied atomically, but here they are copied as two 4-byte word values.
-             */
-            ObjectAccess.writeWord(result, offset, ObjectAccess.readWord(src, offset, ANY_LOCATION), ANY_LOCATION);
+    @Snippet(removeAllFrameStates = true)
+    public static byte[] byteArrayClone(byte[] src) {
+        byte[] result = new byte[src.length];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = src[i];
         }
-
         return result;
     }
 
-    private static Object arrayClone(Object src, Word hub, int layoutHelper) {
-        int arrayLength = ArrayLengthNode.arrayLength(src);
-        int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
-        int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
-        int sizeInBytes = NewObjectSnippets.computeArrayAllocationSize(arrayLength, wordSize(), headerSize, log2ElementSize);
-
-        Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
-        Object result = NewObjectSnippets.allocateArray(hub, arrayLength, prototypeMarkWord, headerSize, log2ElementSize, false);
-
-        for (int offset = headerSize; offset < sizeInBytes; offset += wordSize()) {
-            /*
-             * TODO atomicity problem on 32-bit architectures: The JVM spec requires double values
-             * to be copied atomically, but here they are copied as two 4-byte word values.
-             */
-            ObjectAccess.writeWord(result, offset, ObjectAccess.readWord(src, offset, ANY_LOCATION), ANY_LOCATION);
+    @Snippet(removeAllFrameStates = true)
+    public static char[] charArrayClone(char[] src) {
+        char[] result = new char[src.length];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = src[i];
         }
         return result;
     }
 
-    private static Word getAndCheckHub(Object src) {
-        Word hub = loadHub(src);
-        if (!(src instanceof Cloneable)) {
-            DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
+    @Snippet(removeAllFrameStates = true)
+    public static int[] intArrayClone(int[] src) {
+        int[] result = new int[src.length];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = src[i];
         }
-        return hub;
-    }
-
-    @Snippet
-    public static Object instanceClone(Object src) {
-        instanceCloneCounter.inc();
-        Word hub = getAndCheckHub(src);
-        return instanceClone(src, hub, hub.readInt(layoutHelperOffset(), FINAL_LOCATION));
-    }
-
-    @Snippet
-    public static Object arrayClone(Object src) {
-        arrayCloneCounter.inc();
-        Word hub = getAndCheckHub(src);
-        int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION);
-        return arrayClone(src, hub, layoutHelper);
+        return result;
     }
 
-    @Snippet
-    public static Object genericClone(Object src) {
-        genericCloneCounter.inc();
-        Word hub = getAndCheckHub(src);
-        int layoutHelper = hub.readInt(layoutHelperOffset(), FINAL_LOCATION);
-        if (probability(LIKELY_PROBABILITY, layoutHelper < 0)) {
-            genericArrayCloneCounter.inc();
-            return arrayClone(src, hub, layoutHelper);
-        } else {
-            genericInstanceCloneCounter.inc();
-            return instanceClone(src, hub, layoutHelper);
+    @Snippet(removeAllFrameStates = true)
+    public static long[] longArrayClone(long[] src) {
+        long[] result = new long[src.length];
+        for (int i = 0; i < result.length; i++) {
+            result[i] = src[i];
         }
+        return result;
     }
 
-    private static final SnippetCounter.Group cloneCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Object.clone") : null;
-    private static final SnippetCounter instanceCloneCounter = new SnippetCounter(cloneCounters, "instanceClone", "clone snippet for instances");
-    private static final SnippetCounter arrayCloneCounter = new SnippetCounter(cloneCounters, "arrayClone", "clone snippet for arrays");
-    private static final SnippetCounter genericCloneCounter = new SnippetCounter(cloneCounters, "genericClone", "clone snippet for arrays and instances");
-
-    private static final SnippetCounter.Group genericCloneCounters = SnippetCounters.getValue() ? new SnippetCounter.Group("Object.clone generic snippet") : null;
-    private static final SnippetCounter genericInstanceCloneCounter = new SnippetCounter(genericCloneCounters, "genericInstanceClone", "generic clone implementation took instance path");
-    private static final SnippetCounter genericArrayCloneCounter = new SnippetCounter(genericCloneCounters, "genericArrayClone", "generic clone implementation took array path");
-
+    @Snippet(removeAllFrameStates = true)
+    public static Object[] objectArrayClone(Object[] src) {
+        Object[] result = (Object[]) DynamicNewArrayNode.newArray(GuardingPiNode.guardingNonNull(src.getClass().getComponentType()), src.length);
+        for (int i = 0; i < result.length; i++) {
+            result[i] = src[i];
+        }
+        return result;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,6 +26,8 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -57,7 +59,8 @@
         }
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (AOTCompilation.getValue()) {
             return this;
         }
@@ -69,7 +72,7 @@
                 ObjectStamp objectStamp = (ObjectStamp) stamp;
                 if (objectStamp.isExactType()) {
                     Constant clazz = objectStamp.type().getEncoding(Representation.JavaClass);
-                    return ConstantNode.forConstant(clazz, tool.runtime(), graph());
+                    return ConstantNode.forConstant(clazz, tool.getMetaAccess(), graph());
                 }
             }
             return this;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ReflectionGetCallerClassNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -38,8 +39,8 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        ConstantNode callerClassNode = getCallerClassNode(tool.runtime());
+    public Node canonical(CanonicalizerTool tool) {
+        ConstantNode callerClassNode = getCallerClassNode(tool.getMetaAccess());
         if (callerClassNode != null) {
             return callerClassNode;
         }
@@ -48,7 +49,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        ConstantNode callerClassNode = getCallerClassNode(tool.getRuntime());
+        ConstantNode callerClassNode = getCallerClassNode(tool.getMetaAccess());
 
         if (callerClassNode != null) {
             graph().replaceFixedWithFloating(this, callerClassNode);
@@ -63,10 +64,10 @@
      * If inlining is deep enough this method returns a {@link ConstantNode} of the caller class by
      * walking the the stack.
      * 
-     * @param runtime
+     * @param metaAccess
      * @return ConstantNode of the caller class, or null
      */
-    private ConstantNode getCallerClassNode(MetaAccessProvider runtime) {
+    private ConstantNode getCallerClassNode(MetaAccessProvider metaAccess) {
         if (!shouldIntrinsify(getTargetMethod())) {
             return null;
         }
@@ -92,7 +93,7 @@
                     if (!method.ignoredBySecurityStackWalk()) {
                         // We have reached the desired frame; return the holder class.
                         HotSpotResolvedObjectType callerClass = (HotSpotResolvedObjectType) method.getDeclaringClass();
-                        return ConstantNode.forObject(callerClass.mirror(), runtime, graph());
+                        return ConstantNode.forObject(callerClass.mirror(), metaAccess, graph());
                     }
                     break;
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/TypeCheckSnippetUtils.java	Fri Oct 11 17:21:14 2013 +0200
@@ -122,13 +122,13 @@
         }
     }
 
-    static Hints createHints(TypeCheckHints hints, MetaAccessProvider runtime, boolean positiveOnly, Graph graph) {
+    static Hints createHints(TypeCheckHints hints, MetaAccessProvider metaAccess, boolean positiveOnly, Graph graph) {
         ConstantNode[] hubs = new ConstantNode[hints.hints.length];
         boolean[] isPositive = new boolean[hints.hints.length];
         int index = 0;
         for (int i = 0; i < hubs.length; i++) {
             if (!positiveOnly || hints.hints[i].positive) {
-                hubs[index] = ConstantNode.forConstant(((HotSpotResolvedObjectType) hints.hints[i].type).klass(), runtime, graph);
+                hubs[index] = ConstantNode.forConstant(((HotSpotResolvedObjectType) hints.hints[i].type).klass(), metaAccess, graph);
                 isPositive[index] = hints.hints[i].positive;
                 index++;
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,8 +23,8 @@
 package com.oracle.graal.hotspot.replacements;
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 import static com.oracle.graal.replacements.SnippetTemplate.*;
 
@@ -32,7 +32,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -86,42 +86,42 @@
             for (long i = 0; i < postLoopBytes; i += elementSize) {
                 srcOffset -= elementSize;
                 destOffset -= elementSize;
-                Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind);
+                Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind);
             }
             // Main-loop
             for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) {
                 srcOffset -= VECTOR_SIZE;
                 destOffset -= VECTOR_SIZE;
-                Long a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a.longValue(), VECTOR_KIND);
+                Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND);
             }
             // Pre-loop
             for (long i = 0; i < preLoopBytes; i += elementSize) {
                 srcOffset -= elementSize;
                 destOffset -= elementSize;
-                Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind);
+                Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind);
             }
         } else {
             // Pre-loop
             for (long i = 0; i < preLoopBytes; i += elementSize) {
-                Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind);
+                Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind);
                 srcOffset += elementSize;
                 destOffset += elementSize;
             }
             // Main-loop
             for (long i = 0; i < mainLoopBytes; i += VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a.longValue(), VECTOR_KIND);
+                Long a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a.longValue(), VECTOR_KIND);
                 srcOffset += VECTOR_SIZE;
                 destOffset += VECTOR_SIZE;
             }
             // Post-loop
             for (long i = 0; i < postLoopBytes; i += elementSize) {
-                Object a = UnsafeLoadNode.load(src, arrayBaseOffset, srcOffset, baseKind);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, destOffset, a, baseKind);
+                Object a = UnsafeLoadNode.load(src, arrayBaseOffset + srcOffset, baseKind);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + destOffset, a, baseKind);
                 srcOffset += elementSize;
                 destOffset += elementSize;
             }
@@ -167,13 +167,13 @@
         long destOffset = (long) destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
             for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND);
+                Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
             for (long i = 0; i < byteLength; i += VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND);
+                Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND);
             }
         }
     }
@@ -187,8 +187,8 @@
         long destOffset = (long) destPos * arrayIndexScale(baseKind);
         if (src == dest && srcPos < destPos) { // bad aliased case
             for (long i = byteLength - VECTOR_SIZE; i >= 0; i -= VECTOR_SIZE) {
-                Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND);
+                Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND);
             }
         } else {
             for (long i = 0; i < byteLength; i += VECTOR_SIZE) {
@@ -197,8 +197,8 @@
                  * values to be copied atomically, but not long values. For example, on Intel 32-bit
                  * this code is not atomic as long as the vector kind remains Kind.Long.
                  */
-                Long a = UnsafeLoadNode.load(src, arrayBaseOffset, i + srcOffset, VECTOR_KIND);
-                UnsafeStoreNode.store(dest, arrayBaseOffset, i + destOffset, a.longValue(), VECTOR_KIND);
+                Long a = UnsafeLoadNode.load(src, arrayBaseOffset + i + srcOffset, VECTOR_KIND);
+                UnsafeStoreNode.store(dest, arrayBaseOffset + i + destOffset, a.longValue(), VECTOR_KIND);
             }
         }
     }
@@ -213,13 +213,13 @@
         if (src == dest && srcPos < destPos) { // bad aliased case
             long start = (long) (length - 1) * scale;
             for (long i = start; i >= 0; i -= scale) {
-                Object a = UnsafeLoadNode.load(src, arrayBaseOffset, i + (long) srcPos * scale, Kind.Object);
+                Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object);
                 DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a);
             }
         } else {
             long end = (long) length * scale;
             for (long i = 0; i < end; i += scale) {
-                Object a = UnsafeLoadNode.load(src, arrayBaseOffset, i + (long) srcPos * scale, Kind.Object);
+                Object a = UnsafeLoadNode.load(src, arrayBaseOffset + i + (long) srcPos * scale, Kind.Object);
                 DirectObjectStoreNode.storeObject(dest, arrayBaseOffset, i + (long) destPos * scale, a);
             }
         }
@@ -256,8 +256,8 @@
         private final SnippetInfo[] arraycopySnippets;
         private final SnippetInfo genericPrimitiveSnippet;
 
-        public Templates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
 
             arraycopySnippets = new SnippetInfo[Kind.values().length];
             arraycopySnippets[Kind.Boolean.ordinal()] = snippet(UnsafeArrayCopySnippets.class, "arraycopyBoolean");
@@ -288,7 +288,7 @@
             node.addSnippetArguments(args);
 
             SnippetTemplate template = template(args);
-            template.instantiate(runtime, node, DEFAULT_REPLACER, args);
+            template.instantiate(providers.getMetaAccess(), node, DEFAULT_REPLACER, args);
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeLoadSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -30,6 +30,7 @@
 import com.oracle.graal.nodes.HeapAccess.BarrierType;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -39,9 +40,8 @@
 public class UnsafeLoadSnippets implements Snippets {
 
     @Snippet
-    public static Object lowerUnsafeLoad(Object object, long offset, int disp) {
+    public static Object lowerUnsafeLoad(Object object, long displacement) {
         Object fixedObject = FixedValueAnchorNode.getObject(object);
-        long displacement = disp + offset;
         if (object instanceof java.lang.ref.Reference && referentOffset() == displacement) {
             return Word.fromObject(fixedObject).readObject((int) displacement, BarrierType.PRECISE, true);
         } else {
@@ -53,16 +53,15 @@
 
         private final SnippetInfo unsafeLoad = snippet(UnsafeLoadSnippets.class, "lowerUnsafeLoad");
 
-        public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         public void lower(UnsafeLoadNode load, @SuppressWarnings("unused") LoweringTool tool) {
             Arguments args = new Arguments(unsafeLoad, load.graph().getGuardsStage());
             args.add("object", load.object());
             args.add("offset", load.offset());
-            args.add("disp", load.displacement());
-            template(args).instantiate(runtime, load, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), load, DEFAULT_REPLACER, args);
         }
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -38,6 +38,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
@@ -336,8 +337,8 @@
         private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier");
         private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier");
 
-        public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
         }
 
         public void lower(SerialWriteBarrier writeBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -346,7 +347,7 @@
             args.add("location", writeBarrier.getLocation());
             args.addConst("usePrecise", writeBarrier.usePrecise());
             args.addConst("alwaysNull", ObjectStamp.isObjectAlwaysNull(writeBarrier.getValue()));
-            template(args).instantiate(runtime, writeBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), writeBarrier, DEFAULT_REPLACER, args);
         }
 
         public void lower(SerialArrayRangeWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -354,7 +355,7 @@
             args.add("object", arrayRangeWriteBarrier.getObject());
             args.add("startIndex", arrayRangeWriteBarrier.getStartIndex());
             args.add("length", arrayRangeWriteBarrier.getLength());
-            template(args).instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1PreWriteBarrier writeBarrierPre, @SuppressWarnings("unused") LoweringTool tool) {
@@ -365,7 +366,7 @@
             args.addConst("doLoad", writeBarrierPre.doLoad());
             args.addConst("nullCheck", writeBarrierPre.getNullCheck());
             args.addConst("trace", traceBarrier());
-            template(args).instantiate(runtime, writeBarrierPre, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), writeBarrierPre, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1ReferentFieldReadBarrier readBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -376,7 +377,7 @@
             args.addConst("doLoad", readBarrier.doLoad());
             args.addConst("nullCheck", false);
             args.addConst("trace", traceBarrier());
-            template(args).instantiate(runtime, readBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), readBarrier, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1PostWriteBarrier writeBarrierPost, @SuppressWarnings("unused") LoweringTool tool) {
@@ -387,7 +388,7 @@
             args.addConst("usePrecise", writeBarrierPost.usePrecise());
             args.addConst("alwaysNull", ObjectStamp.isObjectAlwaysNull(writeBarrierPost.getValue()));
             args.addConst("trace", traceBarrier());
-            template(args).instantiate(runtime, writeBarrierPost, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), writeBarrierPost, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1ArrayRangePreWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -395,7 +396,7 @@
             args.add("object", arrayRangeWriteBarrier.getObject());
             args.add("startIndex", arrayRangeWriteBarrier.getStartIndex());
             args.add("length", arrayRangeWriteBarrier.getLength());
-            template(args).instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
 
         public void lower(G1ArrayRangePostWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) {
@@ -403,7 +404,7 @@
             args.add("object", arrayRangeWriteBarrier.getObject());
             args.add("startIndex", arrayRangeWriteBarrier.getStartIndex());
             args.add("length", arrayRangeWriteBarrier.getLength());
-            template(args).instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
+            template(args).instantiate(providers.getMetaAccess(), arrayRangeWriteBarrier, DEFAULT_REPLACER, args);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Fri Oct 11 17:21:14 2013 +0200
@@ -32,9 +32,8 @@
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
@@ -49,8 +48,8 @@
  */
 public class ExceptionHandlerStub extends SnippetStub {
 
-    public ExceptionHandlerStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public ExceptionHandlerStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java	Fri Oct 11 17:21:14 2013 +0200
@@ -43,9 +43,9 @@
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.nodes.*;
 import com.oracle.graal.word.*;
@@ -85,9 +85,9 @@
      *            be re-executed.
      * @param killedLocations the memory locations killed by the stub call
      */
-    public ForeignCallStub(HotSpotRuntime runtime, Replacements replacements, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable,
+    public ForeignCallStub(Providers providers, long address, ForeignCallDescriptor descriptor, boolean prependThread, Transition transition, boolean reexecutable,
                     LocationIdentity... killedLocations) {
-        super(runtime, replacements, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
+        super(providers, HotSpotForeignCallLinkage.create(descriptor, 0L, PRESERVES_REGISTERS, JavaCall, JavaCallee, transition, reexecutable, killedLocations));
         this.prependThread = prependThread;
         Class[] targetParameterTypes = createTargetParameters(descriptor);
         ForeignCallDescriptor targetSig = new ForeignCallDescriptor(descriptor.getName() + ":C", descriptor.getResultType(), targetParameterTypes);
@@ -304,8 +304,8 @@
 
     private void inline(InvokeNode invoke) {
         ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
-        ReplacementsImpl repl = new ReplacementsImpl(runtime, new Assumptions(false), runtime.getTarget());
-        StructuredGraph calleeGraph = repl.makeGraph(method, null, null);
+        ReplacementsImpl repl = new ReplacementsImpl(runtime, runtime, runtime, runtime, new Assumptions(false), runtime.getTarget());
+        StructuredGraph calleeGraph = repl.makeGraph(method, null, null, false);
         InliningUtil.inline(invoke, calleeGraph, false);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Fri Oct 11 17:21:14 2013 +0200
@@ -37,7 +37,7 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.StructuredGraph.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -53,8 +53,8 @@
  */
 public class NewArrayStub extends SnippetStub {
 
-    public NewArrayStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public NewArrayStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Fri Oct 11 17:21:14 2013 +0200
@@ -38,7 +38,7 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.StructuredGraph.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.Fold;
@@ -54,8 +54,8 @@
  */
 public class NewInstanceStub extends SnippetStub {
 
-    public NewInstanceStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public NewInstanceStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,10 +27,9 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.GuardsStage;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -43,8 +42,8 @@
 
     static class Template extends AbstractTemplates {
 
-        Template(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, Class<? extends Snippets> declaringClass) {
-            super(runtime, replacements, target);
+        Template(Providers providers, TargetDescription target, Class<? extends Snippets> declaringClass) {
+            super(providers, target);
             this.info = snippet(declaringClass, null);
         }
 
@@ -66,9 +65,9 @@
      * 
      * @param linkage linkage details for a call to the stub
      */
-    public SnippetStub(HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, linkage);
-        this.snippet = new Template(runtime, replacements, target, getClass());
+    public SnippetStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, linkage);
+        this.snippet = new Template(providers, target, getClass());
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Fri Oct 11 17:21:14 2013 +0200
@@ -40,9 +40,9 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
+import com.oracle.graal.phases.util.*;
 
 //JaCoCo Exclude
 
@@ -93,17 +93,17 @@
 
     protected final HotSpotRuntime runtime;
 
-    protected final Replacements replacements;
+    protected final Providers providers;
 
     /**
      * Creates a new stub.
      * 
      * @param linkage linkage details for a call to the stub
      */
-    public Stub(HotSpotRuntime runtime, Replacements replacements, HotSpotForeignCallLinkage linkage) {
+    public Stub(Providers providers, HotSpotForeignCallLinkage linkage) {
         this.linkage = linkage;
-        this.runtime = runtime;
-        this.replacements = replacements;
+        this.runtime = (HotSpotRuntime) providers.getMetaAccess();
+        this.providers = providers;
     }
 
     /**
@@ -156,7 +156,7 @@
                     phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                     // The stub itself needs the incoming calling convention.
                     CallingConvention incomingCc = linkage.getIncomingCallingConvention();
-                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), runtime, replacements, backend, runtime.getTarget(), null, phasePlan,
+                    final CompilationResult compResult = GraalCompiler.compileGraph(graph, incomingCc, getInstalledCodeOwner(), providers, backend, runtime.getTarget(), null, phasePlan,
                                     OptimisticOptimizations.ALL, new SpeculationLog(), runtime.getDefaultSuites(), new CompilationResult());
 
                     assert destroyedRegisters != null;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
-import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
 import static com.oracle.graal.hotspot.nodes.CStringNode.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Fri Oct 11 17:21:14 2013 +0200
@@ -32,10 +32,9 @@
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
@@ -46,8 +45,8 @@
  */
 public class UnwindExceptionToCallerStub extends SnippetStub {
 
-    public UnwindExceptionToCallerStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public UnwindExceptionToCallerStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/VerifyOopStub.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,7 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 
 /**
@@ -35,8 +35,8 @@
  */
 public class VerifyOopStub extends SnippetStub {
 
-    public VerifyOopStub(final HotSpotRuntime runtime, Replacements replacements, TargetDescription target, HotSpotForeignCallLinkage linkage) {
-        super(runtime, replacements, target, linkage);
+    public VerifyOopStub(Providers providers, TargetDescription target, HotSpotForeignCallLinkage linkage) {
+        super(providers, target, linkage);
     }
 
     @Snippet
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,7 +27,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.java.decompiler.test.example.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.printer.*;
 
 public class Test {
@@ -39,9 +38,9 @@
      */
     public static void main(String[] args) throws NoSuchMethodException, SecurityException {
         DebugEnvironment.initialize(System.out);
-        GraalCodeCacheProvider runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
+        MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
         Method method = Example.class.getDeclaredMethod("loop7", new Class[]{int.class, int.class});
-        final ResolvedJavaMethod javaMethod = runtime.lookupJavaMethod(method);
+        final ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method);
         TestUtil.compileMethod(javaMethod);
     }
 }
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Fri Oct 11 17:21:14 2013 +0200
@@ -32,24 +32,24 @@
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 public class TestUtil {
 
     public static void compileMethod(ResolvedJavaMethod method) {
-        GraalCodeCacheProvider runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
-        Replacements replacements = Graal.getRequiredCapability(Replacements.class);
+        Providers providers = GraalCompiler.getGraalProviders();
         Suites suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
         StructuredGraph graph = new StructuredGraph(method);
-        new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+        new GraphBuilderPhase(providers.getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
         PhasePlan phasePlan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
-        CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
+        CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false);
         Backend backend = Graal.getRequiredCapability(Backend.class);
-        GraalCompiler.compileGraph(graph, cc, method, runtime, replacements, backend, runtime.getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suites, new CompilationResult());
+        GraalCompiler.compileGraph(graph, cc, method, providers, backend, providers.getCodeCache().getTarget(), null, phasePlan, OptimisticOptimizations.ALL, new SpeculationLog(), suites,
+                        new CompilationResult());
     }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.java;
 
-import static com.oracle.graal.api.code.DeoptimizationAction.*;
 import static com.oracle.graal.api.code.TypeCheckHints.*;
+import static com.oracle.graal.api.meta.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.bytecode.Bytecodes.*;
 import static com.oracle.graal.java.GraphBuilderPhase.RuntimeCalls.*;
@@ -50,7 +50,6 @@
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.phases.util.*;
 
 /**
  * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph.
@@ -86,7 +85,7 @@
      */
     protected BlockPlaceholderNode placeholders;
 
-    private final MetaAccessProvider runtime;
+    private final MetaAccessProvider metaAccess;
     private ConstantPool constantPool;
     private ResolvedJavaMethod method;
     private int entryBCI;
@@ -151,11 +150,11 @@
         return currentGraph;
     }
 
-    public GraphBuilderPhase(MetaAccessProvider runtime, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
+    public GraphBuilderPhase(MetaAccessProvider metaAccess, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) {
         this.graphBuilderConfig = graphBuilderConfig;
         this.optimisticOpts = optimisticOpts;
-        this.runtime = runtime;
-        assert runtime != null;
+        this.metaAccess = metaAccess;
+        assert metaAccess != null;
     }
 
     @Override
@@ -436,7 +435,7 @@
 
         DispatchBeginNode dispatchBegin;
         if (exceptionObject == null) {
-            dispatchBegin = currentGraph.add(new ExceptionObjectNode(runtime));
+            dispatchBegin = currentGraph.add(new ExceptionObjectNode(metaAccess));
             dispatchState.apush(dispatchBegin);
             dispatchState.setRethrowException(true);
             dispatchBegin.setStateAfter(dispatchState.create(bci));
@@ -895,7 +894,7 @@
 
     private void genNewPrimitiveArray(int typeCode) {
         Class<?> clazz = arrayTypeCodeToClass(typeCode);
-        ResolvedJavaType elementType = runtime.lookupJavaType(clazz);
+        ResolvedJavaType elementType = metaAccess.lookupJavaType(clazz);
         frameState.apush(append(new NewArrayNode(elementType, frameState.ipop(), true)));
     }
 
@@ -957,10 +956,10 @@
         lastInstr = falseSucc;
 
         if (OmitHotExceptionStacktrace.getValue()) {
-            ValueNode exception = ConstantNode.forObject(cachedNullPointerException, runtime, currentGraph);
+            ValueNode exception = ConstantNode.forObject(cachedNullPointerException, metaAccess, currentGraph);
             trueSucc.setNext(handleException(exception, bci()));
         } else {
-            ForeignCallNode call = currentGraph.add(new ForeignCallNode(runtime, CREATE_NULL_POINTER_EXCEPTION));
+            ForeignCallNode call = currentGraph.add(new ForeignCallNode(metaAccess, CREATE_NULL_POINTER_EXCEPTION));
             call.setStateAfter(frameState.create(bci()));
             trueSucc.setNext(call);
             call.setNext(handleException(call, bci()));
@@ -981,10 +980,10 @@
         lastInstr = trueSucc;
 
         if (OmitHotExceptionStacktrace.getValue()) {
-            ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, runtime, currentGraph);
+            ValueNode exception = ConstantNode.forObject(cachedArrayIndexOutOfBoundsException, metaAccess, currentGraph);
             falseSucc.setNext(handleException(exception, bci()));
         } else {
-            ForeignCallNode call = currentGraph.add(new ForeignCallNode(runtime, CREATE_OUT_OF_BOUNDS_EXCEPTION, index));
+            ForeignCallNode call = currentGraph.add(new ForeignCallNode(metaAccess, CREATE_OUT_OF_BOUNDS_EXCEPTION, index));
             call.setStateAfter(frameState.create(bci()));
             falseSucc.setNext(call);
             call.setNext(handleException(call, bci()));
@@ -1082,7 +1081,7 @@
         if (target instanceof ResolvedJavaMethod) {
             Object appendix = constantPool.lookupAppendix(stream.readCPI4(), Bytecodes.INVOKEDYNAMIC);
             if (appendix != null) {
-                frameState.apush(ConstantNode.forObject(appendix, runtime, currentGraph));
+                frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph));
             }
             ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(false), target.getSignature().getParameterCount(false));
             appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args);
@@ -1099,7 +1098,7 @@
             boolean hasReceiver = !isStatic(((ResolvedJavaMethod) target).getModifiers());
             Object appendix = constantPool.lookupAppendix(stream.readCPI(), Bytecodes.INVOKEVIRTUAL);
             if (appendix != null) {
-                frameState.apush(ConstantNode.forObject(appendix, runtime, currentGraph));
+                frameState.apush(ConstantNode.forObject(appendix, metaAccess, currentGraph));
             }
             ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver));
             if (hasReceiver) {
@@ -1352,7 +1351,7 @@
 
     protected ConstantNode appendConstant(Constant constant) {
         assert constant != null;
-        return ConstantNode.forConstant(constant, runtime, currentGraph);
+        return ConstantNode.forConstant(constant, metaAccess, currentGraph);
     }
 
     private <T extends ControlSinkNode> T append(T fixed) {
@@ -1693,20 +1692,7 @@
     }
 
     private static boolean isBlockEnd(Node n) {
-        return trueSuccessorCount(n) > 1 || n instanceof ReturnNode || n instanceof UnwindNode || n instanceof DeoptimizeNode;
-    }
-
-    private static int trueSuccessorCount(Node n) {
-        if (n == null) {
-            return 0;
-        }
-        int i = 0;
-        for (Node s : n.successors()) {
-            if (Util.isFixed(s)) {
-                i++;
-            }
-        }
-        return i;
+        return n instanceof ControlSplitNode || n instanceof ControlSinkNode;
     }
 
     private void iterateBytecodesForBlock(Block block) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/VerifyOptionsPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.graal.java;
+
+import static com.oracle.graal.api.meta.MetaUtil.*;
+import static java.lang.reflect.Modifier.*;
+
+import java.util.*;
+
+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.util.*;
+import com.oracle.graal.options.*;
+import com.oracle.graal.phases.*;
+
+/**
+ * Verifies that a class declaring one or more {@linkplain OptionValue options} has a class
+ * initializer that only initializes the option(s). This sanity check mitigates the possibility of
+ * an option value being used before the code that sets the value (e.g., from the command line) has
+ * been executed.
+ */
+public class VerifyOptionsPhase extends Phase {
+
+    public static boolean checkOptions(MetaAccessProvider metaAccess) {
+        ServiceLoader<Options> sl = ServiceLoader.loadInstalled(Options.class);
+        Set<ResolvedJavaType> checked = new HashSet<>();
+        for (Options opts : sl) {
+            for (OptionDescriptor desc : opts) {
+                ResolvedJavaType holder = metaAccess.lookupJavaType(desc.getDeclaringClass());
+                checkType(holder, desc, metaAccess, checked);
+            }
+        }
+        return true;
+    }
+
+    private static void checkType(ResolvedJavaType type, OptionDescriptor option, MetaAccessProvider metaAccess, Set<ResolvedJavaType> checked) {
+        if (!checked.contains(type)) {
+            checked.add(type);
+            ResolvedJavaType superType = type.getSuperclass();
+            if (superType != null && !MetaUtil.isJavaLangObject(superType)) {
+                checkType(superType, option, metaAccess, checked);
+            }
+            for (ResolvedJavaMethod method : type.getDeclaredMethods()) {
+                if (method.isClassInitializer()) {
+                    StructuredGraph graph = new StructuredGraph(method);
+                    new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getEagerDefault(), OptimisticOptimizations.ALL).apply(graph);
+                    new VerifyOptionsPhase(type, metaAccess, option).apply(graph);
+                }
+            }
+        }
+    }
+
+    private final MetaAccessProvider metaAccess;
+    private final ResolvedJavaType declaringClass;
+    private final ResolvedJavaType optionValueType;
+    private final Set<ResolvedJavaType> boxingTypes;
+    private final OptionDescriptor option;
+
+    public VerifyOptionsPhase(ResolvedJavaType declaringClass, MetaAccessProvider metaAccess, OptionDescriptor option) {
+        this.metaAccess = metaAccess;
+        this.declaringClass = declaringClass;
+        this.optionValueType = metaAccess.lookupJavaType(OptionValue.class);
+        this.option = option;
+        this.boxingTypes = new HashSet<>();
+        for (Class c : new Class[]{Boolean.class, Byte.class, Short.class, Character.class, Integer.class, Float.class, Long.class, Double.class}) {
+            this.boxingTypes.add(metaAccess.lookupJavaType(c));
+        }
+    }
+
+    /**
+     * Checks whether a given method is allowed to be called.
+     */
+    private boolean checkInvokeTarget(ResolvedJavaMethod method) {
+        ResolvedJavaType holder = method.getDeclaringClass();
+        if (method.isConstructor()) {
+            if (optionValueType.isAssignableFrom(holder)) {
+                return true;
+            }
+        } else if (boxingTypes.contains(holder)) {
+            return method.getName().equals("valueOf");
+        } else if (method.getDeclaringClass() == metaAccess.lookupJavaType(Class.class)) {
+            return method.getName().equals("desiredAssertionStatus");
+        } else if (method.getDeclaringClass().equals(declaringClass)) {
+            return (method.getName().equals("$jacocoInit"));
+        }
+        return false;
+    }
+
+    @Override
+    protected void run(StructuredGraph graph) {
+        for (ValueNode node : graph.getNodes().filter(ValueNode.class)) {
+            if (node instanceof StoreFieldNode) {
+                ResolvedJavaField field = ((StoreFieldNode) node).field();
+                verify(field.getDeclaringClass() == declaringClass, node, "store to field " + format("%H.%n", field));
+                verify(isStatic(field.getModifiers()), node, "store to field " + format("%H.%n", field));
+                if (optionValueType.isAssignableFrom((ResolvedJavaType) field.getType())) {
+                    verify(isFinal(field.getModifiers()), node, "option field " + format("%H.%n", field) + " not final");
+                } else {
+                    verify((field.isSynthetic()), node, "store to non-synthetic field " + format("%H.%n", field));
+                }
+            } else if (node instanceof Invoke) {
+                Invoke invoke = (Invoke) node;
+                MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
+                ResolvedJavaMethod targetMethod = callTarget.targetMethod();
+                verify(checkInvokeTarget(targetMethod), node, "invocation of " + format("%H.%n(%p)", targetMethod));
+            }
+        }
+    }
+
+    private void verify(boolean condition, Node node, String message) {
+        if (!condition) {
+            error(node, message);
+        }
+    }
+
+    private void error(Node node, String message) {
+        String loc = GraphUtil.approxSourceLocation(node);
+        throw new GraalInternalError(String.format("The " + option.getName() + " option is declared in " + option.getDeclaringClass() +
+                        " whose class hierarchy contains a class initializer (in %s) with a code pattern at or near %s implying an action other than initialization of an option:%n%n    %s%n%n" +
+                        "The recommended solution is to move " + option.getName() + " into a separate class (e.g., " + option.getDeclaringClass().getName() + ".Options).%n",
+                        toJavaName(declaringClass), loc, message));
+    }
+}
--- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/JTTTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -50,7 +50,7 @@
     Object[] argsToBind;
 
     public JTTTest() {
-        Assert.assertNotNull(runtime);
+        Assert.assertNotNull(getCodeCache());
     }
 
     @Override
@@ -59,12 +59,12 @@
         if (argsToBind != null) {
             Object receiver = isStatic(m.getModifiers()) ? null : this;
             Object[] args = argsWithReceiver(receiver, argsToBind);
-            JavaType[] parameterTypes = signatureToTypes(runtime.lookupJavaMethod(m));
+            JavaType[] parameterTypes = signatureToTypes(getMetaAccess().lookupJavaMethod(m));
             assert parameterTypes.length == args.length;
             for (int i = 0; i < args.length; i++) {
                 LocalNode local = graph.getLocal(i);
                 Constant c = Constant.forBoxed(parameterTypes[i].getKind(), args[i]);
-                ConstantNode replacement = ConstantNode.forConstant(c, runtime, graph);
+                ConstantNode replacement = ConstantNode.forConstant(c, getMetaAccess(), graph);
                 local.replaceAtUsages(replacement);
             }
         }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Fri Oct 11 17:21:14 2013 +0200
@@ -28,6 +28,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.spi.*;
@@ -182,6 +183,14 @@
         masm.ensureUniquePC();
     }
 
+    public static void directConditionalJmp(TargetMethodAssembler tasm, AMD64MacroAssembler masm, InvokeTarget target, ConditionFlag cond) {
+        int before = masm.codeBuffer.position();
+        masm.jcc(cond, 0, true);
+        int after = masm.codeBuffer.position();
+        tasm.recordDirectCall(before, after, target, null);
+        masm.ensureUniquePC();
+    }
+
     public static void indirectCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Register dst, InvokeTarget callTarget, LIRFrameState info) {
         int before = masm.codeBuffer.position();
         masm.call(dst);
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Fri Oct 11 17:21:14 2013 +0200
@@ -153,7 +153,7 @@
             if (key.getKind() == Kind.Int) {
                 Register intKey = asIntReg(key);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    if (tasm.runtime.needsDataPatch(keyConstants[i])) {
+                    if (tasm.codeCache.needsDataPatch(keyConstants[i])) {
                         tasm.recordDataReferenceInCode(keyConstants[i], 0, true);
                     }
                     long lc = keyConstants[i].asLong();
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64FrameMap.java	Fri Oct 11 17:21:14 2013 +0200
@@ -28,12 +28,12 @@
 
 /**
  * AMD64 specific frame map.
- *
+ * 
  * This is the format of an AMD64 stack frame:
- *
+ * 
  * <pre>
  *   Base       Contents
- *
+ * 
  *            :                                :  -----
  *   caller   | incoming overflow argument n   |    ^
  *   frame    :     ...                        :    | positive
@@ -55,9 +55,9 @@
  *            :     ...                        :    | positive   |      |
  *            | outgoing overflow argument 0   |    | offsets    v      v
  *    %sp-->  +--------------------------------+---------------------------
- *
+ * 
  * </pre>
- *
+ * 
  * The spill slot area also includes stack allocated memory blocks (ALLOCA blocks). The size of such
  * a block may be greater than the size of a normal spill slot or the word size.
  * <p>
@@ -69,8 +69,8 @@
  */
 public class AMD64FrameMap extends FrameMap {
 
-    public AMD64FrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) {
-        super(runtime, target, registerConfig);
+    public AMD64FrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
+        super(codeCache, target, registerConfig);
         // (negative) offset relative to sp + total frame size
         initialSpillSize = returnAddressSize() + calleeSaveAreaSize();
         spillSize = initialSpillSize;
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Fri Oct 11 17:21:14 2013 +0200
@@ -441,7 +441,7 @@
          */
         switch (input.getKind().getStackKind()) {
             case Int:
-                if (tasm.runtime.needsDataPatch(input)) {
+                if (tasm.codeCache.needsDataPatch(input)) {
                     tasm.recordDataReferenceInCode(input, 0, true);
                 }
                 // Do not optimize with an XOR as this instruction may be between
@@ -451,7 +451,7 @@
 
                 break;
             case Long:
-                if (tasm.runtime.needsDataPatch(input)) {
+                if (tasm.codeCache.needsDataPatch(input)) {
                     tasm.recordDataReferenceInCode(input, 0, true);
                 }
                 // Do not optimize with an XOR as this instruction may be between
@@ -462,7 +462,7 @@
             case Float:
                 // This is *not* the same as 'constant == 0.0f' in the case where constant is -0.0f
                 if (Float.floatToRawIntBits(input.asFloat()) == Float.floatToRawIntBits(0.0f)) {
-                    assert !tasm.runtime.needsDataPatch(input);
+                    assert !tasm.codeCache.needsDataPatch(input);
                     masm.xorps(asFloatReg(result), asFloatReg(result));
                 } else {
                     masm.movflt(asFloatReg(result), (AMD64Address) tasm.asFloatConstRef(input));
@@ -471,7 +471,7 @@
             case Double:
                 // This is *not* the same as 'constant == 0.0d' in the case where constant is -0.0d
                 if (Double.doubleToRawLongBits(input.asDouble()) == Double.doubleToRawLongBits(0.0d)) {
-                    assert !tasm.runtime.needsDataPatch(input);
+                    assert !tasm.codeCache.needsDataPatch(input);
                     masm.xorpd(asDoubleReg(result), asDoubleReg(result));
                 } else {
                     masm.movdbl(asDoubleReg(result), (AMD64Address) tasm.asDoubleConstRef(input));
@@ -496,7 +496,7 @@
     }
 
     private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Constant input) {
-        assert !tasm.runtime.needsDataPatch(input);
+        assert !tasm.codeCache.needsDataPatch(input);
         AMD64Address dest = (AMD64Address) tasm.asAddress(result);
         switch (input.getKind().getStackKind()) {
             case Int:
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILFrameMap.java	Fri Oct 11 17:21:14 2013 +0200
@@ -37,8 +37,8 @@
  */
 public final class HSAILFrameMap extends FrameMap {
 
-    public HSAILFrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) {
-        super(runtime, target, registerConfig);
+    public HSAILFrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
+        super(codeCache, target, registerConfig);
     }
 
     @Override
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXArithmetic.java	Fri Oct 11 17:21:14 2013 +0200
@@ -75,7 +75,7 @@
                 case D2I:
                 case D2L:
                 case D2F:
-                    break;  // cvt handles the move 
+                    break;  // cvt handles the move
                 default:
                     PTXMove.move(tasm, masm, result, x);
             }
@@ -422,11 +422,73 @@
     }
 
     private static void verifyKind(PTXArithmetic opcode, Value result, Value x, Value y) {
-        if (((opcode.name().startsWith("I") && result.getKind() == Kind.Int && x.getKind().getStackKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int)
-            || (opcode.name().startsWith("L") && result.getKind() == Kind.Long && x.getKind() == Kind.Long && y.getKind() == Kind.Long)
-            || (opcode.name().startsWith("F") && result.getKind() == Kind.Float && x.getKind() == Kind.Float && y.getKind() == Kind.Float)
-            || (opcode.name().startsWith("D") && result.getKind() == Kind.Double && x.getKind() == Kind.Double && y.getKind() == Kind.Double)) == false) {
-                throw GraalInternalError.shouldNotReachHere("opcode: "  + opcode.name() + " x: " + x.getKind() + " y: " + y.getKind());
+        Kind rk;
+        Kind xk;
+        Kind yk;
+        Kind xsk;
+        Kind ysk;
+
+        switch (opcode) {
+            case IADD:
+            case ISUB:
+            case IMUL:
+            case IDIV:
+            case IREM:
+            case IAND:
+            case IOR:
+            case IXOR:
+            case ISHL:
+            case ISHR:
+            case IUSHR:
+                rk = result.getKind();
+                xsk = x.getKind().getStackKind();
+                ysk = y.getKind().getStackKind();
+                assert rk == Kind.Int && xsk == Kind.Int && ysk == Kind.Int;
+                break;
+            case LADD:
+            case LSUB:
+            case LMUL:
+            case LDIV:
+            case LREM:
+            case LAND:
+            case LOR:
+            case LXOR:
+                rk = result.getKind();
+                xk = x.getKind();
+                yk = y.getKind();
+                assert rk == Kind.Long && xk == Kind.Long && yk == Kind.Long;
+                break;
+            case LSHL:
+            case LSHR:
+            case LUSHR:
+                rk = result.getKind();
+                xk = x.getKind();
+                yk = y.getKind();
+                assert rk == Kind.Long && xk == Kind.Long && (yk == Kind.Int || yk == Kind.Long);
+                break;
+            case FADD:
+            case FSUB:
+            case FMUL:
+            case FDIV:
+            case FREM:
+                rk = result.getKind();
+                xk = x.getKind();
+                yk = y.getKind();
+                assert rk == Kind.Float && xk == Kind.Float && yk == Kind.Float;
+                break;
+            case DADD:
+            case DSUB:
+            case DMUL:
+            case DDIV:
+            case DREM:
+                rk = result.getKind();
+                xk = x.getKind();
+                yk = y.getKind();
+                assert rk == Kind.Double && xk == Kind.Double && yk == Kind.Double :
+                    "opcode=" + opcode + ", result kind=" + rk + ", x kind=" + xk + ", y kind=" + yk;
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("missing: " + opcode);
         }
     }
 }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXControlFlow.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.asm.ptx.PTXAssembler.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+import static com.oracle.graal.lir.LIRValueUtil.*;
 import static com.oracle.graal.nodes.calc.Condition.*;
 
 import com.oracle.graal.api.code.CompilationResult.JumpTable;
@@ -57,7 +58,8 @@
 
     public static class ReturnNoValOp extends PTXLIRInstruction {
 
-        public ReturnNoValOp() { }
+        public ReturnNoValOp() {
+        }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
@@ -97,30 +99,28 @@
         }
     }
 
-    @SuppressWarnings("unused")
     public static class CondMoveOp extends PTXLIRInstruction {
 
         @Def({REG, HINT}) protected Value result;
         @Alive({REG}) protected Value trueValue;
         @Use({REG, STACK, CONST}) protected Value falseValue;
         private final Condition condition;
+        private final int predicate;
 
-        public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue) {
+        public CondMoveOp(Variable result, Condition condition, Variable trueValue, Value falseValue, int predicateRegister) {
             this.result = result;
             this.condition = condition;
             this.trueValue = trueValue;
             this.falseValue = falseValue;
+            this.predicate = predicateRegister;
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
-            // cmove(tasm, masm, result, false, condition, false, trueValue, falseValue);
-            // see 8.3 Predicated Execution p. 61 of PTX ISA 3.1
-            throw new InternalError("NYI");
+            cmove(tasm, masm, result, false, condition, false, trueValue, falseValue, predicate);
         }
     }
 
-    @SuppressWarnings("unused")
     public static class FloatCondMoveOp extends PTXLIRInstruction {
 
         @Def({REG}) protected Value result;
@@ -128,20 +128,71 @@
         @Alive({REG}) protected Value falseValue;
         private final Condition condition;
         private final boolean unorderedIsTrue;
+        private final int predicate;
 
-        public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue) {
+        public FloatCondMoveOp(Variable result, Condition condition, boolean unorderedIsTrue, Variable trueValue, Variable falseValue, int predicateRegister) {
             this.result = result;
             this.condition = condition;
             this.unorderedIsTrue = unorderedIsTrue;
             this.trueValue = trueValue;
             this.falseValue = falseValue;
+            this.predicate = predicateRegister;
         }
 
         @Override
         public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
-            // cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue);
-            // see 8.3 Predicated Execution p. 61 of PTX ISA 3.1
-            throw new InternalError("NYI");
+            cmove(tasm, masm, result, true, condition, unorderedIsTrue, trueValue, falseValue, predicate);
+        }
+    }
+
+    private static void cmove(TargetMethodAssembler tasm, PTXAssembler asm, Value result, boolean isFloat, Condition condition, boolean unorderedIsTrue, Value trueValue, Value falseValue,
+                    int predicateRegister) {
+        // check that we don't overwrite an input operand before it is used.
+        assert !result.equals(trueValue);
+
+        PTXMove.move(tasm, asm, result, falseValue);
+        cmove(asm, result, trueValue, predicateRegister);
+
+        if (isFloat) {
+            if (unorderedIsTrue && !trueOnUnordered(condition)) {
+                // cmove(tasm, masm, result, ConditionFlag.Parity, trueValue);
+                throw GraalInternalError.unimplemented();
+            } else if (!unorderedIsTrue && trueOnUnordered(condition)) {
+                // cmove(tasm, masm, result, ConditionFlag.Parity, falseValue);
+                throw GraalInternalError.unimplemented();
+            }
+        }
+    }
+
+    private static boolean trueOnUnordered(Condition condition) {
+        switch (condition) {
+            case NE:
+            case EQ:
+                return false;
+            case LT:
+            case GE:
+                return true;
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
+    private static void cmove(PTXAssembler asm, Value result, Value other, int predicateRegister) {
+        if (isVariable(other)) {
+            assert !asVariable(other).equals(asVariable(result)) : "other already overwritten by previous move";
+
+            switch (other.getKind()) {
+                case Int:
+                    new Mov(asVariable(result), other, predicateRegister).emit(asm);
+                    break;
+                case Long:
+                    new Mov(asVariable(result), other, predicateRegister).emit(asm);
+                    break;
+                default:
+                    throw new InternalError("unhandled: " + other.getKind());
+            }
+        } else {
+            throw GraalInternalError.shouldNotReachHere("cmove: not register");
         }
     }
 
@@ -171,7 +222,7 @@
 
             if (keyKind == Kind.Int || keyKind == Kind.Long) {
                 for (int i = 0; i < keyConstants.length; i++) {
-                    if (tasm.runtime.needsDataPatch(keyConstants[i])) {
+                    if (tasm.codeCache.needsDataPatch(keyConstants[i])) {
                         tasm.recordDataReferenceInCode(keyConstants[i], 0, true);
                     }
                     new Setp(EQ, keyConstants[i], key, predRegNum).emit(masm);
@@ -232,7 +283,9 @@
     @SuppressWarnings("unused")
     private static void tableswitch(TargetMethodAssembler tasm, PTXAssembler masm, int lowKey, LabelRef defaultTarget, LabelRef[] targets, Value value, Value scratch, int predNum) {
         Buffer buf = masm.codeBuffer;
+
         // Compare index against jump table bounds
+
         int highKey = lowKey + targets.length - 1;
         if (lowKey != 0) {
             // subtract the low value from the switch value
@@ -244,15 +297,20 @@
 
         // Jump to default target if index is not within the jump table
         if (defaultTarget != null) {
-            masm.bra(defaultTarget.label().toString(), predNum);
+            masm.bra(masm.nameOf(defaultTarget.label()), predNum);
         }
 
         // address of jump table
         int tablePos = buf.position();
 
         JumpTable jt = new JumpTable(tablePos, lowKey, highKey, 4);
+        String name = "jumptable" + jt.position;
+
+        new Global(value, name, targets).emit(masm);
+
+        // bra(Value, name);
+
         tasm.compilationResult.addAnnotation(jt);
 
-        // PTX: unimp: tableswitch extract
     }
 }
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXFrameMap.java	Fri Oct 11 17:21:14 2013 +0200
@@ -37,8 +37,8 @@
  */
 public final class PTXFrameMap extends FrameMap {
 
-    public PTXFrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) {
-        super(runtime, target, registerConfig);
+    public PTXFrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
+        super(codeCache, target, registerConfig);
     }
 
     @Override
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMemOp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -43,7 +43,8 @@
         @Use({COMPOSITE}) protected PTXAddressValue address;
         @State protected LIRFrameState state;
 
-        public LoadOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) {
+        public LoadOp(Kind kind, Variable result, PTXAddressValue address,
+                      LIRFrameState state) {
             this.kind = kind;
             this.result = result;
             this.address = address;
@@ -62,7 +63,8 @@
                 case Float:
                 case Double:
                 case Object:
-                    new Ld(Global, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm);
+                    new Ld(Global, result, addr.getBase(),
+                           Constant.forLong(addr.getDisplacement())).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -97,7 +99,8 @@
                 case Float:
                 case Double:
                 case Object:
-                    new St(Global, input, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm);
+                    new St(Global, input, addr.getBase(),
+                           Constant.forLong(addr.getDisplacement())).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind());
@@ -114,7 +117,8 @@
         @Use({COMPOSITE}) protected PTXAddressValue address;
         @State protected LIRFrameState state;
 
-        public LoadParamOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) {
+        public LoadParamOp(Kind kind, Variable result, PTXAddressValue address,
+                           LIRFrameState state) {
             this.kind = kind;
             this.result = result;
             this.address = address;
@@ -133,7 +137,8 @@
                 case Float:
                 case Double:
                 case Object:
-                    new Ld(Parameter, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm);
+                    new Ld(Parameter, result, addr.getBase(),
+                           Constant.forLong(addr.getDisplacement())).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -151,7 +156,8 @@
         @Use({COMPOSITE}) protected PTXAddressValue address;
         @State protected LIRFrameState state;
 
-        public LoadReturnAddrOp(Kind kind, Variable result, PTXAddressValue address, LIRFrameState state) {
+        public LoadReturnAddrOp(Kind kind, Variable result,
+                                PTXAddressValue address, LIRFrameState state) {
             this.kind = kind;
             this.result = result;
             this.address = address;
@@ -166,7 +172,8 @@
                 case Long:
                 case Float:
                 case Double:
-                    new Ld(Parameter, result, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm);
+                    new Ld(Parameter, result, addr.getBase(),
+                           Constant.forLong(addr.getDisplacement())).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
@@ -183,7 +190,8 @@
         @Use({REG}) protected Variable input;
         @State protected LIRFrameState state;
 
-        public StoreReturnValOp(Kind kind, PTXAddressValue address, Variable input, LIRFrameState state) {
+        public StoreReturnValOp(Kind kind, PTXAddressValue address,
+                                Variable input, LIRFrameState state) {
             this.kind = kind;
             this.address = address;
             this.input = input;
@@ -202,7 +210,8 @@
                 case Float:
                 case Double:
                 case Object:
-                    new St(Global, input, addr.getBase(), Constant.forLong(addr.getDisplacement())).emit(masm);
+                    new St(Global, input, addr.getBase(),
+                           Constant.forLong(addr.getDisplacement())).emit(masm);
                     break;
                 default:
                     throw GraalInternalError.shouldNotReachHere("missing: " + address.getKind());
--- a/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXMove.java	Fri Oct 11 17:21:14 2013 +0200
@@ -215,7 +215,7 @@
         switch (input.getKind().getStackKind()) {
             case Int:
             case Long:
-                if (tasm.runtime.needsDataPatch(input)) {
+                if (tasm.codeCache.needsDataPatch(input)) {
                     tasm.recordDataReferenceInCode(input, 0, true);
                 }
                 new Mov(dest, input).emit(masm);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/PTXTestOp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,64 @@
+/*
+ * 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.lir.ptx;
+
+import static com.oracle.graal.asm.ptx.PTXAssembler.BooleanOperator.*;
+import static com.oracle.graal.asm.ptx.PTXAssembler.*;
+import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.ptx.*;
+import com.oracle.graal.lir.asm.*;
+import com.oracle.graal.nodes.calc.Condition;
+
+public class PTXTestOp extends PTXLIRInstruction {
+
+    @Use({REG}) protected Value x;
+    @Use({REG, STACK, CONST}) protected Value y;
+    int predicate;
+
+    public PTXTestOp(Value x, Value y, int predicate) {
+        this.x = x;
+        this.y = y;
+        this.predicate = predicate;
+    }
+
+    @Override
+    public void emitCode(TargetMethodAssembler tasm, PTXAssembler masm) {
+        emit(masm, x, y, predicate);
+    }
+
+    @Override
+    protected void verify() {
+        super.verify();
+        assert (x.getKind() == Kind.Int && y.getKind().getStackKind() == Kind.Int) || (x.getKind() == Kind.Long && y.getKind() == Kind.Long) : x + " " + y;
+    }
+
+    public static void emit(PTXAssembler masm, Value x, Value y, int predicate) {
+        /*
+         * This is not yet quite right - as the result for the equivalent in
+         * ControlPTXText.testIntegerTestBranch2I is wrong.
+         */
+        new Setp(Condition.EQ, AND, x, y, predicate).emit(masm);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ParallelOver.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,36 @@
+/*
+ * 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.lir.ptx;
+
+import static com.oracle.graal.lir.ptx.ThreadDimension.*;
+
+import java.lang.annotation.*;
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface ParallelOver {
+
+    String value() default "";
+
+    ThreadDimension dimension() default X;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/ThreadDimension.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,30 @@
+/*
+ * 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.lir.ptx;
+
+public enum ThreadDimension {
+X,
+Y,
+Z
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.lir.ptx/src/com/oracle/graal/lir/ptx/Warp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * 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.lir.ptx;
+
+import static com.oracle.graal.lir.ptx.ThreadDimension.*;
+
+import java.lang.annotation.*;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.PARAMETER})
+public @interface Warp {
+
+    String value() default "";
+
+    ThreadDimension dimension() default X;
+}
+
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCControlFlow.java	Fri Oct 11 17:21:14 2013 +0200
@@ -279,7 +279,7 @@
             if (key.getKind() == Kind.Int) {
                 Register intKey = asIntReg(key);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    if (tasm.runtime.needsDataPatch(keyConstants[i])) {
+                    if (tasm.codeCache.needsDataPatch(keyConstants[i])) {
                         tasm.recordDataReferenceInCode(keyConstants[i], 0, true);
                     }
                     long lc = keyConstants[i].asLong();
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCFrameMap.java	Fri Oct 11 17:21:14 2013 +0200
@@ -69,8 +69,8 @@
  */
 public final class SPARCFrameMap extends FrameMap {
 
-    public SPARCFrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) {
-        super(runtime, target, registerConfig);
+    public SPARCFrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
+        super(codeCache, target, registerConfig);
         // offset relative to sp + total frame size
         initialSpillSize = 0;
         spillSize = initialSpillSize;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Fri Oct 11 17:21:14 2013 +0200
@@ -413,7 +413,7 @@
     private static void const2reg(TargetMethodAssembler tasm, SPARCMacroAssembler masm, Value result, Constant input) {
         switch (input.getKind().getStackKind()) {
             case Int:
-                if (tasm.runtime.needsDataPatch(input)) {
+                if (tasm.codeCache.needsDataPatch(input)) {
                     tasm.recordDataReferenceInCode(input, 0, true);
                     new Setuw(input.asInt(), asRegister(result)).emit(masm);
                 } else {
@@ -425,7 +425,7 @@
                 }
                 break;
             case Long: {
-                if (tasm.runtime.needsDataPatch(input)) {
+                if (tasm.codeCache.needsDataPatch(input)) {
                     tasm.recordDataReferenceInCode(input, 0, true);
                     new Setx(input.asLong(), asRegister(result), true).emit(masm);
                 } else {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Fri Oct 11 17:21:14 2013 +0200
@@ -40,7 +40,6 @@
  */
 public abstract class FrameMap {
 
-    public final CodeCacheProvider runtime;
     public final TargetDescription target;
     public final RegisterConfig registerConfig;
 
@@ -87,12 +86,11 @@
     /**
      * Creates a new frame map for the specified method.
      */
-    public FrameMap(CodeCacheProvider runtime, TargetDescription target, RegisterConfig registerConfig) {
-        this.runtime = runtime;
+    public FrameMap(CodeCacheProvider codeCache, TargetDescription target, RegisterConfig registerConfig) {
         this.target = target;
         this.registerConfig = registerConfig;
         this.frameSize = -1;
-        this.outgoingSize = runtime.getMinimumOutgoingSize();
+        this.outgoingSize = codeCache.getMinimumOutgoingSize();
         this.objectStackBlocks = new ArrayList<>();
     }
 
@@ -116,7 +114,7 @@
     /**
      * Gets the frame size of the compiled frame, not including the size of the
      * {@link Architecture#getReturnAddressSize() return address slot}.
-     *
+     * 
      * @return The size of the frame (in bytes).
      */
     public int frameSize() {
@@ -136,7 +134,7 @@
     /**
      * Gets the total frame size of the compiled frame, including the size of the
      * {@link Architecture#getReturnAddressSize() return address slot}.
-     *
+     * 
      * @return The total size of the frame (in bytes).
      */
     public abstract int totalFrameSize();
@@ -149,7 +147,7 @@
 
     /**
      * Aligns the given frame size to the stack alignment size and return the aligned size.
-     *
+     * 
      * @param size the initial frame size to be aligned
      * @return the aligned frame size
      */
@@ -181,7 +179,7 @@
 
     /**
      * Computes the offset of a stack slot relative to the frame register.
-     *
+     * 
      * @param slot a stack slot
      * @return the offset of the stack slot
      */
@@ -197,7 +195,7 @@
     /**
      * Computes the index of a stack slot relative to slot 0. This is also the bit index of stack
      * slots in the reference map.
-     *
+     * 
      * @param slot a stack slot
      * @return the index of the stack slot
      */
@@ -209,7 +207,7 @@
     /**
      * Gets the offset from the stack pointer to the stack area where callee-saved registers are
      * stored.
-     *
+     * 
      * @return The offset to the callee save area (in bytes).
      */
     public abstract int offsetToCalleeSaveArea();
@@ -217,7 +215,7 @@
     /**
      * Informs the frame map that the compiled code calls a particular method, which may need stack
      * space for outgoing arguments.
-     *
+     * 
      * @param cc The calling convention for the called method.
      */
     public void callsMethod(CallingConvention cc) {
@@ -226,7 +224,7 @@
 
     /**
      * Reserves space for stack-based outgoing arguments.
-     *
+     * 
      * @param argsSize The amount of space (in bytes) to reserve for stack-based outgoing arguments.
      */
     public void reserveOutgoing(int argsSize) {
@@ -239,7 +237,7 @@
      * Reserves a new spill slot in the frame of the method being compiled. The returned slot is
      * aligned on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte
      * boundary.
-     *
+     * 
      * @param kind The kind of the spill slot to be reserved.
      * @param additionalOffset
      * @return A spill slot denoting the reserved memory area.
@@ -247,8 +245,9 @@
     protected abstract StackSlot allocateNewSpillSlot(PlatformKind kind, int additionalOffset);
 
     /**
-     * Returns the spill slot size for the given {@link PlatformKind}.
-     * The default value is the size in bytes for the target architecture.
+     * Returns the spill slot size for the given {@link PlatformKind}. The default value is the size
+     * in bytes for the target architecture.
+     * 
      * @param kind the {@link PlatformKind} to be stored in the spill slot.
      * @return the size in bytes
      */
@@ -258,9 +257,9 @@
 
     /**
      * Reserves a spill slot in the frame of the method being compiled. The returned slot is aligned
-     * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary,
-     * unless overridden by a subclass.
-     *
+     * on its natural alignment, i.e., an 8-byte spill slot is aligned at an 8-byte boundary, unless
+     * overridden by a subclass.
+     * 
      * @param kind The kind of the spill slot to be reserved.
      * @return A spill slot denoting the reserved memory area.
      */
@@ -299,7 +298,7 @@
     /**
      * Reserves a block of memory in the frame of the method being compiled. The returned block is
      * aligned on a word boundary. If the requested size is 0, the method returns {@code null}.
-     *
+     * 
      * @param size The size to reserve (in bytes).
      * @param refs Specifies if the block is all references. If true, the block will be in all
      *            reference maps for this method. The caller is responsible to initialize the memory
@@ -351,7 +350,7 @@
      * Marks the specified location as a reference in the reference map of the debug information.
      * The tracked location can be a {@link RegisterValue} or a {@link StackSlot}. Note that a
      * {@link Constant} is automatically tracked.
-     *
+     * 
      * @param location The location to be added to the reference map.
      * @param registerRefMap A register reference map, as created by {@link #initRegisterRefMap()}.
      * @param frameRefMap A frame reference map, as created by {@link #initFrameRefMap()}.
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIR.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
@@ -71,22 +70,15 @@
 
     private boolean hasArgInCallerFrame;
 
-    private final SpeculationLog speculationLog;
-
     /**
      * Creates a new LIR instance for the specified compilation.
      */
-    public LIR(ControlFlowGraph cfg, BlockMap<List<ScheduledNode>> blockToNodesMap, List<Block> linearScanOrder, List<Block> codeEmittingOrder, SpeculationLog speculationLog) {
+    public LIR(ControlFlowGraph cfg, BlockMap<List<ScheduledNode>> blockToNodesMap, List<Block> linearScanOrder, List<Block> codeEmittingOrder) {
         this.cfg = cfg;
         this.blockToNodesMap = blockToNodesMap;
         this.codeEmittingOrder = codeEmittingOrder;
         this.linearScanOrder = linearScanOrder;
         this.lirInstructions = new BlockMap<>(cfg);
-        this.speculationLog = speculationLog;
-    }
-
-    public SpeculationLog getDeoptimizationReasons() {
-        return speculationLog;
     }
 
     /**
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -42,13 +42,11 @@
     private final VirtualObject[] virtualObjects;
     public final LabelRef exceptionEdge;
     private DebugInfo debugInfo;
-    private final short deoptimizationReason;
 
-    public LIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge, short deoptimizationReason) {
+    public LIRFrameState(BytecodeFrame topFrame, VirtualObject[] virtualObjects, LabelRef exceptionEdge) {
         this.topFrame = topFrame;
         this.virtualObjects = virtualObjects;
         this.exceptionEdge = exceptionEdge;
-        this.deoptimizationReason = deoptimizationReason;
     }
 
     public boolean hasDebugInfo() {
@@ -112,7 +110,7 @@
     }
 
     public void finish(BitSet registerRefMap, BitSet frameRefMap) {
-        debugInfo = new DebugInfo(topFrame, registerRefMap, frameRefMap, deoptimizationReason);
+        debugInfo = new DebugInfo(topFrame, registerRefMap, frameRefMap);
     }
 
     @Override
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/Variable.java	Fri Oct 11 17:21:14 2013 +0200
@@ -38,6 +38,8 @@
      */
     public final int index;
 
+    private String name;
+
     /**
      * Creates a new variable.
      * 
@@ -50,9 +52,21 @@
         this.index = index;
     }
 
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
     @Override
     public String toString() {
-        return "v" + index + getKindSuffix();
+        if (name != null) {
+            return name;
+        } else {
+            return "v" + index + getKindSuffix();
+        }
     }
 
     @Override
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Fri Oct 11 17:21:14 2013 +0200
@@ -51,7 +51,7 @@
     public final AbstractAssembler asm;
     public final CompilationResult compilationResult;
     public final TargetDescription target;
-    public final CodeCacheProvider runtime;
+    public final CodeCacheProvider codeCache;
     public final FrameMap frameMap;
 
     /**
@@ -62,9 +62,9 @@
 
     private List<ExceptionInfo> exceptionInfoList;
 
-    public TargetMethodAssembler(TargetDescription target, CodeCacheProvider runtime, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) {
+    public TargetMethodAssembler(TargetDescription target, CodeCacheProvider codeCache, FrameMap frameMap, AbstractAssembler asm, FrameContext frameContext, CompilationResult compilationResult) {
         this.target = target;
-        this.runtime = runtime;
+        this.codeCache = codeCache;
         this.frameMap = frameMap;
         this.asm = asm;
         this.compilationResult = compilationResult;
@@ -185,7 +185,7 @@
     public int asIntConst(Value value) {
         assert (value.getKind().getStackKind() == Kind.Int || value.getKind() == Kind.Long) && isConstant(value);
         Constant constant = (Constant) value;
-        assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
         long c = constant.asLong();
         if (!NumUtil.isInt(c)) {
             throw GraalInternalError.shouldNotReachHere();
@@ -199,7 +199,7 @@
     public float asFloatConst(Value value) {
         assert (value.getKind().getStackKind() == Kind.Float && isConstant(value));
         Constant constant = (Constant) value;
-        assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
         return constant.asFloat();
     }
 
@@ -209,7 +209,7 @@
     public long asLongConst(Value value) {
         assert (value.getKind().getStackKind() == Kind.Long && isConstant(value));
         Constant constant = (Constant) value;
-        assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
         return constant.asLong();
     }
 
@@ -219,7 +219,7 @@
     public double asDoubleConst(Value value) {
         assert (value.getKind().getStackKind() == Kind.Double && isConstant(value));
         Constant constant = (Constant) value;
-        assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        assert !codeCache.needsDataPatch(constant) : constant + " should be in a DataPatch";
         return constant.asDouble();
     }
 
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/CountedLoopInfo.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,7 +24,6 @@
 
 import static com.oracle.graal.nodes.calc.IntegerArithmeticNode.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.loop.InductionVariable.Direction;
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Fri Oct 11 17:21:14 2013 +0200
@@ -48,11 +48,11 @@
             return false;
         }
         CountedLoopInfo counted = loop.counted();
-        long exactTrips = counted.constantMaxTripCount();
+        long maxTrips = counted.constantMaxTripCount();
         int maxNodes = (counted.isExactTripCount() && counted.isConstantExactTripCount()) ? ExactFullUnrollMaxNodes.getValue() : FullUnrollMaxNodes.getValue();
         maxNodes = Math.min(maxNodes, MaximumDesiredSize.getValue() - loop.loopBegin().graph().getNodeCount());
         int size = Math.max(1, loop.size() - 1 - loop.loopBegin().phis().count());
-        return size * exactTrips <= maxNodes;
+        return size * maxTrips <= maxNodes;
     }
 
     public static boolean shouldTryUnswitch(LoopEx loop) {
--- a/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes.test/src/com/oracle/graal/nodes/test/ObjectStampJoinTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -151,6 +151,6 @@
     }
 
     private ResolvedJavaType getType(Class<?> clazz) {
-        return runtime().lookupJavaType(clazz);
+        return getMetaAccess().lookupJavaType(clazz);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractBeginNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/AbstractDeoptimizeNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013, 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.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.type.*;
+
+/**
+ * This node represents an unconditional explicit request for immediate deoptimization.
+ * 
+ * After this node, execution will continue using a fallback execution engine (such as an
+ * interpreter) at the position described by the {@link #getDeoptimizationState() deoptimization
+ * state}.
+ * 
+ */
+public abstract class AbstractDeoptimizeNode extends ControlSinkNode implements IterableNodeType, DeoptimizingNode {
+
+    @Input private FrameState deoptState;
+
+    public AbstractDeoptimizeNode() {
+        super(StampFactory.forVoid());
+    }
+
+    @Override
+    public boolean canDeoptimize() {
+        return true;
+    }
+
+    @Override
+    public FrameState getDeoptimizationState() {
+        return deoptState;
+    }
+
+    @Override
+    public void setDeoptimizationState(FrameState f) {
+        updateUsages(deoptState, f);
+        deoptState = f;
+    }
+
+    public FrameState getState() {
+        return deoptState;
+    }
+
+    public abstract ValueNode getActionAndReason(MetaAccessProvider metaAccess);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConditionAnchorNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+@NodeInfo(nameTemplate = "ConditionAnchor(!={p#negated})")
+public final class ConditionAnchorNode extends FixedWithNextNode implements Canonicalizable, Lowerable, GuardingNode {
+
+    @Input private LogicNode condition;
+    private boolean negated;
+
+    public ConditionAnchorNode(LogicNode condition) {
+        this(condition, false);
+    }
+
+    public ConditionAnchorNode(LogicNode condition, boolean negated) {
+        super(StampFactory.dependency());
+        this.negated = negated;
+        this.condition = condition;
+    }
+
+    public LogicNode condition() {
+        return condition;
+    }
+
+    private void setCondition(LogicNode x) {
+        updateUsages(condition, x);
+        condition = x;
+    }
+
+    public boolean isNegated() {
+        return negated;
+    }
+
+    @Override
+    public String toString(Verbosity verbosity) {
+        if (verbosity == Verbosity.Name && negated) {
+            return "!" + super.toString(verbosity);
+        } else {
+            return super.toString(verbosity);
+        }
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (condition instanceof LogicNegationNode) {
+            LogicNegationNode negation = (LogicNegationNode) condition;
+            setCondition(negation.getInput());
+            negated = !negated;
+        }
+
+        if (condition instanceof LogicConstantNode) {
+            LogicConstantNode c = (LogicConstantNode) condition;
+            if (c.getValue() != negated) {
+                this.replaceAtUsages(null);
+                return null;
+            } else {
+                return graph().add(new ValueAnchorNode(null));
+            }
+        }
+
+        return this;
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
+            ValueAnchorNode newAnchor = graph().add(new ValueAnchorNode(null));
+            graph().replaceFixedWithFixed(this, newAnchor);
+        }
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ConstantNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,7 +26,6 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -50,27 +49,34 @@
      * 
      * @param value the constant
      */
-    protected ConstantNode(Constant value, MetaAccessProvider runtime) {
-        super(StampFactory.forConstant(value, runtime));
+    protected ConstantNode(Constant value, MetaAccessProvider metaAccess) {
+        super(StampFactory.forConstant(value, metaAccess));
         this.value = value;
     }
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        if (gen.canInlineConstant(value) || onlyUsedInFrameState()) {
+        if (gen.canInlineConstant(value) || onlyUsedInVirtualState()) {
             gen.setResult(this, value);
         } else {
             gen.setResult(this, gen.emitMove(value));
         }
     }
 
-    private boolean onlyUsedInFrameState() {
-        return usages().filter(NodePredicates.isNotA(FrameState.class)).isEmpty();
+    private boolean onlyUsedInVirtualState() {
+        for (Node n : this.usages()) {
+            if (n instanceof VirtualState) {
+                // Only virtual usage.
+            } else {
+                return false;
+            }
+        }
+        return true;
     }
 
-    public static ConstantNode forConstant(Constant constant, MetaAccessProvider runtime, Graph graph) {
+    public static ConstantNode forConstant(Constant constant, MetaAccessProvider metaAccess, Graph graph) {
         if (constant.getKind() == Kind.Object) {
-            return graph.unique(new ConstantNode(constant, runtime));
+            return graph.unique(new ConstantNode(constant, metaAccess));
         } else {
             return graph.unique(new ConstantNode(constant));
         }
@@ -179,9 +185,9 @@
      * @param graph
      * @return a node representing the object
      */
-    public static ConstantNode forObject(Object o, MetaAccessProvider runtime, Graph graph) {
+    public static ConstantNode forObject(Object o, MetaAccessProvider metaAccess, Graph graph) {
         assert !(o instanceof Constant) : "wrapping a Constant into a Constant";
-        return graph.unique(new ConstantNode(Constant.forObject(o), runtime));
+        return graph.unique(new ConstantNode(Constant.forObject(o), metaAccess));
     }
 
     public static ConstantNode forIntegerKind(Kind kind, long value, Graph graph) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,30 +22,17 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
 
-/**
- * This node represents an unconditional explicit request for immediate deoptimization.
- * 
- * After this node, execution will continue using a fallback execution engine (such as an
- * interpreter) at the position described by the {@link #getDeoptimizationState() deoptimization
- * state}.
- * 
- */
 @NodeInfo(shortName = "Deopt", nameTemplate = "Deopt {p#reason/s}")
-public class DeoptimizeNode extends ControlSinkNode implements IterableNodeType, LIRLowerable, DeoptimizingNode {
-
-    @Input private FrameState deoptState;
+public class DeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable {
 
     private final DeoptimizationAction action;
     private final DeoptimizationReason reason;
 
     public DeoptimizeNode(DeoptimizationAction action, DeoptimizationReason reason) {
-        super(StampFactory.forVoid());
         this.action = action;
         this.reason = reason;
     }
@@ -60,34 +47,14 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        gen.emitDeoptimize(action, this);
+        gen.emitDeoptimize(gen.getMetaAccess().encodeDeoptActionAndReason(action, reason), this);
+    }
+
+    @Override
+    public ValueNode getActionAndReason(MetaAccessProvider metaAccess) {
+        return ConstantNode.forConstant(metaAccess.encodeDeoptActionAndReason(action, reason), metaAccess, graph());
     }
 
     @NodeIntrinsic
     public static native void deopt(@ConstantNodeParameter DeoptimizationAction action, @ConstantNodeParameter DeoptimizationReason reason);
-
-    @Override
-    public boolean canDeoptimize() {
-        return true;
-    }
-
-    @Override
-    public FrameState getDeoptimizationState() {
-        return deoptState;
-    }
-
-    @Override
-    public void setDeoptimizationState(FrameState f) {
-        updateUsages(deoptState, f);
-        deoptState = f;
-    }
-
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return reason;
-    }
-
-    public FrameState getState() {
-        return deoptState;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizingNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.*;
 
 /**
@@ -46,13 +45,4 @@
      * @param state the FrameState which represents the deoptimization information
      */
     void setDeoptimizationState(FrameState state);
-
-    /**
-     * Returns the reason for deoptimization triggered by this node. If deoptimization at this point
-     * can happen for external reasons (i.e. not explicitely triggered by this node) this method can
-     * return null.
-     * 
-     * @return the reason for deoptimization triggered by this node.
-     */
-    DeoptimizationReason getDeoptimizationReason();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DynamicDeoptimizeNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, 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.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.spi.*;
+
+public class DynamicDeoptimizeNode extends AbstractDeoptimizeNode implements LIRLowerable {
+    @Input private ValueNode actionAndReason;
+
+    public DynamicDeoptimizeNode(ValueNode actionAndReason) {
+        this.actionAndReason = actionAndReason;
+    }
+
+    public ValueNode getActionAndReason() {
+        return actionAndReason;
+    }
+
+    @Override
+    public ValueNode getActionAndReason(MetaAccessProvider metaAccess) {
+        return getActionAndReason();
+    }
+
+    public void generate(LIRGeneratorTool generator) {
+        generator.emitDeoptimize(generator.operand(actionAndReason), this);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/EntryMarkerNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.spi.*;
 
 /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -136,9 +136,4 @@
     public boolean canDeoptimize() {
         return true;
     }
-
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return reason;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,11 +22,10 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 /**
@@ -91,7 +90,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (condition() instanceof LogicNegationNode) {
             LogicNegationNode negation = (LogicNegationNode) condition();
             return graph().unique(new GuardNode(negation.getInput(), getGuard(), reason, action, !negated));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardedValueNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -74,7 +75,8 @@
         }
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (getGuard() == graph().start()) {
             if (stamp().equals(object().stamp())) {
                 return object();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardingPiNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,9 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -93,7 +93,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (stamp() == StampFactory.illegal(object.kind())) {
             // The guard always fails
             return graph().add(new DeoptimizeNode(action, reason));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -30,6 +30,7 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
@@ -182,7 +183,7 @@
             if (this.trueSuccessorProbability < probabilityB) {
                 // Reordering of those two if statements is beneficial from the point of view of
                 // their probabilities.
-                if (prepareForSwap(tool.runtime(), condition(), nextIf.condition(), this.trueSuccessorProbability, probabilityB)) {
+                if (prepareForSwap(tool.getConstantReflection(), condition(), nextIf.condition(), this.trueSuccessorProbability, probabilityB)) {
                     // Reording is allowed from (if1 => begin => if2) to (if2 => begin => if1).
                     assert intermediateBegin.next() == nextIf;
                     AbstractBeginNode bothFalseBegin = nextIf.falseSuccessor();
@@ -207,7 +208,7 @@
         }
     }
 
-    private static boolean prepareForSwap(MetaAccessProvider runtime, LogicNode a, LogicNode b, double probabilityA, double probabilityB) {
+    private static boolean prepareForSwap(ConstantReflectionProvider constantReflection, LogicNode a, LogicNode b, double probabilityA, double probabilityB) {
         if (a instanceof InstanceOfNode) {
             InstanceOfNode instanceOfA = (InstanceOfNode) a;
             if (b instanceof IsNullNode) {
@@ -296,13 +297,13 @@
                     }
                 } else if (conditionA == Condition.EQ && conditionB == Condition.EQ) {
                     boolean canSwap = false;
-                    if ((compareA.x() == compareB.x() && valuesDistinct(runtime, compareA.y(), compareB.y()))) {
+                    if ((compareA.x() == compareB.x() && valuesDistinct(constantReflection, compareA.y(), compareB.y()))) {
                         canSwap = true;
-                    } else if ((compareA.x() == compareB.y() && valuesDistinct(runtime, compareA.y(), compareB.x()))) {
+                    } else if ((compareA.x() == compareB.y() && valuesDistinct(constantReflection, compareA.y(), compareB.x()))) {
                         canSwap = true;
-                    } else if ((compareA.y() == compareB.x() && valuesDistinct(runtime, compareA.x(), compareB.y()))) {
+                    } else if ((compareA.y() == compareB.x() && valuesDistinct(constantReflection, compareA.x(), compareB.y()))) {
                         canSwap = true;
-                    } else if ((compareA.y() == compareB.y() && valuesDistinct(runtime, compareA.x(), compareB.x()))) {
+                    } else if ((compareA.y() == compareB.y() && valuesDistinct(constantReflection, compareA.x(), compareB.x()))) {
                         canSwap = true;
                     }
 
@@ -317,9 +318,9 @@
         return false;
     }
 
-    private static boolean valuesDistinct(MetaAccessProvider runtime, ValueNode a, ValueNode b) {
+    private static boolean valuesDistinct(ConstantReflectionProvider constantReflection, ValueNode a, ValueNode b) {
         if (a.isConstant() && b.isConstant()) {
-            return !runtime.constantEquals(a.asConstant(), b.asConstant());
+            return !constantReflection.constantEquals(a.asConstant(), b.asConstant());
         }
 
         Stamp stampA = a.stamp();
@@ -486,7 +487,7 @@
         for (int i = 0; i < xs.length; i++) {
             AbstractEndNode end = ends.next();
             phiValues.put(end, phi.valueAt(end));
-            if (compare.condition().foldCondition(xs[i], ys[i], tool.runtime(), compare.unorderedIsTrue())) {
+            if (compare.condition().foldCondition(xs[i], ys[i], tool.getConstantReflection(), compare.unorderedIsTrue())) {
                 trueEnds.add(end);
             } else {
                 falseEnds.add(end);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -109,7 +109,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
@@ -174,11 +174,6 @@
     }
 
     @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return null;
-    }
-
-    @Override
     public FrameState getDeoptimizationState() {
         if (deoptState == null) {
             FrameState stateDuring = stateDuring();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/InvokeWithExceptionNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -121,7 +121,7 @@
     @Override
     public void setNext(FixedNode x) {
         if (x != null) {
-            this.setNext(AbstractBeginNode.begin(x));
+            this.setNext(KillingBeginNode.begin(x, getLocationIdentity()));
         } else {
             this.setNext(null);
         }
@@ -129,7 +129,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
@@ -219,11 +219,6 @@
     }
 
     @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return null;
-    }
-
-    @Override
     public FrameState getDeoptimizationState() {
         if (deoptState == null) {
             FrameState stateDuring = stateDuring();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/KillingBeginNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.extended.*;
+
+public class KillingBeginNode extends AbstractBeginNode implements MemoryCheckpoint.Single {
+
+    private LocationIdentity locationIdentity;
+
+    public KillingBeginNode(LocationIdentity locationIdentity) {
+        this.locationIdentity = locationIdentity;
+    }
+
+    public static KillingBeginNode begin(FixedNode with, LocationIdentity locationIdentity) {
+        if (with instanceof KillingBeginNode) {
+            return (KillingBeginNode) with;
+        }
+        KillingBeginNode begin = with.graph().add(new KillingBeginNode(locationIdentity));
+        begin.setNext(with);
+        return begin;
+    }
+
+    @Override
+    public LocationIdentity getLocationIdentity() {
+        return locationIdentity;
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LogicNegationNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,12 +23,12 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.graph.spi.*;
 
 /**
  * Logic node that negates its argument.
  */
-public class LogicNegationNode extends LogicNode implements Canonicalizable, IterableNodeType {
+public class LogicNegationNode extends LogicNode implements Canonicalizable {
 
     @Input private LogicNode input;
 
@@ -40,7 +40,8 @@
         return input;
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (input instanceof LogicNegationNode) {
             return ((LogicNegationNode) input).getInput();
         } else {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopExitNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.graph.spi.*;
 
 public class LoopExitNode extends BeginStateSplitNode implements IterableNodeType {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryMapNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,37 @@
+/*
+ * 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.nodes;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.type.*;
+
+public abstract class MemoryMapNode extends FloatingNode {
+
+    public MemoryMapNode() {
+        super(StampFactory.forVoid());
+    }
+
+    public abstract Node getLastLocationAccess(LocationIdentity locationIdentity);
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MemoryState.java	Fri Oct 11 17:14:35 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.nodes;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-
-public class MemoryState extends VirtualState {
-
-    private MemoryMap<Node> memoryMap;
-    @Input private Node object;
-
-    public MemoryState(MemoryMap<Node> memoryMap, FixedNode object) {
-        this.memoryMap = memoryMap;
-        this.object = object;
-    }
-
-    public Node object() {
-        return object;
-    }
-
-    public MemoryMap<Node> getMemoryMap() {
-        return memoryMap;
-    }
-
-    @Override
-    public VirtualState duplicateWithVirtualState() {
-        throw new GraalInternalError("should not reach here");
-    }
-
-    @Override
-    public void applyToNonVirtual(NodeClosure<? super ValueNode> closure) {
-        throw new GraalInternalError("should not reach here");
-    }
-
-    @Override
-    public void applyToVirtual(VirtualClosure closure) {
-        throw new GraalInternalError("should not reach here");
-    }
-
-    @Override
-    public boolean isPartOfThisState(VirtualState state) {
-        throw new GraalInternalError("should not reach here");
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/MergeNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.util.*;
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,9 +24,9 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 /**
@@ -34,7 +34,7 @@
  * variable.
  */
 @NodeInfo(nameTemplate = "{p#type/s}Phi({i#values})")
-public class PhiNode extends FloatingNode implements Canonicalizable, IterableNodeType, GuardingNode {
+public class PhiNode extends FloatingNode implements Canonicalizable, GuardingNode {
 
     public static enum PhiType {
         Value(null), // normal value phis
@@ -231,7 +231,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode singleValue = singleValue();
 
         if (singleValue != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiArrayNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -45,7 +47,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (!(object() instanceof ArrayLengthProvider) || length() != ((ArrayLengthProvider) object()).length()) {
             return this;
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PiNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -76,14 +77,13 @@
     @Override
     public void virtualize(VirtualizerTool tool) {
         State state = tool.getObjectState(object);
-        if (state != null && state.getState() == EscapeState.Virtual) {
-            assert ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type());
+        if (state != null && state.getState() == EscapeState.Virtual && ObjectStamp.typeOrNull(this).isAssignableFrom(state.getVirtualObject().type())) {
             tool.replaceWithVirtual(state.getVirtualObject());
         }
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         inferStamp();
         if (stamp().equals(object().stamp())) {
             return object();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ProxyNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.ValueNumberable;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
@@ -87,7 +88,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (type == PhiType.Value && value.isConstant()) {
             return value;
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ReturnNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -28,6 +28,7 @@
 public final class ReturnNode extends ControlSinkNode implements LIRLowerable {
 
     @Input private ValueNode result;
+    @Input private MemoryMapNode memoryMap;
 
     public ValueNode result() {
         return result;
@@ -40,8 +41,13 @@
      *            void return
      */
     public ReturnNode(ValueNode result) {
+        this(result, null);
+    }
+
+    public ReturnNode(ValueNode result, MemoryMapNode memoryMap) {
         super(StampFactory.forVoid());
         this.result = result;
+        this.memoryMap = memoryMap;
     }
 
     @Override
@@ -53,4 +59,13 @@
     public void generate(LIRGeneratorTool gen) {
         gen.visitReturn(this);
     }
+
+    public void setMemoryMap(MemoryMapNode memoryMap) {
+        updateUsages(this.memoryMap, memoryMap);
+        this.memoryMap = memoryMap;
+    }
+
+    public MemoryMapNode getMemoryMap() {
+        return memoryMap;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SafepointNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -41,11 +40,6 @@
     }
 
     @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return null;
-    }
-
-    @Override
     public boolean canDeoptimize() {
         return true;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ShortCircuitOrNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,7 +23,7 @@
 package com.oracle.graal.nodes;
 
 import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.graph.spi.*;
 
 public class ShortCircuitOrNode extends LogicNode implements IterableNodeType, Canonicalizable {
 
@@ -88,7 +88,7 @@
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         ShortCircuitOrNode ret = canonicalizeNegation();
         if (ret != null) {
             return ret;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Fri Oct 11 17:21:14 2013 +0200
@@ -250,7 +250,7 @@
         node.safeDelete();
     }
 
-    public void replaceFloating(FloatingNode node, ValueNode replacement) {
+    public void replaceFloating(FloatingNode node, Node replacement) {
         assert node != null && replacement != null && node.isAlive() && replacement.isAlive() : "cannot replace " + node + " with " + replacement;
         node.replaceAtUsages(replacement);
         node.safeDelete();
@@ -324,7 +324,7 @@
         for (Node successor : snapshot) {
             if (successor != null && successor.isAlive()) {
                 if (successor != survivingSuccessor) {
-                    GraphUtil.killCFG((AbstractBeginNode) successor);
+                    GraphUtil.killCFG(successor);
                 }
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/TypeProfileProxyNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -71,7 +72,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (ObjectStamp.isExactType(object)) {
             // The profile is useless - we know the type!
             return object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,7 +26,6 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.nodes.util.*;
 
 /**
  * This class represents a value within the graph, including local variables, phis, and all other
@@ -127,13 +126,6 @@
         return null;
     }
 
-    public <T extends Stamp> boolean verifyStamp(Class<T> stampClass) {
-        assert stamp() != null;
-        assert stampClass.isInstance(stamp()) : this + " (" + GraphUtil.approxSourceLocation(this) + ") has unexpected stamp type: expected " + stampClass.getName() + ", got " +
-                        stamp().getClass().getName() + ", usages=" + usages();
-        return true;
-    }
-
     @Override
     public boolean verify() {
         assertTrue(kind() != null, "Should have a valid kind");
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/AndNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -41,7 +42,13 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        return Constant.forIntegerKind(kind(), inputs[0].asLong() & inputs[1].asLong(), null);
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return x();
         }
@@ -49,12 +56,7 @@
             return graph().unique(new AndNode(kind(), y(), x()));
         }
         if (x().isConstant()) {
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(x().asConstant().asInt() & y().asConstant().asInt(), graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(x().asConstant().asLong() & y().asConstant().asLong(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
             if (kind() == Kind.Int) {
                 int c = y().asConstant().asInt();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -76,13 +77,13 @@
     public void generate(LIRGeneratorTool gen) {
     }
 
-    private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, MetaAccessProvider runtime, Condition cond) {
+    private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) {
         Constant trueConstant = conditionalNode.trueValue().asConstant();
         Constant falseConstant = conditionalNode.falseValue().asConstant();
 
-        if (falseConstant != null && trueConstant != null && runtime != null) {
-            boolean trueResult = cond.foldCondition(trueConstant, constant, runtime, unorderedIsTrue());
-            boolean falseResult = cond.foldCondition(falseConstant, constant, runtime, unorderedIsTrue());
+        if (falseConstant != null && trueConstant != null && constantReflection != null) {
+            boolean trueResult = cond.foldCondition(trueConstant, constant, constantReflection, unorderedIsTrue());
+            boolean falseResult = cond.foldCondition(falseConstant, constant, constantReflection, unorderedIsTrue());
 
             if (trueResult == falseResult) {
                 return LogicConstantNode.forBoolean(trueResult, graph());
@@ -115,19 +116,19 @@
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
-        if (x().isConstant() && y().isConstant() && tool.runtime() != null) {
-            return LogicConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.runtime(), unorderedIsTrue()), graph());
+    public Node canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && y().isConstant() && tool.getMetaAccess() != null) {
+            return LogicConstantNode.forBoolean(condition().foldCondition(x().asConstant(), y().asConstant(), tool.getConstantReflection(), unorderedIsTrue()), graph());
         }
         if (x().isConstant()) {
             if (y() instanceof ConditionalNode) {
-                return optimizeConditional(x().asConstant(), (ConditionalNode) y(), tool.runtime(), condition().mirror());
+                return optimizeConditional(x().asConstant(), (ConditionalNode) y(), tool.getConstantReflection(), condition().mirror());
             } else if (y() instanceof NormalizeCompareNode) {
                 return optimizeNormalizeCmp(x().asConstant(), (NormalizeCompareNode) y(), true);
             }
         } else if (y().isConstant()) {
             if (x() instanceof ConditionalNode) {
-                return optimizeConditional(y().asConstant(), (ConditionalNode) x(), tool.runtime(), condition());
+                return optimizeConditional(y().asConstant(), (ConditionalNode) x(), tool.getConstantReflection(), condition());
             } else if (x() instanceof NormalizeCompareNode) {
                 return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x(), false);
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/Condition.java	Fri Oct 11 17:21:14 2013 +0200
@@ -317,13 +317,13 @@
      * 
      * @param lt the constant on the left side of the comparison
      * @param rt the constant on the right side of the comparison
-     * @param runtime needed to compare runtime-specific types
+     * @param constantReflection needed to compare constants
      * @return {@link Boolean#TRUE} if the comparison is known to be true, {@link Boolean#FALSE} if
      *         the comparison is known to be false
      */
-    public boolean foldCondition(Constant lt, Constant rt, CodeCacheProvider runtime) {
+    public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection) {
         assert lt.getKind() != Kind.Double && lt.getKind() != Kind.Float && rt.getKind() != Kind.Double && rt.getKind() != Kind.Float;
-        return foldCondition(lt, rt, runtime, false);
+        return foldCondition(lt, rt, constantReflection, false);
     }
 
     /**
@@ -331,12 +331,12 @@
      * 
      * @param lt the constant on the left side of the comparison
      * @param rt the constant on the right side of the comparison
-     * @param runtime needed to compare runtime-specific types
+     * @param constantReflection needed to compare constants
      * @param unorderedIsTrue true if an undecided float comparison should result in "true"
      * @return true if the comparison is known to be true, false if the comparison is known to be
      *         false
      */
-    public boolean foldCondition(Constant lt, Constant rt, MetaAccessProvider runtime, boolean unorderedIsTrue) {
+    public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) {
         switch (lt.getKind()) {
             case Boolean:
             case Byte:
@@ -401,9 +401,9 @@
             case Object: {
                 switch (this) {
                     case EQ:
-                        return runtime.constantEquals(lt, rt);
+                        return constantReflection.constantEquals(lt, rt);
                     case NE:
-                        return !runtime.constantEquals(lt, rt);
+                        return !constantReflection.constantEquals(lt, rt);
                     default:
                         throw new GraalInternalError("expected condition: %s", this);
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConditionalNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,6 +25,8 @@
 import static com.oracle.graal.nodes.calc.CompareNode.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
@@ -66,7 +68,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (condition instanceof LogicNegationNode) {
             LogicNegationNode negated = (LogicNegationNode) condition;
             return graph().unique(new ConditionalNode(negated.getInput(), falseValue(), trueValue()));
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ConvertNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -150,52 +151,59 @@
         this.value = value;
     }
 
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 1;
+        Constant c = inputs[0];
+        switch (opcode) {
+            case I2L:
+                return Constant.forLong(c.asInt());
+            case L2I:
+                return Constant.forInt((int) c.asLong());
+            case I2B:
+                return Constant.forByte((byte) c.asInt());
+            case I2C:
+                return Constant.forChar((char) c.asInt());
+            case I2S:
+                return Constant.forShort((short) c.asInt());
+            case F2D:
+                return Constant.forDouble(c.asFloat());
+            case D2F:
+                return Constant.forFloat((float) c.asDouble());
+            case I2F:
+                return Constant.forFloat(c.asInt());
+            case I2D:
+                return Constant.forDouble(c.asInt());
+            case F2I:
+                return Constant.forInt((int) c.asFloat());
+            case D2I:
+                return Constant.forInt((int) c.asDouble());
+            case L2F:
+                return Constant.forFloat(c.asLong());
+            case L2D:
+                return Constant.forDouble(c.asLong());
+            case F2L:
+                return Constant.forLong((long) c.asFloat());
+            case D2L:
+                return Constant.forLong((long) c.asDouble());
+            case UNSIGNED_I2L:
+                return Constant.forLong(c.asInt() & 0xffffffffL);
+            case MOV_I2F:
+                return Constant.forFloat(java.lang.Float.intBitsToFloat(c.asInt()));
+            case MOV_L2D:
+                return Constant.forDouble(java.lang.Double.longBitsToDouble(c.asLong()));
+            case MOV_F2I:
+                return Constant.forInt(java.lang.Float.floatToRawIntBits(c.asFloat()));
+            case MOV_D2L:
+                return Constant.forLong(java.lang.Double.doubleToRawLongBits(c.asDouble()));
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (value instanceof ConstantNode) {
-            Constant c = ((ConstantNode) value).asConstant();
-            switch (opcode) {
-                case I2L:
-                    return ConstantNode.forLong(c.asInt(), graph());
-                case L2I:
-                    return ConstantNode.forInt((int) c.asLong(), graph());
-                case I2B:
-                    return ConstantNode.forByte((byte) c.asInt(), graph());
-                case I2C:
-                    return ConstantNode.forChar((char) c.asInt(), graph());
-                case I2S:
-                    return ConstantNode.forShort((short) c.asInt(), graph());
-                case F2D:
-                    return ConstantNode.forDouble(c.asFloat(), graph());
-                case D2F:
-                    return ConstantNode.forFloat((float) c.asDouble(), graph());
-                case I2F:
-                    return ConstantNode.forFloat(c.asInt(), graph());
-                case I2D:
-                    return ConstantNode.forDouble(c.asInt(), graph());
-                case F2I:
-                    return ConstantNode.forInt((int) c.asFloat(), graph());
-                case D2I:
-                    return ConstantNode.forInt((int) c.asDouble(), graph());
-                case L2F:
-                    return ConstantNode.forFloat(c.asLong(), graph());
-                case L2D:
-                    return ConstantNode.forDouble(c.asLong(), graph());
-                case F2L:
-                    return ConstantNode.forLong((long) c.asFloat(), graph());
-                case D2L:
-                    return ConstantNode.forLong((long) c.asDouble(), graph());
-                case UNSIGNED_I2L:
-                    return ConstantNode.forLong(c.asInt() & 0xffffffffL, graph());
-                case MOV_I2F:
-                    return ConstantNode.forFloat(java.lang.Float.intBitsToFloat(c.asInt()), graph());
-                case MOV_L2D:
-                    return ConstantNode.forDouble(java.lang.Double.longBitsToDouble(c.asLong()), graph());
-                case MOV_F2I:
-                    return ConstantNode.forInt(java.lang.Float.floatToRawIntBits(c.asFloat()), graph());
-                case MOV_D2L:
-                    return ConstantNode.forLong(java.lang.Double.doubleToRawLongBits(c.asDouble()), graph());
-            }
+    public Node canonical(CanonicalizerTool tool) {
+        if (value.isConstant()) {
+            return ConstantNode.forPrimitive(evalConst(value.asConstant()), graph());
         }
         return this;
     }
@@ -236,7 +244,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FixedBinaryNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -44,9 +44,4 @@
         this.x = x;
         this.y = y;
     }
-
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return DeoptimizationReason.ArithmeticException;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatAddNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -34,18 +35,23 @@
         super(kind, x, y, isStrictFP);
     }
 
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        if (kind() == Kind.Float) {
+            return Constant.forFloat(inputs[0].asFloat() + inputs[1].asFloat());
+        } else {
+            assert kind() == Kind.Double;
+            return Constant.forDouble(inputs[0].asDouble() + inputs[1].asDouble());
+        }
+    }
+
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
             return graph().unique(new FloatAddNode(kind(), y(), x(), isStrictFP()));
         }
         if (x().isConstant()) {
-            if (kind() == Kind.Float) {
-                return ConstantNode.forFloat(x().asConstant().asFloat() + y().asConstant().asFloat(), graph());
-            } else {
-                assert kind() == Kind.Double;
-                return ConstantNode.forDouble(x().asConstant().asDouble() + y().asConstant().asDouble(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
             if (kind() == Kind.Float) {
                 float c = y().asConstant().asFloat();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatDivNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -34,19 +35,20 @@
         super(kind, x, y, isStrictFP);
     }
 
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        if (kind() == Kind.Float) {
+            return Constant.forFloat(inputs[0].asFloat() / inputs[1].asFloat());
+        } else {
+            assert kind() == Kind.Double;
+            return Constant.forDouble(inputs[0].asDouble() / inputs[1].asDouble());
+        }
+    }
+
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
-            if (kind() == Kind.Float) {
-                if (y().asConstant().asFloat() != 0) {
-                    return ConstantNode.forFloat(x().asConstant().asFloat() / y().asConstant().asFloat(), graph());
-                }
-            } else {
-                assert kind() == Kind.Double;
-                if (y().asConstant().asDouble() != 0) {
-                    return ConstantNode.forDouble(x().asConstant().asDouble() / y().asConstant().asDouble(), graph());
-                }
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,8 +24,8 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 
 @NodeInfo(shortName = "<")
 public final class FloatLessThanNode extends CompareNode {
@@ -58,7 +58,7 @@
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y() && !unorderedIsTrue()) {
             return LogicConstantNode.contradiction(graph());
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatMulNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -34,18 +35,23 @@
         super(kind, x, y, isStrictFP);
     }
 
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        if (kind() == Kind.Float) {
+            return Constant.forFloat(inputs[0].asFloat() * inputs[1].asFloat());
+        } else {
+            assert kind() == Kind.Double;
+            return Constant.forDouble(inputs[0].asDouble() * inputs[1].asDouble());
+        }
+    }
+
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
             return graph().unique(new FloatMulNode(kind(), y(), x(), isStrictFP()));
         }
         if (x().isConstant()) {
-            if (kind() == Kind.Float) {
-                return ConstantNode.forFloat(x().asConstant().asFloat() * y().asConstant().asFloat(), graph());
-            } else {
-                assert kind() == Kind.Double;
-                return ConstantNode.forDouble(x().asConstant().asDouble() * y().asConstant().asDouble(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatRemNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -34,15 +35,20 @@
         super(kind, x, y, isStrictFP);
     }
 
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        if (kind() == Kind.Float) {
+            return Constant.forFloat(inputs[0].asFloat() % inputs[1].asFloat());
+        } else {
+            assert kind() == Kind.Double;
+            return Constant.forDouble(inputs[0].asDouble() % inputs[1].asDouble());
+        }
+    }
+
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
-            if (kind() == Kind.Float) {
-                return ConstantNode.forFloat(x().asConstant().asFloat() % y().asConstant().asFloat(), graph());
-            } else {
-                assert kind() == Kind.Double;
-                return ConstantNode.forDouble(x().asConstant().asDouble() % y().asConstant().asDouble(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         }
         return this;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatSubNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -34,18 +35,23 @@
         super(kind, x, y, isStrictFP);
     }
 
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        if (kind() == Kind.Float) {
+            return Constant.forFloat(inputs[0].asFloat() - inputs[1].asFloat());
+        } else {
+            assert kind() == Kind.Double;
+            return Constant.forDouble(inputs[0].asDouble() - inputs[1].asDouble());
+        }
+    }
+
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return ConstantNode.forFloatingKind(kind(), 0.0f, graph());
         }
         if (x().isConstant() && y().isConstant()) {
-            if (kind() == Kind.Float) {
-                return ConstantNode.forFloat(x().asConstant().asFloat() - y().asConstant().asFloat(), graph());
-            } else {
-                assert kind() == Kind.Double;
-                return ConstantNode.forDouble(x().asConstant().asDouble() - y().asConstant().asDouble(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
             if (kind() == Kind.Float) {
                 float c = y().asConstant().asFloat();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerAddNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -41,7 +42,13 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        return Constant.forIntegerKind(kind(), inputs[0].asLong() + inputs[1].asLong(), null);
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
             return graph().unique(new IntegerAddNode(kind(), y(), x()));
         }
@@ -60,12 +67,7 @@
             }
         }
         if (x().isConstant()) {
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(x().asConstant().asInt() + y().asConstant().asInt(), graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(x().asConstant().asLong() + y().asConstant().asLong(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
             long c = y().asConstant().asLong();
             if (c == 0) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,8 +24,8 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "|<|")
@@ -54,7 +54,7 @@
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return LogicConstantNode.contradiction(graph());
         } else {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerDivNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -42,7 +43,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
             long yConst = y().asConstant().asLong();
             if (yConst == 0) {
@@ -111,7 +112,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,8 +24,8 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 
 @NodeInfo(shortName = "==")
 public final class IntegerEqualsNode extends CompareNode {
@@ -68,7 +68,7 @@
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return LogicConstantNode.tautology(graph());
         } else if (x().stamp().alwaysDistinct(y().stamp())) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,8 +24,8 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 @NodeInfo(shortName = "<")
@@ -70,7 +70,7 @@
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return LogicConstantNode.contradiction(graph());
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerMulNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -36,17 +37,18 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        return Constant.forIntegerKind(kind(), inputs[0].asLong() * inputs[1].asLong(), null);
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
             return graph().unique(new IntegerMulNode(kind(), y(), x()));
         }
         if (x().isConstant()) {
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(x().asConstant().asInt() * y().asConstant().asInt(), graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(x().asConstant().asLong() * y().asConstant().asLong(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
             long c = y().asConstant().asLong();
             if (c == 1) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerRemNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -37,7 +38,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
             long yConst = y().asConstant().asLong();
             if (yConst == 0) {
@@ -62,7 +63,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerSubNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -41,7 +42,13 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        return Constant.forIntegerKind(kind(), inputs[0].asLong() - inputs[1].asLong(), null);
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return ConstantNode.forIntegerKind(kind(), 0, graph());
         }
@@ -80,12 +87,7 @@
             }
         }
         if (x().isConstant() && y().isConstant()) {
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(x().asConstant().asInt() - y().asConstant().asInt(), graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(x().asConstant().asLong() - y().asConstant().asLong(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
             long c = y().asConstant().asLong();
             if (c == 0) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerTestNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -61,7 +63,7 @@
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
             return LogicConstantNode.forBoolean((x().asConstant().asLong() & y().asConstant().asLong()) == 0, graph());
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IsNullNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.nodes.calc;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -60,7 +62,7 @@
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         Constant constant = object().asConstant();
         if (constant != null) {
             assert constant.getKind() == Kind.Object;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/LeftShiftNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -41,8 +42,21 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (y().isConstant()) {
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        if (kind() == Kind.Int) {
+            return Constant.forInt(inputs[0].asInt() << inputs[1].asInt());
+        } else {
+            assert kind() == Kind.Long;
+            return Constant.forLong(inputs[0].asLong() << inputs[1].asLong());
+        }
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && y().isConstant()) {
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
+        } else if (y().isConstant()) {
             int amount = y().asConstant().asInt();
             int originalAmout = amount;
             int mask;
@@ -53,14 +67,6 @@
                 mask = 0x3f;
             }
             amount &= mask;
-            if (x().isConstant()) {
-                if (kind() == Kind.Int) {
-                    return ConstantNode.forInt(x().asConstant().asInt() << amount, graph());
-                } else {
-                    assert kind() == Kind.Long;
-                    return ConstantNode.forLong(x().asConstant().asLong() << amount, graph());
-                }
-            }
             if (amount == 0) {
                 return x();
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NegateNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,6 +22,9 @@
  */
 package com.oracle.graal.nodes.calc;
 
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -52,19 +55,26 @@
         this.x = x;
     }
 
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 1;
+        switch (inputs[0].getKind()) {
+            case Int:
+                return Constant.forInt(-inputs[0].asInt());
+            case Long:
+                return Constant.forLong(-inputs[0].asLong());
+            case Float:
+                return Constant.forFloat(-inputs[0].asFloat());
+            case Double:
+                return Constant.forDouble(-inputs[0].asDouble());
+            default:
+                throw GraalInternalError.shouldNotReachHere();
+        }
+    }
+
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant()) {
-            switch (x().kind()) {
-                case Int:
-                    return ConstantNode.forInt(-x().asConstant().asInt(), graph());
-                case Long:
-                    return ConstantNode.forLong(-x().asConstant().asLong(), graph());
-                case Float:
-                    return ConstantNode.forFloat(-x().asConstant().asFloat(), graph());
-                case Double:
-                    return ConstantNode.forDouble(-x().asConstant().asDouble(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x.asConstant()), graph());
         }
         if (x() instanceof NegateNode) {
             return ((NegateNode) x()).x();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/NotNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.nodes.calc;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -43,6 +45,12 @@
         return updateStamp(StampTool.not(x().stamp()));
     }
 
+    @Override
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 1;
+        return Constant.forIntegerKind(kind(), ~inputs[0].asLong(), null);
+    }
+
     /**
      * Creates new NegateNode instance.
      * 
@@ -55,14 +63,9 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant()) {
-            switch (x().kind()) {
-                case Int:
-                    return ConstantNode.forInt(~x().asConstant().asInt(), graph());
-                case Long:
-                    return ConstantNode.forLong(~x().asConstant().asLong(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant()), graph());
         }
         if (x() instanceof NotNode) {
             return ((NotNode) x()).x();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -54,7 +55,7 @@
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return LogicConstantNode.tautology(graph());
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/OrNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -41,7 +42,13 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        return Constant.forIntegerKind(kind(), inputs[0].asLong() | inputs[1].asLong(), null);
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return x();
         }
@@ -49,12 +56,7 @@
             return graph().unique(new OrNode(kind(), y(), x()));
         }
         if (x().isConstant()) {
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(x().asConstant().asInt() | y().asConstant().asInt(), graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(x().asConstant().asLong() | y().asConstant().asLong(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
             if (kind() == Kind.Int) {
                 int c = y().asConstant().asInt();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/RightShiftNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -36,11 +37,24 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        if (kind() == Kind.Int) {
+            return Constant.forInt(inputs[0].asInt() >> inputs[1].asInt());
+        } else {
+            assert kind() == Kind.Long;
+            return Constant.forLong(inputs[0].asLong() >> inputs[1].asLong());
+        }
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (x().stamp() instanceof IntegerStamp && ((IntegerStamp) x().stamp()).isPositive()) {
             return graph().unique(new UnsignedRightShiftNode(kind(), x(), y()));
         }
-        if (y().isConstant()) {
+        if (x().isConstant() && y().isConstant()) {
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
+        } else if (y().isConstant()) {
             int amount = y().asConstant().asInt();
             int originalAmout = amount;
             int mask;
@@ -51,14 +65,6 @@
                 mask = 0x3f;
             }
             amount &= mask;
-            if (x().isConstant()) {
-                if (kind() == Kind.Int) {
-                    return ConstantNode.forInt(x().asConstant().asInt() >> amount, graph());
-                } else {
-                    assert kind() == Kind.Long;
-                    return ConstantNode.forLong(x().asConstant().asLong() >> amount, graph());
-                }
-            }
             if (amount == 0) {
                 return x();
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedDivNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -37,7 +38,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
             long yConst = y().asConstant().asLong();
             if (yConst == 0) {
@@ -63,7 +64,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRemNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -37,7 +38,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && y().isConstant()) {
             long yConst = y().asConstant().asLong();
             if (yConst == 0) {
@@ -62,7 +63,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/UnsignedRightShiftNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -41,8 +42,21 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (y().isConstant()) {
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        if (kind() == Kind.Int) {
+            return Constant.forInt(inputs[0].asInt() >>> inputs[1].asInt());
+        } else {
+            assert kind() == Kind.Long;
+            return Constant.forLong(inputs[0].asLong() >>> inputs[1].asLong());
+        }
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (x().isConstant() && y().isConstant()) {
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
+        } else if (y().isConstant()) {
             int amount = y().asConstant().asInt();
             int originalAmout = amount;
             int mask;
@@ -53,14 +67,6 @@
                 mask = 0x3f;
             }
             amount &= mask;
-            if (x().isConstant()) {
-                if (kind() == Kind.Int) {
-                    return ConstantNode.forInt(x().asConstant().asInt() >>> amount, graph());
-                } else {
-                    assert kind() == Kind.Long;
-                    return ConstantNode.forLong(x().asConstant().asLong() >>> amount, graph());
-                }
-            }
             if (amount == 0) {
                 return x();
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/XorNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -41,7 +42,13 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 2;
+        return Constant.forIntegerKind(kind(), inputs[0].asLong() ^ inputs[1].asLong(), null);
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return ConstantNode.forIntegerKind(kind(), 0, graph());
         }
@@ -49,12 +56,7 @@
             return graph().unique(new XorNode(kind(), y(), x()));
         }
         if (x().isConstant()) {
-            if (kind() == Kind.Int) {
-                return ConstantNode.forInt(x().asConstant().asInt() ^ y().asConstant().asInt(), graph());
-            } else {
-                assert kind() == Kind.Long;
-                return ConstantNode.forLong(x().asConstant().asLong() ^ y().asConstant().asLong(), graph());
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant(), y().asConstant()), graph());
         } else if (y().isConstant()) {
             if (kind() == Kind.Int) {
                 int c = y().asConstant().asInt();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/DynamicCounterNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,200 +22,61 @@
  */
 package com.oracle.graal.nodes.debug;
 
-import java.io.*;
-import java.util.*;
-
-import sun.misc.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.HeapAccess.BarrierType;
-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.*;
 
 /**
  * This node can be used to add a counter to the code that will estimate the dynamic number of calls
  * by adding an increment to the compiled code. This should of course only be used for
- * debugging/testing purposes, and is not 100% accurate (because of concurrency issues while
- * accessing the counters).
+ * debugging/testing purposes.
  * 
- * A unique counter will be created for each unique String passed to the constructor.
+ * A unique counter will be created for each unique name passed to the constructor. Depending on the
+ * value of withContext, the name of the root method is added to the counter's name.
  */
 public class DynamicCounterNode extends FixedWithNextNode implements Lowerable {
 
-    private static final int MAX_COUNTERS = 10 * 1024;
-    public static final long[] COUNTERS = new long[MAX_COUNTERS];
-    private static final long[] STATIC_COUNTERS = new long[MAX_COUNTERS];
-    private static final String[] GROUPS = new String[MAX_COUNTERS];
-    private static final HashMap<String, Integer> INDEXES = new HashMap<>();
-    public static String excludedClassPrefix = null;
-    public static boolean enabled = false;
+    @Input private ValueNode increment;
 
     private final String name;
     private final String group;
-    private final long increment;
-    private final boolean addContext;
+    private final boolean withContext;
 
-    public DynamicCounterNode(String name, String group, long increment, boolean addContext) {
+    public DynamicCounterNode(String name, String group, ValueNode increment, boolean withContext) {
         super(StampFactory.forVoid());
-        if (!enabled) {
-            throw new GraalInternalError("dynamic counters not enabled");
-        }
         this.name = name;
         this.group = group;
         this.increment = increment;
-        this.addContext = addContext;
+        this.withContext = withContext;
+    }
+
+    public ValueNode getIncrement() {
+        return increment;
     }
 
     public String getName() {
         return name;
     }
 
-    public long getIncrement() {
-        return increment;
-    }
-
-    public boolean isAddContext() {
-        return addContext;
-    }
-
-    private static synchronized int getIndex(String name) {
-        Integer index = INDEXES.get(name);
-        if (index == null) {
-            index = INDEXES.size();
-            INDEXES.put(name, index);
-            if (index >= MAX_COUNTERS) {
-                throw new GraalInternalError("too many dynamic counters");
-            }
-            return index;
-        } else {
-            return index;
-        }
-    }
-
-    public static synchronized void dump(PrintStream out, double seconds) {
-        for (String group : new HashSet<>(Arrays.asList(GROUPS))) {
-            if (group != null) {
-                dumpCounters(out, seconds, true, group);
-                dumpCounters(out, seconds, false, group);
-            }
-        }
-        out.println("============================");
-
-        clear();
+    public String getGroup() {
+        return group;
     }
 
-    private static void dumpCounters(PrintStream out, double seconds, boolean staticCounter, String group) {
-        TreeMap<Long, String> sorted = new TreeMap<>();
-
-        long[] array = staticCounter ? STATIC_COUNTERS : COUNTERS;
-        long sum = 0;
-        for (Map.Entry<String, Integer> entry : INDEXES.entrySet()) {
-            int index = entry.getValue();
-            if (GROUPS[index].equals(group)) {
-                sum += array[index];
-                sorted.put(array[index] * MAX_COUNTERS + index, entry.getKey());
-            }
-        }
-
-        if (sum > 0) {
-            long cutoff = sum / 1000;
-            long sum2 = 0;
-            if (staticCounter) {
-                out.println("=========== " + group + " static counters: ");
-                for (Map.Entry<Long, String> entry : sorted.entrySet()) {
-                    long counter = entry.getKey() / MAX_COUNTERS;
-                    sum2 += counter;
-                    if (sum2 >= cutoff) {
-                        out.println(counter + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue());
-                    }
-                }
-                out.println(sum + ": total");
-            } else {
-                if (group.startsWith("~")) {
-                    out.println("=========== " + group + " dynamic counters");
-                    for (Map.Entry<Long, String> entry : sorted.entrySet()) {
-                        long counter = entry.getKey() / MAX_COUNTERS;
-                        sum2 += counter;
-                        if (sum2 >= cutoff) {
-                            out.println(counter + " \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue());
-                        }
-                    }
-                    out.println(sum + "/s: total");
-                } else {
-                    out.println("=========== " + group + " dynamic counters, time = " + seconds + " s");
-                    for (Map.Entry<Long, String> entry : sorted.entrySet()) {
-                        long counter = entry.getKey() / MAX_COUNTERS;
-                        sum2 += counter;
-                        if (sum2 >= cutoff) {
-                            out.println((long) (counter / seconds) + "/s \t" + ((counter * 200 + 1) / sum / 2) + "% \t" + entry.getValue());
-                        }
-                    }
-                    out.println((long) (sum / seconds) + "/s: total");
-                }
-            }
-        }
-    }
-
-    public static void clear() {
-        Arrays.fill(COUNTERS, 0);
+    public boolean isWithContext() {
+        return withContext;
     }
 
     @Override
     public void lower(LoweringTool tool) {
-        if (!enabled) {
-            throw new GraalInternalError("counter nodes shouldn't exist when not enabled");
-        }
-        if (excludedClassPrefix == null || !graph().method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) {
-            int index = addContext ? getIndex(name + " @ " + MetaUtil.format("%h.%n", graph().method())) : getIndex(name);
-            STATIC_COUNTERS[index] += increment;
-            GROUPS[index] = group;
-
-            ConstantNode arrayConstant = ConstantNode.forObject(COUNTERS, tool.getRuntime(), graph());
-            ConstantNode indexConstant = ConstantNode.forInt(index, graph());
-            LoadIndexedNode load = graph().add(new LoadIndexedNode(arrayConstant, indexConstant, Kind.Long));
-            IntegerAddNode add = graph().add(new IntegerAddNode(Kind.Long, load, ConstantNode.forLong(increment, graph())));
-            StoreIndexedNode store = graph().add(new StoreIndexedNode(arrayConstant, indexConstant, Kind.Long, add));
-
-            graph().addBeforeFixed(this, load);
-            graph().addBeforeFixed(this, store);
-            load.lower(tool);
-            store.lower(tool);
-        }
-        graph().removeFixed(this);
+        tool.getLowerer().lower(this, tool);
     }
 
-    public static void addLowLevel(String group, String name, long increment, boolean addContext, FixedNode position, MetaAccessProvider runtime) {
-        if (!enabled) {
-            throw new GraalInternalError("counter nodes shouldn't exist when not enabled");
-        }
+    public static void addCounterBefore(String group, String name, long increment, boolean withContext, FixedNode position) {
         StructuredGraph graph = position.graph();
-        if (excludedClassPrefix == null || !graph.method().getDeclaringClass().getName().startsWith(excludedClassPrefix)) {
-            int index = addContext ? getIndex(name + " @ " + MetaUtil.format("%h.%n", graph.method())) : getIndex(name);
-            STATIC_COUNTERS[index] += increment;
-            GROUPS[index] = group;
-
-            ConstantNode arrayConstant = ConstantNode.forObject(COUNTERS, runtime, graph);
-            ConstantLocationNode location = ConstantLocationNode.create(NamedLocationIdentity.getArrayLocation(Kind.Long), Kind.Long, Unsafe.ARRAY_LONG_BASE_OFFSET + Unsafe.ARRAY_LONG_INDEX_SCALE *
-                            index, graph);
-            ReadNode read = graph.add(new ReadNode(arrayConstant, location, StampFactory.forKind(Kind.Long), BarrierType.NONE, false));
-            IntegerAddNode add = graph.add(new IntegerAddNode(Kind.Long, read, ConstantNode.forLong(increment, graph)));
-            WriteNode write = graph.add(new WriteNode(arrayConstant, add, location, BarrierType.NONE, false));
-
-            graph.addBeforeFixed(position, read);
-            graph.addBeforeFixed(position, write);
-        }
+        graph.addBeforeFixed(position, position.graph().add(new DynamicCounterNode(name, group, ConstantNode.forLong(increment, position.graph()), withContext)));
     }
 
-    public static void addCounterBefore(String group, String name, long increment, boolean addContext, FixedNode position) {
-        if (enabled) {
-            StructuredGraph graph = position.graph();
-            DynamicCounterNode counter = graph.add(new DynamicCounterNode(name, group, increment, addContext));
-            graph.addBeforeFixed(position, counter);
-        }
-    }
+    @NodeIntrinsic
+    public static native void counter(@ConstantNodeParameter String name, @ConstantNodeParameter String group, long increment, @ConstantNodeParameter boolean addContext);
+
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/SurvivingCounterNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +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.nodes.debug;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-
-/**
- * This is a special version of the dynamic counter node that removes itself as soon as it's the
- * only usage of the associated node. This way it only increments the counter if the node is
- * actually executed.
- */
-public class SurvivingCounterNode extends DynamicCounterNode implements Simplifiable, Virtualizable {
-
-    @Input private ValueNode checkedValue;
-
-    public SurvivingCounterNode(String group, String name, long increment, boolean addContext, ValueNode checkedValue) {
-        super(group, name, increment, addContext);
-        this.checkedValue = checkedValue;
-    }
-
-    @Override
-    public void simplify(SimplifierTool tool) {
-        if (checkedValue instanceof FloatingNode && checkedValue.usages().count() == 1) {
-            tool.addToWorkList(checkedValue);
-            graph().removeFixed(this);
-        }
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        State state = tool.getObjectState(checkedValue);
-        if (state != null && state.getState() == EscapeState.Virtual) {
-            tool.delete();
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/WeakCounterNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,65 @@
+/*
+ * 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.nodes.debug;
+
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * This is a special version of the dynamic counter node that removes itself as soon as it's the
+ * only usage of the associated node. This way it only increments the counter if the node is
+ * actually executed.
+ */
+public class WeakCounterNode extends DynamicCounterNode implements Simplifiable, Virtualizable {
+
+    @Input private ValueNode checkedValue;
+
+    public WeakCounterNode(String group, String name, ValueNode increment, boolean addContext, ValueNode checkedValue) {
+        super(group, name, increment, addContext);
+        this.checkedValue = checkedValue;
+    }
+
+    @Override
+    public void simplify(SimplifierTool tool) {
+        if (checkedValue instanceof FloatingNode && checkedValue.usages().count() == 1) {
+            tool.addToWorkList(checkedValue);
+            graph().removeFixed(this);
+        }
+    }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        State state = tool.getObjectState(checkedValue);
+        if (state != null && state.getState() == EscapeState.Virtual) {
+            tool.delete();
+        }
+    }
+
+    public static void addCounterBefore(String group, String name, long increment, boolean addContext, ValueNode checkedValue, FixedNode position) {
+        StructuredGraph graph = position.graph();
+        WeakCounterNode counter = graph.add(new WeakCounterNode(name, group, ConstantNode.forLong(increment, graph), addContext, checkedValue));
+        graph.addBeforeFixed(position, counter);
+    }
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AccessNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -83,11 +82,6 @@
     }
 
     @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return DeoptimizationReason.NullCheckException;
-    }
-
-    @Override
     public GuardingNode getGuard() {
         return guard;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -69,7 +70,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x instanceof ConstantLocationNode) {
             return canonical((ConstantLocationNode) x, getY());
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BoxNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -54,11 +56,11 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         /*
          * Constant values are not canonicalized into their constant boxing objects because this
          * would mean that the information that they came from a valueOf is lost.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/BranchProbabilityNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -64,7 +65,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (probability.isConstant()) {
             double probabilityValue = probability.asConstant().asDouble();
             if (probabilityValue < 0.0) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -75,11 +74,6 @@
     }
 
     @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return DeoptimizationReason.NullCheckException;
-    }
-
-    @Override
     public FrameState getDeoptimizationState() {
         return deoptState;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,7 +24,9 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -65,7 +67,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         return ReadNode.canonicalizeRead(this, location(), object(), tool, isCompressible());
     }
 
@@ -73,4 +75,25 @@
     public Access asFixedNode() {
         return graph().add(new ReadNode(object(), nullCheckLocation(), stamp(), getGuard(), getBarrierType(), isCompressible()));
     }
+
+    private static boolean isMemoryCheckPoint(Node n) {
+        return n instanceof MemoryCheckpoint.Single || n instanceof MemoryCheckpoint.Multi;
+    }
+
+    private static boolean isMemoryPhi(Node n) {
+        return n instanceof PhiNode && ((PhiNode) n).type() == PhiType.Memory;
+    }
+
+    private static boolean isMemoryProxy(Node n) {
+        return n instanceof ProxyNode && ((ProxyNode) n).type() == PhiType.Memory;
+    }
+
+    @Override
+    public boolean verify() {
+        Node lla = lastLocationAccess();
+        if (lla != null && !(isMemoryCheckPoint(lla) || isMemoryPhi(lla) || isMemoryProxy(lla))) {
+            assert false : "lastLocationAccess of " + this + " should be a MemoryCheckpoint, but is " + lla;
+        }
+        return super.verify();
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ForeignCallNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -36,28 +36,28 @@
 public class ForeignCallNode extends AbstractStateSplit implements LIRLowerable, DeoptimizingNode, MemoryCheckpoint.Multi {
 
     @Input private final NodeInputList<ValueNode> arguments;
-    private final MetaAccessProvider runtime;
+    private final MetaAccessProvider metaAccess;
     @Input private FrameState deoptState;
 
     private final ForeignCallDescriptor descriptor;
 
-    public ForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, ValueNode... arguments) {
+    public ForeignCallNode(MetaAccessProvider metaAccess, ForeignCallDescriptor descriptor, ValueNode... arguments) {
         super(StampFactory.forKind(Kind.fromJavaClass(descriptor.getResultType())));
         this.arguments = new NodeInputList<>(this, arguments);
         this.descriptor = descriptor;
-        this.runtime = runtime;
+        this.metaAccess = metaAccess;
     }
 
-    protected ForeignCallNode(MetaAccessProvider runtime, ForeignCallDescriptor descriptor, Stamp stamp) {
+    protected ForeignCallNode(MetaAccessProvider metaAccess, ForeignCallDescriptor descriptor, Stamp stamp) {
         super(stamp);
         this.arguments = new NodeInputList<>(this);
         this.descriptor = descriptor;
-        this.runtime = runtime;
+        this.metaAccess = metaAccess;
     }
 
     @Override
     public boolean hasSideEffect() {
-        return !runtime.isReexecutable(descriptor);
+        return !metaAccess.isReexecutable(descriptor);
     }
 
     public ForeignCallDescriptor getDescriptor() {
@@ -66,7 +66,7 @@
 
     @Override
     public LocationIdentity[] getLocationIdentities() {
-        return runtime.getKilledLocations(descriptor);
+        return metaAccess.getKilledLocations(descriptor);
     }
 
     protected Value[] operands(LIRGeneratorTool gen) {
@@ -79,7 +79,7 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(descriptor);
+        ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(descriptor);
         Value[] operands = operands(gen);
         Value result = gen.emitForeignCall(linkage, this, operands);
         if (result != null) {
@@ -126,12 +126,7 @@
 
     @Override
     public boolean canDeoptimize() {
-        return runtime.canDeoptimize(descriptor);
-    }
-
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return null;
+        return metaAccess.canDeoptimize(descriptor);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -85,7 +86,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (index == null || indexScaling == 0) {
             return ConstantLocationNode.create(getLocationIdentity(), getValueKind(), displacement, graph());
         } else if (index.isConstant()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IntegerSwitchNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,6 +25,7 @@
 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.spi.*;
 import com.oracle.graal.nodes.type.*;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,8 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ResolvedJavaType.Representation;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -60,14 +62,14 @@
     @Override
     public void lower(LoweringTool tool) {
         if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
-            tool.getRuntime().lower(this, tool);
+            tool.getLowerer().lower(this, tool);
         }
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        MetaAccessProvider runtime = tool.runtime();
-        if (runtime != null && object.stamp() instanceof ObjectStamp) {
+    public Node canonical(CanonicalizerTool tool) {
+        MetaAccessProvider metaAccess = tool.getMetaAccess();
+        if (metaAccess != null && object.stamp() instanceof ObjectStamp) {
             ObjectStamp stamp = (ObjectStamp) object.stamp();
 
             ResolvedJavaType exactType;
@@ -83,7 +85,7 @@
             }
 
             if (exactType != null) {
-                return ConstantNode.forConstant(exactType.getEncoding(Representation.ObjectHub), runtime, graph());
+                return ConstantNode.forConstant(exactType.getEncoding(Representation.ObjectHub), metaAccess, graph());
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadMethodNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -52,7 +52,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public ResolvedJavaMethod getMethod() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/NullCheckNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes.extended;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -49,9 +48,4 @@
     public boolean canDeoptimize() {
         return true;
     }
-
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return DeoptimizationReason.NullCheckException;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/OSRStartNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -30,7 +30,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public NodeIterable<OSRLocalNode> getOSRLocals() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -41,18 +43,6 @@
         super(object, location, stamp, guard, barrierType, compressible);
     }
 
-    public ReadNode(ValueNode object, int displacement, LocationIdentity locationIdentity, Kind kind) {
-        super(object, ConstantLocationNode.create(locationIdentity, kind, displacement, object.graph()), StampFactory.forKind(kind));
-    }
-
-    private ReadNode(ValueNode object, ValueNode location, ValueNode guard) {
-        /*
-         * Used by node intrinsics. Since the initial value for location is a parameter, i.e., a
-         * LocalNode, the constructor cannot use the declared type LocationNode.
-         */
-        super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, BarrierType.NONE, false);
-    }
-
     @Override
     public void generate(LIRGeneratorTool gen) {
         Value address = location().generateAddress(gen, gen.operand(object()));
@@ -60,7 +50,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         return canonicalizeRead(this, location(), object(), tool, isCompressible());
     }
 
@@ -70,29 +60,29 @@
     }
 
     public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool, boolean compressible) {
-        MetaAccessProvider runtime = tool.runtime();
+        MetaAccessProvider metaAccess = tool.getMetaAccess();
         if (read.usages().isEmpty()) {
             // Read without usages can be savely removed.
             return null;
         }
-        if (tool.canonicalizeReads() && runtime != null && object != null && object.isConstant()) {
+        if (tool.canonicalizeReads() && metaAccess != null && object != null && object.isConstant()) {
             if (location.getLocationIdentity() == LocationIdentity.FINAL_LOCATION && location instanceof ConstantLocationNode) {
                 long displacement = ((ConstantLocationNode) location).getDisplacement();
                 Kind kind = location.getValueKind();
                 if (object.kind() == Kind.Object) {
                     Object base = object.asConstant().asObject();
                     if (base != null) {
-                        Constant constant = tool.runtime().readUnsafeConstant(kind, base, displacement, compressible);
+                        Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, base, displacement, compressible);
                         if (constant != null) {
-                            return ConstantNode.forConstant(constant, runtime, read.graph());
+                            return ConstantNode.forConstant(constant, metaAccess, read.graph());
                         }
                     }
                 } else if (object.kind() == Kind.Long || object.kind().getStackKind() == Kind.Int) {
                     long base = object.asConstant().asLong();
                     if (base != 0L) {
-                        Constant constant = tool.runtime().readUnsafeConstant(kind, null, base + displacement, compressible);
+                        Constant constant = tool.getConstantReflection().readUnsafeConstant(kind, null, base + displacement, compressible);
                         if (constant != null) {
-                            return ConstantNode.forConstant(constant, runtime, read.graph());
+                            return ConstantNode.forConstant(constant, metaAccess, read.graph());
                         }
                     }
                 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SnippetLocationNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -80,7 +81,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (valueKind.isConstant() && locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) {
             Kind constKind = (Kind) valueKind.asConstant().asObject();
             LocationIdentity constLocation = (LocationIdentity) locationIdentity.asConstant().asObject();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/StoreHubNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -47,7 +47,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnboxNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -49,7 +51,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
@@ -61,7 +63,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
             Constant constant = value.asConstant();
             Object o = constant.asObject();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeAccessNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,34 +23,35 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 public abstract class UnsafeAccessNode extends FixedWithNextNode implements Canonicalizable {
 
     @Input private ValueNode object;
     @Input private ValueNode offset;
-    private final int displacement;
     private final Kind accessKind;
+    private final LocationIdentity locationIdentity;
 
-    public UnsafeAccessNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, Kind accessKind) {
+    public UnsafeAccessNode(Stamp stamp, ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity) {
         super(stamp);
         assert accessKind != null;
         this.object = object;
-        this.displacement = displacement;
         this.offset = offset;
         this.accessKind = accessKind;
+        this.locationIdentity = locationIdentity;
+    }
+
+    public LocationIdentity getLocationIdentity() {
+        return locationIdentity;
     }
 
     public ValueNode object() {
         return object;
     }
 
-    public int displacement() {
-        return displacement;
-    }
-
     public ValueNode offset() {
         return offset;
     }
@@ -60,14 +61,14 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        if (offset().isConstant()) {
+    public Node canonical(CanonicalizerTool tool) {
+        if (this.getLocationIdentity() == LocationIdentity.ANY_LOCATION && offset().isConstant()) {
             long constantOffset = offset().asConstant().asLong();
 
             // Try to canonicalize to a field access.
             ResolvedJavaType receiverType = ObjectStamp.typeOrNull(object());
             if (receiverType != null) {
-                ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(displacement() + constantOffset);
+                ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantOffset);
                 // No need for checking that the receiver is non-null. The field access includes
                 // the null check and if a field is found, the offset is so small that this is
                 // never a valid access of an arbitrary address.
@@ -75,18 +76,9 @@
                     return cloneAsFieldAccess(field);
                 }
             }
-
-            if (constantOffset != 0 && Integer.MAX_VALUE - displacement() >= constantOffset) {
-                int intDisplacement = (int) (constantOffset + displacement());
-                if (constantOffset == intDisplacement) {
-                    return cloneWithZeroOffset(intDisplacement);
-                }
-            }
         }
         return this;
     }
 
     protected abstract ValueNode cloneAsFieldAccess(ResolvedJavaField field);
-
-    protected abstract ValueNode cloneWithZeroOffset(int intDisplacement);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeCastNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -58,7 +59,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         assert kind() == Kind.Object && object.kind() == Kind.Object;
 
         ObjectStamp my = (ObjectStamp) stamp();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeLoadNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -35,31 +35,33 @@
  * performed before the load.
  */
 public class UnsafeLoadNode extends UnsafeAccessNode implements Lowerable, Virtualizable {
+    @Input private LogicNode guardingCondition;
 
-    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, boolean nonNull) {
-        this(nonNull ? StampFactory.objectNonNull() : StampFactory.object(), object, displacement, offset, Kind.Object);
+    public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind) {
+        this(object, offset, accessKind, LocationIdentity.ANY_LOCATION, null);
     }
 
-    public UnsafeLoadNode(ValueNode object, int displacement, ValueNode offset, Kind accessKind) {
-        this(StampFactory.forKind(accessKind.getStackKind()), object, displacement, offset, accessKind);
+    public UnsafeLoadNode(ValueNode object, ValueNode offset, Kind accessKind, LocationIdentity locationIdentity, LogicNode condition) {
+        super(StampFactory.forKind(accessKind.getStackKind()), object, offset, accessKind, locationIdentity);
+        this.guardingCondition = condition;
     }
 
-    public UnsafeLoadNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, Kind accessKind) {
-        super(stamp, object, displacement, offset, accessKind);
+    public LogicNode getGuardingCondition() {
+        return guardingCondition;
     }
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
     public void virtualize(VirtualizerTool tool) {
         State state = tool.getObjectState(object());
         if (state != null && state.getState() == EscapeState.Virtual) {
-            ValueNode indexValue = tool.getReplacedValue(offset());
-            if (indexValue.isConstant()) {
-                long offset = indexValue.asConstant().asLong() + displacement();
+            ValueNode offsetValue = tool.getReplacedValue(offset());
+            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));
@@ -73,39 +75,34 @@
         return this.graph().add(new LoadFieldNode(object(), field));
     }
 
-    @Override
-    protected ValueNode cloneWithZeroOffset(int intDisplacement) {
-        return graph().add(new UnsafeLoadNode(this.stamp(), object(), intDisplacement, graph().unique(ConstantNode.forInt(0, graph())), accessKind()));
-    }
-
     @SuppressWarnings("unchecked")
     @NodeIntrinsic
-    public static <T> T load(Object object, @ConstantNodeParameter int displacement, long offset, @ConstantNodeParameter Kind kind) {
+    public static <T> T load(Object object, long offset, @ConstantNodeParameter Kind kind) {
         if (kind == Kind.Boolean) {
-            return (T) (Boolean) unsafe.getBoolean(object, displacement + offset);
+            return (T) (Boolean) unsafe.getBoolean(object, offset);
         }
         if (kind == Kind.Byte) {
-            return (T) (Byte) unsafe.getByte(object, displacement + offset);
+            return (T) (Byte) unsafe.getByte(object, offset);
         }
         if (kind == Kind.Short) {
-            return (T) (Short) unsafe.getShort(object, displacement + offset);
+            return (T) (Short) unsafe.getShort(object, offset);
         }
         if (kind == Kind.Char) {
-            return (T) (Character) unsafe.getChar(object, displacement + offset);
+            return (T) (Character) unsafe.getChar(object, offset);
         }
         if (kind == Kind.Int) {
-            return (T) (Integer) unsafe.getInt(object, displacement + offset);
+            return (T) (Integer) unsafe.getInt(object, offset);
         }
         if (kind == Kind.Float) {
-            return (T) (Float) unsafe.getFloat(object, displacement + offset);
+            return (T) (Float) unsafe.getFloat(object, offset);
         }
         if (kind == Kind.Long) {
-            return (T) (Long) unsafe.getLong(object, displacement + offset);
+            return (T) (Long) unsafe.getLong(object, offset);
         }
         if (kind == Kind.Double) {
-            return (T) (Double) unsafe.getDouble(object, displacement + offset);
+            return (T) (Double) unsafe.getDouble(object, offset);
         }
         assert kind == Kind.Object;
-        return (T) unsafe.getObject(object, displacement + offset);
+        return (T) unsafe.getObject(object, offset);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/UnsafeStoreNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -39,12 +39,12 @@
     @Input private ValueNode value;
     @Input(notDataflow = true) private FrameState stateAfter;
 
-    public UnsafeStoreNode(ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind accessKind) {
-        this(StampFactory.forVoid(), object, displacement, offset, value, accessKind);
+    public UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind) {
+        this(object, offset, value, accessKind, LocationIdentity.ANY_LOCATION);
     }
 
-    public UnsafeStoreNode(Stamp stamp, ValueNode object, int displacement, ValueNode offset, ValueNode value, Kind accessKind) {
-        super(stamp, object, displacement, offset, accessKind);
+    public UnsafeStoreNode(ValueNode object, ValueNode offset, ValueNode value, Kind accessKind, LocationIdentity locationIdentity) {
+        super(StampFactory.forVoid(), object, offset, accessKind, locationIdentity);
         assert accessKind != Kind.Void && accessKind != Kind.Illegal;
         this.value = value;
     }
@@ -69,12 +69,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
-    }
-
-    @Override
-    public LocationIdentity getLocationIdentity() {
-        return LocationIdentity.ANY_LOCATION;
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
@@ -83,7 +78,7 @@
         if (state != null && state.getState() == EscapeState.Virtual) {
             ValueNode indexValue = tool.getReplacedValue(offset());
             if (indexValue.isConstant()) {
-                long offset = indexValue.asConstant().asLong() + displacement();
+                long offset = indexValue.asConstant().asLong();
                 int entryIndex = state.getVirtualObject().entryIndexForOffset(offset);
                 if (entryIndex != -1 && state.getVirtualObject().entryKind(entryIndex) == accessKind()) {
                     tool.setVirtualEntry(state, entryIndex, value());
@@ -100,13 +95,6 @@
         return storeFieldNode;
     }
 
-    @Override
-    protected ValueNode cloneWithZeroOffset(int intDisplacement) {
-        UnsafeStoreNode unsafeStoreNode = graph().add(new UnsafeStoreNode(stamp(), object(), intDisplacement, ConstantNode.forInt(0, graph()), value(), accessKind()));
-        unsafeStoreNode.setStateAfter(stateAfter());
-        return unsafeStoreNode;
-    }
-
     public FrameState getState() {
         return stateAfter;
     }
@@ -115,55 +103,55 @@
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, Object value, @ConstantNodeParameter Kind kind) {
-        unsafe.putObject(object, offset + displacement, value);
+    public static void store(Object object, long offset, Object value, @ConstantNodeParameter Kind kind) {
+        unsafe.putObject(object, offset, value);
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, boolean value, @ConstantNodeParameter Kind kind) {
-        unsafe.putBoolean(object, offset + displacement, value);
+    public static void store(Object object, long offset, boolean value, @ConstantNodeParameter Kind kind) {
+        unsafe.putBoolean(object, offset, value);
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, byte value, @ConstantNodeParameter Kind kind) {
-        unsafe.putByte(object, offset + displacement, value);
+    public static void store(Object object, long offset, byte value, @ConstantNodeParameter Kind kind) {
+        unsafe.putByte(object, offset, value);
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, char value, @ConstantNodeParameter Kind kind) {
-        unsafe.putChar(object, offset + displacement, value);
+    public static void store(Object object, long offset, char value, @ConstantNodeParameter Kind kind) {
+        unsafe.putChar(object, offset, value);
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, double value, @ConstantNodeParameter Kind kind) {
-        unsafe.putDouble(object, offset + displacement, value);
+    public static void store(Object object, long offset, double value, @ConstantNodeParameter Kind kind) {
+        unsafe.putDouble(object, offset, value);
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, float value, @ConstantNodeParameter Kind kind) {
-        unsafe.putFloat(object, offset + displacement, value);
+    public static void store(Object object, long offset, float value, @ConstantNodeParameter Kind kind) {
+        unsafe.putFloat(object, offset, value);
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, int value, @ConstantNodeParameter Kind kind) {
-        unsafe.putInt(object, offset + displacement, value);
+    public static void store(Object object, long offset, int value, @ConstantNodeParameter Kind kind) {
+        unsafe.putInt(object, offset, value);
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, long value, @ConstantNodeParameter Kind kind) {
-        unsafe.putLong(object, offset + displacement, value);
+    public static void store(Object object, long offset, long value, @ConstantNodeParameter Kind kind) {
+        unsafe.putLong(object, offset, value);
     }
 
     @SuppressWarnings("unused")
     @NodeIntrinsic
-    public static void store(Object object, @ConstantNodeParameter int displacement, long offset, short value, @ConstantNodeParameter Kind kind) {
-        unsafe.putShort(object, offset + displacement, value);
+    public static void store(Object object, long offset, short value, @ConstantNodeParameter Kind kind) {
+        unsafe.putShort(object, offset, value);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ValueAnchorNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,7 @@
 package com.oracle.graal.nodes.extended;
 
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -30,7 +31,7 @@
 /**
  * The ValueAnchor instruction keeps non-CFG (floating) nodes above a certain point in the graph.
  */
-public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, IterableNodeType, Virtualizable, GuardingNode {
+public final class ValueAnchorNode extends FixedWithNextNode implements Canonicalizable, LIRLowerable, Virtualizable, GuardingNode {
 
     @Input private ValueNode anchored;
 
@@ -49,7 +50,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (anchored != null && !anchored.isConstant() && !(anchored instanceof FixedNode)) {
             // Found entry that needs this anchor.
             return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewArrayNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,8 @@
  */
 package com.oracle.graal.nodes.java;
 
-import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -76,7 +77,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (usages().isEmpty()) {
             Stamp stamp = length.stamp();
             if (stamp instanceof IntegerStamp && ((IntegerStamp) stamp).isPositive()) {
@@ -88,16 +89,11 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
     public boolean canDeoptimize() {
         return true;
     }
-
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return DeoptimizationReason.RuntimeConstraint;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessFieldNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -84,7 +84,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessIndexedNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -65,6 +65,6 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ArrayLengthNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.nodes.java;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -44,8 +46,8 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        ValueNode length = readArrayLength(array(), tool.runtime());
+    public Node canonical(CanonicalizerTool tool) {
+        ValueNode length = readArrayLength(array(), tool.getConstantReflection());
         if (length != null) {
             return length;
         }
@@ -58,17 +60,17 @@
      * @param array an array
      * @return a node representing the length of {@code array} or null if it is not available
      */
-    public static ValueNode readArrayLength(ValueNode array, MetaAccessProvider runtime) {
+    public static ValueNode readArrayLength(ValueNode array, ConstantReflectionProvider constantReflection) {
         if (array instanceof ArrayLengthProvider) {
             ValueNode length = ((ArrayLengthProvider) array).length();
             if (length != null) {
                 return length;
             }
         }
-        if (runtime != null && array.isConstant() && !array.isNullConstant()) {
+        if (constantReflection != null && array.isConstant() && !array.isNullConstant()) {
             Constant constantValue = array.asConstant();
             if (constantValue != null && constantValue.isNonNull()) {
-                Integer constantLength = runtime.lookupArrayLength(constantValue);
+                Integer constantLength = constantReflection.lookupArrayLength(constantValue);
                 if (constantLength != null) {
                     return ConstantNode.forInt(constantLength, array.graph());
                 }
@@ -79,7 +81,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @NodeIntrinsic
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastDynamicNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.nodes.java;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -59,7 +61,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
@@ -68,7 +70,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         assert object() != null : this;
 
         if (ObjectStamp.isObjectAlwaysNull(object())) {
@@ -76,7 +78,7 @@
         }
         if (hub.isConstant() && hub.kind() == Kind.Object && hub.asConstant().asObject() instanceof Class) {
             Class clazz = (Class) hub.asConstant().asObject();
-            ResolvedJavaType t = tool.runtime().lookupJavaType(clazz);
+            ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz);
             return graph().add(new CheckCastNode(t, object(), null, forStoreCheck));
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CheckCastNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,14 +22,14 @@
  */
 package com.oracle.graal.nodes.java;
 
-import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -136,7 +136,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         assert object() != null : this;
 
         ResolvedJavaType objectType = ObjectStamp.typeOrNull(object());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -79,7 +79,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     // specialized on value type until boxing/unboxing is sorted out in intrinsification
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,8 +25,9 @@
 import java.lang.reflect.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 /**
@@ -51,11 +52,11 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (elementType.isConstant()) {
             Class<?> elementClass = (Class<?>) elementType.asConstant().asObject();
             if (elementClass != null && !(elementClass.equals(void.class))) {
-                ResolvedJavaType javaType = tool.runtime().lookupJavaType(elementClass);
+                ResolvedJavaType javaType = tool.getMetaAccess().lookupJavaType(elementClass);
                 return graph().add(new NewArrayNode(javaType, length(), fillContents()));
             }
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/ExceptionObjectNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -38,8 +39,8 @@
  */
 public class ExceptionObjectNode extends DispatchBeginNode implements Lowerable, MemoryCheckpoint.Single {
 
-    public ExceptionObjectNode(MetaAccessProvider runtime) {
-        super(StampFactory.declaredNonNull(runtime.lookupJavaType(Throwable.class)));
+    public ExceptionObjectNode(MetaAccessProvider metaAccess) {
+        super(StampFactory.declaredNonNull(metaAccess.lookupJavaType(Throwable.class)));
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfDynamicNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.nodes.java;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -51,15 +53,15 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         assert object() != null : this;
         if (mirror().isConstant()) {
             Class clazz = (Class) mirror().asConstant().asObject();
-            ResolvedJavaType t = tool.runtime().lookupJavaType(clazz);
+            ResolvedJavaType t = tool.getMetaAccess().lookupJavaType(clazz);
             return graph().unique(new InstanceOfNode(t, object(), null));
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/InstanceOfNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.nodes.java;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -52,11 +54,11 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
-    public LogicNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         Stamp stamp = object().stamp();
         if (!(stamp instanceof ObjectStamp)) {
             return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadExceptionObjectNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -45,6 +45,6 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadFieldNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -36,7 +37,7 @@
  * The {@code LoadFieldNode} represents a read of a static or instance field.
  */
 @NodeInfo(nameTemplate = "LoadField#{p#field/s}")
-public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, IterableNodeType, VirtualizableRoot {
+public final class LoadFieldNode extends AccessFieldNode implements Canonicalizable, VirtualizableRoot {
 
     /**
      * Creates a new LoadFieldNode instance.
@@ -58,8 +59,8 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        MetaAccessProvider runtime = tool.runtime();
+    public Node canonical(CanonicalizerTool tool) {
+        MetaAccessProvider runtime = tool.getMetaAccess();
         if (tool.canonicalizeReads() && runtime != null) {
             ConstantNode constant = asConstant(runtime);
             if (constant != null) {
@@ -76,7 +77,7 @@
     /**
      * Gets a constant value for this load if possible.
      */
-    public ConstantNode asConstant(MetaAccessProvider runtime) {
+    public ConstantNode asConstant(MetaAccessProvider metaAccess) {
         Constant constant = null;
         if (isStatic()) {
             constant = field().readConstantValue(null);
@@ -84,12 +85,12 @@
             constant = field().readConstantValue(object().asConstant());
         }
         if (constant != null) {
-            return ConstantNode.forConstant(constant, runtime, graph());
+            return ConstantNode.forConstant(constant, metaAccess, graph());
         }
         return null;
     }
 
-    private PhiNode asPhi(MetaAccessProvider runtime) {
+    private PhiNode asPhi(MetaAccessProvider metaAccess) {
         if (!isStatic() && Modifier.isFinal(field.getModifiers()) && object() instanceof PhiNode && ((PhiNode) object()).values().filter(NodePredicates.isNotA(ConstantNode.class)).isEmpty()) {
             PhiNode phi = (PhiNode) object();
             Constant[] constants = new Constant[phi.valueCount()];
@@ -102,7 +103,7 @@
             }
             PhiNode newPhi = graph().addWithoutUnique(new PhiNode(stamp(), phi.merge()));
             for (int i = 0; i < phi.valueCount(); i++) {
-                newPhi.addInput(ConstantNode.forConstant(constants[i], runtime, graph()));
+                newPhi.addInput(ConstantNode.forConstant(constants[i], metaAccess, graph()));
             }
             return newPhi;
         }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoadIndexedNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,7 +23,6 @@
 package com.oracle.graal.nodes.java;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -31,7 +30,7 @@
 /**
  * The {@code LoadIndexedNode} represents a read from an element of an array.
  */
-public final class LoadIndexedNode extends AccessIndexedNode implements IterableNodeType, Virtualizable {
+public final class LoadIndexedNode extends AccessIndexedNode implements Virtualizable {
 
     /**
      * Creates a new LoadIndexedNode.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,8 +26,8 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 public class MethodCallTargetNode extends CallTargetNode implements IterableNodeType, Canonicalizable {
@@ -125,7 +125,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (!isStatic()) {
             ValueNode receiver = receiver();
             if (receiver != null && ObjectStamp.isExactType(receiver) && ObjectStamp.typeOrNull(receiver) != null) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorEnterNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -51,7 +51,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public int getLockDepth() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -52,7 +52,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public int getLockDepth() {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewInstanceNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -68,7 +69,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (usages().isEmpty()) {
             return null;
         } else {
@@ -78,7 +79,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
@@ -100,9 +101,4 @@
     public boolean canDeoptimize() {
         return true;
     }
-
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return DeoptimizationReason.RuntimeConstraint;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/NewMultiArrayNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -63,7 +63,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     public ResolvedJavaType type() {
@@ -74,9 +74,4 @@
     public boolean canDeoptimize() {
         return true;
     }
-
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return DeoptimizationReason.RuntimeConstraint;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RegisterFinalizerNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,8 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -50,12 +52,12 @@
 
     @Override
     public void generate(LIRGeneratorTool gen) {
-        ForeignCallLinkage linkage = gen.getRuntime().lookupForeignCall(REGISTER_FINALIZER);
+        ForeignCallLinkage linkage = gen.getCodeCache().lookupForeignCall(REGISTER_FINALIZER);
         gen.emitForeignCall(linkage, this, gen.operand(object()));
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (!(object.stamp() instanceof ObjectStamp)) {
             return this;
         }
@@ -105,11 +107,6 @@
         deoptState = f;
     }
 
-    @Override
-    public DeoptimizationReason getDeoptimizationReason() {
-        return null;
-    }
-
     @SuppressWarnings("unused")
     @NodeIntrinsic
     public static void register(Object thisObj) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/TypeSwitchNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ResolvedJavaType.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
@@ -85,7 +86,7 @@
             for (int i = 0; i < keyCount(); i++) {
                 Constant typeHub = keyAt(i);
                 assert constant.getKind() == typeHub.getKind();
-                if (tool.runtime().constantEquals(constant, typeHub)) {
+                if (tool.getConstantReflection().constantEquals(constant, typeHub)) {
                     survivingEdge = keySuccessorIndex(i);
                 }
             }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Canonicalizable.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.spi;
-
-import com.oracle.graal.nodes.*;
-
-public interface Canonicalizable {
-
-    ValueNode canonical(CanonicalizerTool tool);
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/CanonicalizerTool.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.spi;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-
-public interface CanonicalizerTool {
-
-    Assumptions assumptions();
-
-    MetaAccessProvider runtime();
-
-    boolean canonicalizeReads();
-
-    void removeIfUnused(Node node);
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/DelegatingGraalCodeCacheProvider.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.spi;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-
-/**
- * A {@link GraalCodeCacheProvider} that delegates to another {@link GraalCodeCacheProvider}.
- */
-public class DelegatingGraalCodeCacheProvider extends DelegatingCodeCacheProvider implements GraalCodeCacheProvider {
-
-    public DelegatingGraalCodeCacheProvider(CodeCacheProvider delegate) {
-        super(delegate);
-    }
-
-    @Override
-    protected GraalCodeCacheProvider delegate() {
-        return (GraalCodeCacheProvider) super.delegate();
-    }
-
-    public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph) {
-        return delegate().addMethod(method, compResult, graph);
-    }
-
-    public void lower(Node n, LoweringTool tool) {
-        delegate().lower(n, tool);
-    }
-
-    public ValueNode reconstructArrayIndex(LocationNode location) {
-        return delegate().reconstructArrayIndex(location);
-    }
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/GraalCodeCacheProvider.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.nodes.spi;
-
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-
-/**
- * Graal-specific extensions for the code cache provider interface.
- */
-public interface GraalCodeCacheProvider extends CodeCacheProvider {
-
-    /**
-     * Adds the given compilation result as an implementation of the given method without making it
-     * the default implementation. The graph might be inlined later on.
-     * 
-     * @param method a method to which the executable code is begin added
-     * @param compResult the compilation result to be added
-     * @param graph the graph that represents the method
-     * @return a reference to the compiled and ready-to-run code or null if the code installation
-     *         failed
-     */
-    InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, Graph graph);
-
-    void lower(Node n, LoweringTool tool);
-
-    /**
-     * Reconstructs the array index from a location node that was created as a lowering of an indexed
-     * access to an array.
-     * 
-     * @param location a location pointing to an element in an array
-     * @return a node that gives the index of the element
-     */
-    ValueNode reconstructArrayIndex(LocationNode location);
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java	Fri Oct 11 17:21:14 2013 +0200
@@ -33,7 +33,9 @@
 
     TargetDescription target();
 
-    CodeCacheProvider getRuntime();
+    MetaAccessProvider getMetaAccess();
+
+    CodeCacheProvider getCodeCache();
 
     /**
      * Checks whether the supplied constant can be used without loading it into a register for most
@@ -63,7 +65,7 @@
 
     void emitMembar(int barriers);
 
-    void emitDeoptimize(DeoptimizationAction action, DeoptimizingNode deopting);
+    void emitDeoptimize(Value actionAndReason, DeoptimizingNode deopting);
 
     void emitNullCheck(ValueNode v, DeoptimizingNode deopting);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringProvider.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.spi;
+
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+
+/**
+ * Provides a capability for replacing a higher node with one or more lower level nodes.
+ */
+public interface LoweringProvider {
+
+    void lower(Node n, LoweringTool tool);
+
+    /**
+     * Reconstructs the array index from a location node that was created as a lowering of an
+     * indexed access to an array.
+     * 
+     * @param location a location pointing to an element in an array
+     * @return a node that gives the index of the element
+     */
+    ValueNode reconstructArrayIndex(LocationNode location);
+}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringTool.java	Fri Oct 11 17:21:14 2013 +0200
@@ -31,7 +31,13 @@
 
 public interface LoweringTool {
 
-    GraalCodeCacheProvider getRuntime();
+    MetaAccessProvider getMetaAccess();
+
+    CodeCacheProvider getCodeCache();
+
+    LoweringProvider getLowerer();
+
+    ConstantReflectionProvider getConstantReflection();
 
     Replacements getReplacements();
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/NodeWithState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java	Fri Oct 11 17:21:14 2013 +0200
@@ -30,5 +30,5 @@
  */
 public interface ReplacementsProvider {
 
-    void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target);
+    void registerReplacements(MetaAccessProvider metaAccess, Replacements replacements, TargetDescription target);
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Simplifiable.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +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.nodes.spi;
-
-/**
- * This interface allows nodes to perform more complicated simplifications, in contrast to
- * {@link Canonicalizable}, which supports only replacing the current node.
- * 
- * Implementors of this interface need to be aware that they need to call
- * {@link SimplifierTool#addToWorkList(com.oracle.graal.graph.Node)} for each node that might be
- * influenced (in terms of simplification and canonicalization) by the actions performed in
- * simplify.
- */
-public interface Simplifiable {
-
-    void simplify(SimplifierTool tool);
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/SimplifierTool.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +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.nodes.spi;
-
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-
-/**
- * @see Simplifiable
- */
-public interface SimplifierTool extends CanonicalizerTool {
-
-    void deleteBranch(FixedNode branch);
-
-    /**
-     * Adds a node to the worklist independent of whether it has already been on the worklist.
-     */
-    void addToWorkList(Node node);
-}
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/Virtualizable.java	Fri Oct 11 17:21:14 2013 +0200
@@ -34,7 +34,7 @@
 public interface Virtualizable {
 
     public static enum EscapeState {
-        Virtual, ThreadLocal, Global
+        Virtual, Materialized
     }
 
     public abstract static class State {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/VirtualizerTool.java	Fri Oct 11 17:21:14 2013 +0200
@@ -87,15 +87,6 @@
      */
     void setVirtualEntry(State state, int index, ValueNode value);
 
-    /**
-     * Queries the current state of the given value: if it was materialized or not.
-     * 
-     * @param value the value whose state should be queried.
-     * @return the materialized value (usually a MaterializeObjectNode or a {@link PhiNode}) if it
-     *         was materialized, null otherwise.
-     */
-    ValueNode getMaterializedValue(ValueNode value);
-
     // scalar replacement
 
     /**
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/FloatStamp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -92,12 +92,6 @@
     }
 
     @Override
-    public boolean alwaysDistinct(Stamp otherStamp) {
-        FloatStamp other = (FloatStamp) otherStamp;
-        return (nonNaN || other.nonNaN) && (lowerBound > other.upperBound || upperBound < other.lowerBound);
-    }
-
-    @Override
     public Stamp meet(Stamp otherStamp) {
         if (otherStamp == this) {
             return this;
@@ -183,4 +177,16 @@
         return true;
     }
 
+    @Override
+    public Constant asConstant() {
+        if (nonNaN && lowerBound == upperBound) {
+            switch (kind()) {
+                case Float:
+                    return Constant.forFloat((float) lowerBound);
+                case Double:
+                    return Constant.forDouble(lowerBound);
+            }
+        }
+        return null;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -40,11 +40,6 @@
     }
 
     @Override
-    public boolean alwaysDistinct(Stamp other) {
-        return true;
-    }
-
-    @Override
     public Stamp meet(Stamp other) {
         return other;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IntegerStamp.java	Fri Oct 11 17:21:14 2013 +0200
@@ -145,21 +145,6 @@
         return str.toString();
     }
 
-    @Override
-    public boolean alwaysDistinct(Stamp otherStamp) {
-        IntegerStamp other = (IntegerStamp) otherStamp;
-        if (lowerBound > other.upperBound || upperBound < other.lowerBound) {
-            return true;
-        } else if ((upMask & other.upMask) == 0 && (lowerBound > 0 || upperBound < 0 || other.lowerBound > 0 || other.upperBound < 0)) {
-            /*
-             * Zero is the only common value if the masks don't overlap. If one of the two values is
-             * less than or greater than zero, they are always distinct.
-             */
-            return true;
-        }
-        return false;
-    }
-
     private Stamp createStamp(IntegerStamp other, long newUpperBound, long newLowerBound, long newDownMask, long newUpMask) {
         assert kind() == other.kind();
         if (newLowerBound > newUpperBound || (newDownMask & (~newUpMask)) != 0) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampFactory.java	Fri Oct 11 17:21:14 2013 +0200
@@ -168,10 +168,10 @@
         }
     }
 
-    public static Stamp forConstant(Constant value, MetaAccessProvider runtime) {
+    public static Stamp forConstant(Constant value, MetaAccessProvider metaAccess) {
         assert value.getKind() == Kind.Object;
         if (value.getKind() == Kind.Object) {
-            ResolvedJavaType type = value.isNull() ? null : runtime.lookupJavaType(value);
+            ResolvedJavaType type = value.isNull() ? null : metaAccess.lookupJavaType(value);
             return new ObjectStamp(type, value.isNonNull(), value.isNonNull(), value.isNull());
         } else {
             throw new GraalInternalError(Kind.Object + " expected, actual kind: %s", value.getKind());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/util/GraphUtil.java	Fri Oct 11 17:21:14 2013 +0200
@@ -43,7 +43,7 @@
         }
     };
 
-    public static void killCFG(FixedNode node) {
+    public static void killCFG(Node node) {
         assert node.isAlive();
         if (node instanceof AbstractEndNode) {
             // We reached a control flow end.
@@ -58,7 +58,7 @@
              * while processing one branch.
              */
             for (Node successor : node.successors()) {
-                killCFG((FixedNode) successor);
+                killCFG(successor);
             }
         }
         propagateKill(node);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/CommitAllocationNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,6 +26,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -66,7 +67,7 @@
 
     @Override
     public void lower(LoweringTool tool) {
-        tool.getRuntime().lower(this, tool);
+        tool.getLowerer().lower(this, tool);
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/virtual/EscapeObjectState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,10 +22,9 @@
  */
 package com.oracle.graal.nodes.virtual;
 
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
-public abstract class EscapeObjectState extends VirtualState implements IterableNodeType {
+public abstract class EscapeObjectState extends VirtualState {
 
     @Input private VirtualObjectNode object;
 
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -29,9 +29,9 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Graph.NodeChangedListener;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
@@ -53,7 +53,7 @@
 
     public interface CustomCanonicalizer {
 
-        ValueNode canonicalize(ValueNode node);
+        Node canonicalize(Node node);
     }
 
     public CanonicalizerPhase(boolean canonicalizeReads) {
@@ -67,7 +67,7 @@
 
     @Override
     protected void run(StructuredGraph graph, PhaseContext context) {
-        new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, customCanonicalizer).run(graph);
+        new Instance(context, canonicalizeReads, customCanonicalizer).run(graph);
     }
 
     /**
@@ -79,7 +79,7 @@
     }
 
     public void applyIncremental(StructuredGraph graph, PhaseContext context, int newNodesMark, boolean dumpGraph) {
-        new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, newNodesMark, customCanonicalizer).apply(graph, dumpGraph);
+        new Instance(context, canonicalizeReads, newNodesMark, customCanonicalizer).apply(graph, dumpGraph);
     }
 
     /**
@@ -91,7 +91,7 @@
     }
 
     public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<Node> workingSet, boolean dumpGraph) {
-        new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, workingSet, customCanonicalizer).apply(graph, dumpGraph);
+        new Instance(context, canonicalizeReads, workingSet, customCanonicalizer).apply(graph, dumpGraph);
     }
 
     public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<Node> workingSet, int newNodesMark) {
@@ -99,19 +99,18 @@
     }
 
     public void applyIncremental(StructuredGraph graph, PhaseContext context, Iterable<Node> workingSet, int newNodesMark, boolean dumpGraph) {
-        new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, workingSet, newNodesMark, customCanonicalizer).apply(graph, dumpGraph);
+        new Instance(context, canonicalizeReads, workingSet, newNodesMark, customCanonicalizer).apply(graph, dumpGraph);
     }
 
     @Deprecated
     public void addToPhasePlan(PhasePlan plan, PhaseContext context) {
-        plan.addPhase(PhasePosition.AFTER_PARSING, new Instance(context.getRuntime(), context.getAssumptions(), canonicalizeReads, customCanonicalizer));
+        plan.addPhase(PhasePosition.AFTER_PARSING, new Instance(context, canonicalizeReads, customCanonicalizer));
     }
 
     private static final class Instance extends Phase {
 
         private final int newNodesMark;
-        private final Assumptions assumptions;
-        private final MetaAccessProvider runtime;
+        private final PhaseContext context;
         private final CustomCanonicalizer customCanonicalizer;
         private final Iterable<Node> initWorkingSet;
         private final boolean canonicalizeReads;
@@ -119,23 +118,22 @@
         private NodeWorkList workList;
         private Tool tool;
 
-        private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) {
-            this(runtime, assumptions, canonicalizeReads, null, 0, customCanonicalizer);
+        private Instance(PhaseContext context, boolean canonicalizeReads, CustomCanonicalizer customCanonicalizer) {
+            this(context, canonicalizeReads, null, 0, customCanonicalizer);
         }
 
-        private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable<Node> workingSet, CustomCanonicalizer customCanonicalizer) {
-            this(runtime, assumptions, canonicalizeReads, workingSet, 0, customCanonicalizer);
+        private Instance(PhaseContext context, boolean canonicalizeReads, Iterable<Node> workingSet, CustomCanonicalizer customCanonicalizer) {
+            this(context, canonicalizeReads, workingSet, 0, customCanonicalizer);
         }
 
-        private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, int newNodesMark, CustomCanonicalizer customCanonicalizer) {
-            this(runtime, assumptions, canonicalizeReads, null, newNodesMark, customCanonicalizer);
+        private Instance(PhaseContext context, boolean canonicalizeReads, int newNodesMark, CustomCanonicalizer customCanonicalizer) {
+            this(context, canonicalizeReads, null, newNodesMark, customCanonicalizer);
         }
 
-        private Instance(MetaAccessProvider runtime, Assumptions assumptions, boolean canonicalizeReads, Iterable<Node> workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) {
+        private Instance(PhaseContext context, boolean canonicalizeReads, Iterable<Node> workingSet, int newNodesMark, CustomCanonicalizer customCanonicalizer) {
             super("Canonicalizer");
             this.newNodesMark = newNodesMark;
-            this.assumptions = assumptions;
-            this.runtime = runtime;
+            this.context = context;
             this.canonicalizeReads = canonicalizeReads;
             this.customCanonicalizer = customCanonicalizer;
             this.initWorkingSet = workingSet;
@@ -179,22 +177,23 @@
             if (node.isAlive()) {
                 METRIC_PROCESSED_NODES.increment();
 
-                if (tryGlobalValueNumbering(node)) {
+                NodeClass nodeClass = node.getNodeClass();
+                if (tryGlobalValueNumbering(node, nodeClass)) {
                     return;
                 }
                 StructuredGraph graph = (StructuredGraph) node.graph();
                 int mark = graph.getMark();
                 if (!tryKillUnused(node)) {
-                    if (!tryCanonicalize(node)) {
+                    if (!tryCanonicalize(node, nodeClass)) {
                         if (node instanceof ValueNode) {
                             ValueNode valueNode = (ValueNode) node;
                             boolean improvedStamp = tryInferStamp(valueNode);
                             Constant constant = valueNode.stamp().asConstant();
                             if (constant != null && !(node instanceof ConstantNode)) {
-                                performReplacement(valueNode, ConstantNode.forConstant(constant, runtime, valueNode.graph()));
+                                performReplacement(valueNode, ConstantNode.forConstant(constant, context.getMetaAccess(), valueNode.graph()));
                             } else if (improvedStamp) {
                                 // the improved stamp may enable additional canonicalization
-                                tryCanonicalize(valueNode);
+                                tryCanonicalize(valueNode, nodeClass);
                             }
                         }
                     }
@@ -214,8 +213,7 @@
             return false;
         }
 
-        public static boolean tryGlobalValueNumbering(Node node) {
-            NodeClass nodeClass = node.getNodeClass();
+        public static boolean tryGlobalValueNumbering(Node node, NodeClass nodeClass) {
             if (nodeClass.valueNumberable() && !nodeClass.isLeafNode()) {
                 Node newNode = node.graph().findDuplicate(node);
                 if (newNode != null) {
@@ -230,34 +228,33 @@
             return false;
         }
 
-        public boolean tryCanonicalize(final Node node) {
-            boolean result = baseTryCanonicalize(node);
-            if (!result && customCanonicalizer != null && node instanceof ValueNode) {
-                ValueNode valueNode = (ValueNode) node;
-                ValueNode canonical = customCanonicalizer.canonicalize(valueNode);
+        public boolean tryCanonicalize(final Node node, NodeClass nodeClass) {
+            boolean result = baseTryCanonicalize(node, nodeClass);
+            if (!result && customCanonicalizer != null) {
+                Node canonical = customCanonicalizer.canonicalize(node);
                 result = performReplacement(node, canonical);
             }
             return result;
         }
 
-        public boolean baseTryCanonicalize(final Node node) {
-            if (node instanceof Canonicalizable) {
-                assert !(node instanceof Simplifiable);
+        public boolean baseTryCanonicalize(final Node node, NodeClass nodeClass) {
+            if (nodeClass.isCanonicalizable()) {
+                assert !nodeClass.isSimplifiable();
                 METRIC_CANONICALIZATION_CONSIDERED_NODES.increment();
                 return Debug.scope("CanonicalizeNode", node, new Callable<Boolean>() {
 
                     public Boolean call() {
-                        ValueNode canonical = ((Canonicalizable) node).canonical(tool);
+                        Node canonical = node.canonical(tool);
                         return performReplacement(node, canonical);
                     }
                 });
-            } else if (node instanceof Simplifiable) {
+            } else if (nodeClass.isSimplifiable()) {
                 Debug.log("Canonicalizer: simplifying %s", node);
                 METRIC_SIMPLIFICATION_CONSIDERED_NODES.increment();
                 Debug.scope("SimplifyNode", node, new Runnable() {
 
                     public void run() {
-                        ((Simplifiable) node).simplify(tool);
+                        node.simplify(tool);
                     }
                 });
             }
@@ -280,7 +277,7 @@
 //                                         --------------------------------------------
 //       X: must not happen (checked with assertions)
 // @formatter:on
-        private boolean performReplacement(final Node node, ValueNode canonical) {
+        private boolean performReplacement(final Node node, Node canonical) {
             if (canonical == node) {
                 Debug.log("Canonicalizer: work on %s", node);
                 return false;
@@ -362,7 +359,7 @@
         private final class Tool implements SimplifierTool {
 
             @Override
-            public void deleteBranch(FixedNode branch) {
+            public void deleteBranch(Node branch) {
                 branch.predecessor().replaceFirstSuccessor(branch, null);
                 GraphUtil.killCFG(branch);
             }
@@ -373,12 +370,17 @@
              */
             @Override
             public Assumptions assumptions() {
-                return assumptions;
+                return context.getAssumptions();
             }
 
             @Override
-            public MetaAccessProvider runtime() {
-                return runtime;
+            public MetaAccessProvider getMetaAccess() {
+                return context.getMetaAccess();
+            }
+
+            @Override
+            public ConstantReflectionProvider getConstantReflection() {
+                return context.getConstantReflection();
             }
 
             @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -52,12 +52,12 @@
     private static final DebugMetric metricObjectEqualsRemoved = Debug.metric("ObjectEqualsRemoved");
     private static final DebugMetric metricGuardsRemoved = Debug.metric("GuardsRemoved");
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
 
     private StructuredGraph graph;
 
-    public ConditionalEliminationPhase(MetaAccessProvider metaAccessProvider) {
-        this.metaAccessProvider = metaAccessProvider;
+    public ConditionalEliminationPhase(MetaAccessProvider metaAccess) {
+        this.metaAccess = metaAccess;
     }
 
     @Override
@@ -510,8 +510,8 @@
                     }
                     PiNode piNode;
                     if (isNull) {
-                        ConstantNode nullObject = ConstantNode.forObject(null, metaAccessProvider, graph);
-                        piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccessProvider), replacementAnchor.asNode()));
+                        ConstantNode nullObject = ConstantNode.forObject(null, metaAccess, graph);
+                        piNode = graph.unique(new PiNode(nullObject, StampFactory.forConstant(nullObject.value, metaAccess), replacementAnchor.asNode()));
                     } else {
                         piNode = graph.unique(new PiNode(object, StampFactory.declared(type, nonNull), replacementAnchor.asNode()));
                     }
@@ -523,6 +523,23 @@
                     }
                     metricCheckCastRemoved.increment();
                 }
+            } else if (node instanceof ConditionAnchorNode) {
+                ConditionAnchorNode conditionAnchorNode = (ConditionAnchorNode) node;
+                LogicNode condition = conditionAnchorNode.condition();
+                ValueNode replacementAnchor = null;
+                if (conditionAnchorNode.isNegated()) {
+                    if (state.falseConditions.containsKey(condition)) {
+                        replacementAnchor = state.falseConditions.get(condition);
+                    }
+                } else {
+                    if (state.trueConditions.containsKey(condition)) {
+                        replacementAnchor = state.trueConditions.get(condition);
+                    }
+                }
+                if (replacementAnchor != null) {
+                    conditionAnchorNode.replaceAtUsages(replacementAnchor);
+                    conditionAnchorNode.graph().removeFixed(conditionAnchorNode);
+                }
             } else if (node instanceof IfNode) {
                 IfNode ifNode = (IfNode) node;
                 LogicNode compare = ifNode.condition();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,23 +24,26 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.tiers.*;
 
 /**
- * This phase tries to find {@link DeoptimizeNode DeoptimizeNodes} which use the same
+ * This phase tries to find {@link AbstractDeoptimizeNode DeoptimizeNodes} which use the same
  * {@link FrameState} and merges them together.
  */
-public class DeoptimizationGroupingPhase extends Phase {
+public class DeoptimizationGroupingPhase extends BasePhase<MidTierContext> {
 
     @Override
-    protected void run(StructuredGraph graph) {
+    protected void run(StructuredGraph graph, MidTierContext context) {
         ControlFlowGraph cfg = null;
         for (FrameState fs : graph.getNodes(FrameState.class)) {
             FixedNode target = null;
-            List<DeoptimizeNode> obsoletes = null;
-            for (DeoptimizeNode deopt : fs.usages().filter(DeoptimizeNode.class)) {
+            PhiNode phi = null;
+            List<AbstractDeoptimizeNode> obsoletes = null;
+            for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) {
                 if (target == null) {
                     target = deopt;
                 } else {
@@ -48,34 +51,41 @@
                         cfg = ControlFlowGraph.compute(graph, true, true, false, false);
                     }
                     MergeNode merge;
-                    if (target instanceof DeoptimizeNode) {
+                    if (target instanceof AbstractDeoptimizeNode) {
                         merge = graph.add(new MergeNode());
                         EndNode firstEnd = graph.add(new EndNode());
+                        phi = graph.addWithoutUnique(new PhiNode(Kind.Int, merge));
                         merge.addForwardEnd(firstEnd);
+                        phi.addInput(((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess()));
                         target.predecessor().replaceFirstSuccessor(target, firstEnd);
-                        exitLoops((DeoptimizeNode) target, firstEnd, cfg);
-                        merge.setNext(target);
+
+                        exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg);
+
+                        merge.setNext(graph.add(new DynamicDeoptimizeNode(phi)));
                         obsoletes = new LinkedList<>();
+                        obsoletes.add((AbstractDeoptimizeNode) target);
                         target = merge;
                     } else {
                         merge = (MergeNode) target;
                     }
                     EndNode newEnd = graph.add(new EndNode());
                     merge.addForwardEnd(newEnd);
+                    phi.addInput(deopt.getActionAndReason(context.getMetaAccess()));
                     deopt.predecessor().replaceFirstSuccessor(deopt, newEnd);
                     exitLoops(deopt, newEnd, cfg);
                     obsoletes.add(deopt);
                 }
             }
             if (obsoletes != null) {
-                for (DeoptimizeNode obsolete : obsoletes) {
+                ((DynamicDeoptimizeNode) ((MergeNode) target).next()).setDeoptimizationState(fs);
+                for (AbstractDeoptimizeNode obsolete : obsoletes) {
                     obsolete.safeDelete();
                 }
             }
         }
     }
 
-    private static void exitLoops(DeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) {
+    private static void exitLoops(AbstractDeoptimizeNode deopt, EndNode end, ControlFlowGraph cfg) {
         Block block = cfg.blockFor(deopt);
         Loop loop = block.getLoop();
         while (loop != null) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/EliminatePartiallyRedundantGuardsPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,7 +25,6 @@
 import java.util.*;
 import java.util.Map.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,7 +27,6 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.extended.*;
@@ -42,7 +41,7 @@
         ANALYSIS_ONLY, CREATE_FLOATING_READS
     }
 
-    public static class MemoryMapImpl implements MemoryMap<Node> {
+    public static class MemoryMapImpl extends MemoryMapNode {
 
         private IdentityHashMap<LocationIdentity, ValueNode> lastMemorySnapshot;
 
@@ -74,11 +73,6 @@
             }
         }
 
-        @Override
-        public String toString() {
-            return "Map=" + lastMemorySnapshot.toString();
-        }
-
         public boolean isEmpty() {
             if (lastMemorySnapshot.size() == 0) {
                 return true;
@@ -92,7 +86,7 @@
         }
 
         public Set<LocationIdentity> getLocations() {
-            return new HashSet<>(lastMemorySnapshot.keySet());
+            return lastMemorySnapshot.keySet();
         }
 
     }
@@ -192,7 +186,7 @@
             assert MemoryCheckpoint.TypeAssertion.correctType(node) : node;
 
             if (execmode == ExecutionMode.ANALYSIS_ONLY && node instanceof ReturnNode) {
-                node.graph().add(new MemoryState(new MemoryMapImpl(state), node));
+                ((ReturnNode) node).setMemoryMap(node.graph().unique(new MemoryMapImpl(state)));
             }
             return state;
         }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IncrementalCanonicalizerPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -30,6 +30,10 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
 
+/**
+ * A phase suite that applies {@linkplain CanonicalizerPhase canonicalization} to a graph after all
+ * phases in the suite have been applied if any of the phases changed the graph.
+ */
 public class IncrementalCanonicalizerPhase<C extends PhaseContext> extends PhaseSuite<C> {
 
     private final CanonicalizerPhase canonicalizer;
@@ -58,6 +62,8 @@
         graph.stopTrackingInputChange();
         graph.stopTrackingUsagesDroppedZero();
 
-        canonicalizer.applyIncremental(graph, context, changedNodes, newNodesMark, false);
+        if (graph.getMark() != newNodesMark || !changedNodes.isEmpty()) {
+            canonicalizer.applyIncremental(graph, context, changedNodes, newNodesMark, false);
+        }
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -173,7 +173,7 @@
         if (inliningPolicy.isWorthInlining(context.getReplacements(), callee, inliningDepth, calleeInfo.probability(), calleeInfo.relevance(), true)) {
             doInline(callerGraphInfo, calleeInfo, callerAssumptions, context);
         } else if (context.getOptimisticOptimizations().devirtualizeInvokes()) {
-            callee.tryToDevirtualizeInvoke(context.getRuntime(), callerAssumptions);
+            callee.tryToDevirtualizeInvoke(context.getMetaAccess(), callerAssumptions);
         }
         metricInliningConsidered.increment();
     }
@@ -184,7 +184,7 @@
         InlineInfo callee = calleeInfo.callee();
         try {
             List<Node> invokeUsages = callee.invoke().asNode().usages().snapshot();
-            callee.inline(context.getRuntime(), callerAssumptions, context.getReplacements());
+            callee.inline(context, callerAssumptions);
             callerAssumptions.record(calleeInfo.assumptions());
             metricInliningRuns.increment();
             Debug.dump(callerGraph, "after %s", callee);
@@ -258,7 +258,7 @@
                     ValueNode arg = args.get(localNode.index());
                     if (arg.isConstant()) {
                         Constant constant = arg.asConstant();
-                        newGraph.replaceFloating(localNode, ConstantNode.forConstant(constant, context.getRuntime(), newGraph));
+                        newGraph.replaceFloating(localNode, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph));
                         callerHasMoreInformationAboutArguments = true;
                     } else {
                         Stamp joinedStamp = localNode.stamp().join(arg.stamp());
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.phases.common;
 
-import static com.oracle.graal.api.code.DeoptimizationAction.*;
+import static com.oracle.graal.api.meta.DeoptimizationAction.*;
 import static com.oracle.graal.api.meta.DeoptimizationReason.*;
 import static com.oracle.graal.nodes.type.StampFactory.*;
 import static com.oracle.graal.phases.GraalOptions.*;
@@ -51,6 +51,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.InliningPhase.InliningData;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 public class InliningUtil {
 
@@ -292,13 +293,13 @@
          * Performs the inlining described by this object and returns the node that represents the
          * return value of the inlined method (or null for void methods and methods that have no
          * non-exceptional exit).
-         **/
-        void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements);
+         */
+        void inline(Providers providers, Assumptions assumptions);
 
         /**
          * Try to make the call static bindable to avoid interface and virtual method calls.
          */
-        void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions);
+        void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions);
     }
 
     public abstract static class AbstractInlineInfo implements InlineInfo {
@@ -367,12 +368,12 @@
         }
 
         @Override
-        public void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) {
+        public void inline(Providers providers, Assumptions assumptions) {
             inline(invoke, concrete, inlineableElement, assumptions, !suppressNullCheck);
         }
 
         @Override
-        public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) {
+        public void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions) {
             // nothing todo, can already be bound statically
         }
 
@@ -470,20 +471,20 @@
         }
 
         @Override
-        public void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) {
-            createGuard(graph(), runtime);
+        public void inline(Providers providers, Assumptions assumptions) {
+            createGuard(graph(), providers.getMetaAccess());
             inline(invoke, concrete, inlineableElement, assumptions, false);
         }
 
         @Override
-        public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) {
-            createGuard(graph(), runtime);
+        public void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions) {
+            createGuard(graph(), metaAccess);
             replaceInvokeCallTarget(invoke, graph(), InvokeKind.Special, concrete);
         }
 
-        private void createGuard(StructuredGraph graph, MetaAccessProvider runtime) {
+        private void createGuard(StructuredGraph graph, MetaAccessProvider metaAccess) {
             ValueNode nonNullReceiver = InliningUtil.nonNullReceiver(invoke);
-            ConstantNode typeHub = ConstantNode.forConstant(type.getEncoding(Representation.ObjectHub), runtime, graph);
+            ConstantNode typeHub = ConstantNode.forConstant(type.getEncoding(Representation.ObjectHub), metaAccess, graph);
             LoadHubNode receiverHub = graph.unique(new LoadHubNode(nonNullReceiver, typeHub.kind(), null));
 
             CompareNode typeCheck = CompareNode.createCompareNode(Condition.EQ, receiverHub, typeHub);
@@ -587,11 +588,11 @@
         }
 
         @Override
-        public void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) {
+        public void inline(Providers providers, Assumptions assumptions) {
             if (hasSingleMethod()) {
-                inlineSingleMethod(graph(), runtime, assumptions);
+                inlineSingleMethod(graph(), providers.getMetaAccess(), assumptions);
             } else {
-                inlineMultipleMethods(graph(), runtime, assumptions, replacements);
+                inlineMultipleMethods(graph(), providers, assumptions);
             }
         }
 
@@ -603,7 +604,7 @@
             return notRecordedTypeProbability > 0;
         }
 
-        private void inlineMultipleMethods(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) {
+        private void inlineMultipleMethods(StructuredGraph graph, Providers providers, Assumptions assumptions) {
             int numberOfMethods = concretes.size();
             FixedNode continuation = invoke.next();
 
@@ -658,7 +659,7 @@
             assert invoke.asNode().isAlive();
 
             // replace the invoke with a switch on the type of the actual receiver
-            boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, runtime);
+            boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, providers.getMetaAccess());
 
             assert invoke.next() == continuation;
             invoke.setNext(null);
@@ -713,8 +714,9 @@
                 if (opportunities > 0) {
                     metricInliningTailDuplication.increment();
                     Debug.log("MultiTypeGuardInlineInfo starting tail duplication (%d opportunities)", opportunities);
-                    TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, new PhaseContext(runtime, assumptions, replacements), new CanonicalizerPhase(
-                                    !AOTCompilation.getValue()));
+                    PhaseContext phaseContext = new PhaseContext(providers, assumptions);
+                    CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue());
+                    TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer);
                 }
             }
         }
@@ -752,21 +754,21 @@
             return result;
         }
 
-        private void inlineSingleMethod(StructuredGraph graph, MetaAccessProvider runtime, Assumptions assumptions) {
+        private void inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions) {
             assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
 
             AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
 
             AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
             AbstractBeginNode[] successors = new AbstractBeginNode[]{calleeEntryNode, unknownTypeSux};
-            createDispatchOnTypeBeforeInvoke(graph, successors, false, runtime);
+            createDispatchOnTypeBeforeInvoke(graph, successors, false, metaAccess);
 
             calleeEntryNode.setNext(invoke.asNode());
 
             inline(invoke, methodAt(0), inlineableElementAt(0), assumptions, false);
         }
 
-        private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider runtime) {
+        private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, AbstractBeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess) {
             assert ptypes.size() >= 1;
             ValueNode nonNullReceiver = nonNullReceiver(invoke);
             Kind hubKind = ((MethodCallTargetNode) invoke.callTarget()).targetMethod().getDeclaringClass().getEncoding(Representation.ObjectHub).getKind();
@@ -783,7 +785,7 @@
                     ResolvedJavaMethod firstMethod = concretes.get(i);
                     Constant firstMethodConstant = firstMethod.getEncoding();
 
-                    ValueNode firstMethodConstantNode = ConstantNode.forConstant(firstMethodConstant, runtime, graph);
+                    ValueNode firstMethodConstantNode = ConstantNode.forConstant(firstMethodConstant, metaAccess, graph);
                     constantMethods[i] = firstMethodConstantNode;
                     double concretesProbability = concretesProbabilities.get(i);
                     assert concretesProbability >= 0.0;
@@ -928,15 +930,15 @@
         }
 
         @Override
-        public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) {
+        public void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions) {
             if (hasSingleMethod()) {
-                devirtualizeWithTypeSwitch(graph(), InvokeKind.Special, concretes.get(0), runtime);
+                devirtualizeWithTypeSwitch(graph(), InvokeKind.Special, concretes.get(0), metaAccess);
             } else {
-                tryToDevirtualizeMultipleMethods(graph(), runtime);
+                tryToDevirtualizeMultipleMethods(graph(), metaAccess);
             }
         }
 
-        private void tryToDevirtualizeMultipleMethods(StructuredGraph graph, MetaAccessProvider runtime) {
+        private void tryToDevirtualizeMultipleMethods(StructuredGraph graph, MetaAccessProvider metaAccess) {
             MethodCallTargetNode methodCallTarget = (MethodCallTargetNode) invoke.callTarget();
             if (methodCallTarget.invokeKind() == InvokeKind.Interface) {
                 ResolvedJavaMethod targetMethod = methodCallTarget.targetMethod();
@@ -947,17 +949,17 @@
                 if (!leastCommonType.isInterface() && targetMethod.getDeclaringClass().isAssignableFrom(leastCommonType)) {
                     ResolvedJavaMethod baseClassTargetMethod = leastCommonType.resolveMethod(targetMethod);
                     if (baseClassTargetMethod != null) {
-                        devirtualizeWithTypeSwitch(graph, InvokeKind.Virtual, leastCommonType.resolveMethod(targetMethod), runtime);
+                        devirtualizeWithTypeSwitch(graph, InvokeKind.Virtual, leastCommonType.resolveMethod(targetMethod), metaAccess);
                     }
                 }
             }
         }
 
-        private void devirtualizeWithTypeSwitch(StructuredGraph graph, InvokeKind kind, ResolvedJavaMethod target, MetaAccessProvider runtime) {
+        private void devirtualizeWithTypeSwitch(StructuredGraph graph, InvokeKind kind, ResolvedJavaMethod target, MetaAccessProvider metaAccess) {
             AbstractBeginNode invocationEntry = graph.add(new BeginNode());
             AbstractBeginNode unknownTypeSux = createUnknownTypeSuccessor(graph);
             AbstractBeginNode[] successors = new AbstractBeginNode[]{invocationEntry, unknownTypeSux};
-            createDispatchOnTypeBeforeInvoke(graph, successors, true, runtime);
+            createDispatchOnTypeBeforeInvoke(graph, successors, true, metaAccess);
 
             invocationEntry.setNext(invoke.asNode());
             ValueNode receiver = ((MethodCallTargetNode) invoke.callTarget()).receiver();
@@ -1006,13 +1008,13 @@
         }
 
         @Override
-        public void inline(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) {
+        public void inline(Providers providers, Assumptions assumptions) {
             assumptions.record(takenAssumption);
-            super.inline(runtime, assumptions, replacements);
+            super.inline(providers, assumptions);
         }
 
         @Override
-        public void tryToDevirtualizeInvoke(MetaAccessProvider runtime, Assumptions assumptions) {
+        public void tryToDevirtualizeInvoke(MetaAccessProvider metaAccess, Assumptions assumptions) {
             assumptions.record(takenAssumption);
             replaceInvokeCallTarget(invoke, graph(), InvokeKind.Special, concrete);
         }
@@ -1363,6 +1365,13 @@
             } else {
                 invokeWithException.killExceptionEdge();
             }
+
+            // get rid of memory kill
+            AbstractBeginNode begin = invokeWithException.next();
+            if (begin instanceof KillingBeginNode) {
+                graph.addAfterFixed(begin, graph.add(new BeginNode()));
+                graph.removeFixed(begin);
+            }
         } else {
             if (unwindNode != null) {
                 UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/IterativeConditionalEliminationPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,8 +24,8 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.util.*;
 import com.oracle.graal.phases.tiers.*;
@@ -42,7 +42,7 @@
 
     @Override
     protected void run(StructuredGraph graph, PhaseContext context) {
-        ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(context.getRuntime());
+        ConditionalEliminationPhase eliminate = new ConditionalEliminationPhase(context.getMetaAccess());
         HashSetNodeChangeListener listener = new HashSetNodeChangeListener();
         int count = 0;
         while (true) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -63,8 +63,23 @@
         }
 
         @Override
-        public GraalCodeCacheProvider getRuntime() {
-            return (GraalCodeCacheProvider) context.getRuntime();
+        public CodeCacheProvider getCodeCache() {
+            return context.getCodeCache();
+        }
+
+        @Override
+        public ConstantReflectionProvider getConstantReflection() {
+            return context.getConstantReflection();
+        }
+
+        @Override
+        public MetaAccessProvider getMetaAccess() {
+            return context.getMetaAccess();
+        }
+
+        @Override
+        public LoweringProvider getLowerer() {
+            return context.getLowerer();
         }
 
         @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/PhiStampPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.phases.common;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.phases.*;
-
-public class PhiStampPhase extends Phase {
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        // Infer phis stopping at loop phis.
-        for (PhiNode phi : graph.getNodes(PhiNode.class)) {
-            inferPhi(phi);
-        }
-
-        // Start iterative inference for loop phis.
-        if (graph.hasLoops()) {
-            for (PhiNode phi : graph.getNodes(PhiNode.class)) {
-                if (phi.isLoopPhi()) {
-                    iterativeInferPhi(phi);
-                }
-            }
-        }
-    }
-
-    private void iterativeInferPhi(PhiNode phi) {
-        if (phi.inferPhiStamp()) {
-            for (PhiNode phiUsage : phi.usages().filter(PhiNode.class)) {
-                iterativeInferPhi(phiUsage);
-            }
-        }
-    }
-
-    private void inferPhi(PhiNode phi) {
-        for (PhiNode phiInput : phi.values().filter(PhiNode.class)) {
-            if (!phiInput.isLoopPhi()) {
-                inferPhi(phiInput);
-            }
-        }
-        phi.inferPhiStamp();
-    }
-}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -36,6 +36,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.phases.tiers.*;
@@ -172,6 +173,9 @@
         int fixedCount = 0;
         while (fixed instanceof FixedWithNextNode) {
             fixed = ((FixedWithNextNode) fixed).next();
+            if (fixed instanceof CommitAllocationNode) {
+                return false;
+            }
             fixedCount++;
         }
         if (fixedCount > 1) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -70,8 +70,6 @@
     @Option(help = "")
     public static final OptionValue<Boolean> PartialEscapeAnalysis = new OptionValue<>(true);
     @Option(help = "")
-    public static final OptionValue<Boolean> EscapeAnalysisHistogram = new OptionValue<>(false);
-    @Option(help = "")
     public static final OptionValue<Integer> EscapeAnalysisIterations = new OptionValue<>(2);
     @Option(help = "")
     public static final OptionValue<String> EscapeAnalyzeOnly = new OptionValue<>(null);
@@ -167,6 +165,8 @@
     @Option(help = "")
     public static final OptionValue<Boolean> PrintCompilation = new OptionValue<>(false);
     @Option(help = "")
+    public static final OptionValue<Boolean> PrintAfterCompilation = new OptionValue<>(false);
+    @Option(help = "")
     public static final OptionValue<Boolean> PrintProfilingInformation = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> PrintIRWithLIR = new OptionValue<>(false);
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhaseSuite.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/PhaseSuite.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,6 +26,9 @@
 
 import com.oracle.graal.nodes.*;
 
+/**
+ * A compiler phase that can apply an ordered collection of phases to a graph.
+ */
 public class PhaseSuite<C> extends BasePhase<C> {
 
     private final List<BasePhase<? super C>> phases;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ComputeProbabilityClosure.java	Fri Oct 11 17:21:14 2013 +0200
@@ -77,8 +77,8 @@
     private void adjustControlSplitProbabilities() {
         HashSet<ControlSplitNode> result = new HashSet<>();
         NodeBitMap visitedNodes = new NodeBitMap(graph);
-        for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) {
-            if (n.action().doesInvalidateCompilation()) {
+        for (AbstractDeoptimizeNode n : graph.getNodes(AbstractDeoptimizeNode.class)) {
+            if (!(n instanceof DeoptimizeNode) || ((DeoptimizeNode) n).action().doesInvalidateCompilation()) {
                 findParentControlSplitNodes(result, n, visitedNodes);
             }
         }
@@ -90,7 +90,7 @@
         }
     }
 
-    private static void findParentControlSplitNodes(HashSet<ControlSplitNode> result, DeoptimizeNode n, NodeBitMap visitedNodes) {
+    private static void findParentControlSplitNodes(HashSet<ControlSplitNode> result, AbstractDeoptimizeNode n, NodeBitMap visitedNodes) {
         ArrayDeque<FixedNode> nodes = new ArrayDeque<>();
         nodes.push(n);
 
@@ -142,9 +142,9 @@
 
     private boolean verifyProbabilities() {
         if (doesNotAlwaysDeopt(graph)) {
-            for (DeoptimizeNode n : graph.getNodes(DeoptimizeNode.class)) {
-                if (n.action().doesInvalidateCompilation() && nodeProbabilities.get(n) > 0.01) {
-                    throw new AssertionError(String.format("%s with reason %s and probability %f in graph %s", n, n.reason(), nodeProbabilities.get(n), graph));
+            for (AbstractDeoptimizeNode n : graph.getNodes(AbstractDeoptimizeNode.class)) {
+                if (nodeProbabilities.get(n) > 0.01 && (!(n instanceof DeoptimizeNode) || ((DeoptimizeNode) n).action().doesInvalidateCompilation())) {
+                    throw new AssertionError(String.format("%s with probability %f in graph %s", n, nodeProbabilities.get(n), graph));
                 }
             }
         }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -33,6 +33,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.Verbosity;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.extended.*;
@@ -99,7 +100,7 @@
 
         @Override
         protected HashSet<FloatingReadNode> processBlock(Block block, HashSet<FloatingReadNode> currentState) {
-            for (Node node : getBlockToNodesMap().get(block)) {
+            for (Node node : blockToNodesMap.get(block)) {
                 if (node instanceof FloatingReadNode) {
                     currentState.add((FloatingReadNode) node);
                 } else if (node instanceof MemoryCheckpoint.Single) {
@@ -183,37 +184,49 @@
 
         @Override
         protected Map<LocationIdentity, Node> processBlock(Block block, Map<LocationIdentity, Node> currentState) {
-            Map<LocationIdentity, Node> initKillMap = getBlockToKillMap().get(block);
-            initKillMap.putAll(currentState);
+
+            if (block.getBeginNode() instanceof MergeNode) {
+                MergeNode mergeNode = (MergeNode) block.getBeginNode();
+                for (PhiNode phi : mergeNode.usages().filter(PhiNode.class)) {
+                    if (phi.type() == PhiType.Memory) {
+                        LocationIdentity identity = (LocationIdentity) phi.getIdentity();
+                        locationKilledBy(identity, phi, currentState);
+                    }
+                }
+            }
+            currentState.putAll(blockToKillMapInit.get(block));
 
             for (Node node : block.getNodes()) {
                 if (node instanceof MemoryCheckpoint.Single) {
                     LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
-                    initKillMap.put(identity, node);
+                    locationKilledBy(identity, node, currentState);
                 } else if (node instanceof MemoryCheckpoint.Multi) {
                     for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
-                        initKillMap.put(identity, node);
+                        locationKilledBy(identity, node, currentState);
                     }
                 }
                 assert MemoryCheckpoint.TypeAssertion.correctType(node);
             }
 
-            return cloneState(initKillMap);
+            blockToKillMap.put(block, currentState);
+            return cloneState(currentState);
+        }
+
+        private void locationKilledBy(LocationIdentity identity, Node checkpoint, Map<LocationIdentity, Node> state) {
+            state.put(identity, checkpoint);
+            if (identity == ANY_LOCATION) {
+                for (LocationIdentity locid : state.keySet()) {
+                    state.put(locid, checkpoint);
+                }
+            }
         }
 
         @Override
         protected Map<LocationIdentity, Node> merge(Block merge, List<Map<LocationIdentity, Node>> states) {
-            return merge(merge, states, false);
-        }
-
-        protected Map<LocationIdentity, Node> merge(Block merge, List<Map<LocationIdentity, Node>> states, boolean loopbegin) {
             assert merge.getBeginNode() instanceof MergeNode;
             MergeNode mergeNode = (MergeNode) merge.getBeginNode();
 
             Map<LocationIdentity, Node> initKillMap = new HashMap<>();
-            if (loopbegin) {
-                initKillMap.putAll(getBlockToKillMap().get(merge));
-            }
             for (Map<LocationIdentity, Node> state : states) {
                 for (LocationIdentity locid : state.keySet()) {
                     if (initKillMap.containsKey(locid)) {
@@ -226,10 +239,7 @@
                 }
             }
 
-            getMergeToKillMap().set(mergeNode, cloneState(initKillMap));
-            if (!loopbegin) {
-                initKillMap.putAll(getBlockToKillMap().get(merge));
-            }
+            mergeToKillMap.set(mergeNode, cloneState(initKillMap));
             return initKillMap;
         }
 
@@ -240,18 +250,27 @@
 
         @Override
         protected List<Map<LocationIdentity, Node>> processLoop(Loop loop, Map<LocationIdentity, Node> state) {
-            LoopInfo<Map<LocationIdentity, Node>> info = ReentrantBlockIterator.processLoop(this, loop, new HashMap<>(state));
+            LoopInfo<Map<LocationIdentity, Node>> info = ReentrantBlockIterator.processLoop(this, loop, cloneState(state));
 
             assert loop.header.getBeginNode() instanceof LoopBeginNode;
-            Map<LocationIdentity, Node> headerState = merge(loop.header, info.endStates, true);
-            getBlockToKillMap().put(loop.header, headerState);
+            Map<LocationIdentity, Node> headerState = merge(loop.header, info.endStates);
+            // second iteration, for computing information at loop exits
+            info = ReentrantBlockIterator.processLoop(this, loop, cloneState(headerState));
+
+            int i = 0;
+            for (Block exit : loop.exits) {
+                Map<LocationIdentity, Node> exitState = info.exitStates.get(i++);
 
-            for (Map<LocationIdentity, Node> exitState : info.exitStates) {
-                for (LocationIdentity key : headerState.keySet()) {
-                    exitState.put(key, headerState.get(key));
+                Node begin = exit.getBeginNode();
+                assert begin instanceof LoopExitNode;
+                for (Node usage : begin.usages()) {
+                    if (usage instanceof ProxyNode && ((ProxyNode) usage).type() == PhiType.Memory) {
+                        ProxyNode proxy = (ProxyNode) usage;
+                        LocationIdentity identity = (LocationIdentity) proxy.getIdentity();
+                        locationKilledBy(identity, proxy, exitState);
+                    }
                 }
             }
-
             return info.exitStates;
         }
     }
@@ -263,6 +282,7 @@
      * Map from blocks to the nodes in each block.
      */
     private BlockMap<List<ScheduledNode>> blockToNodesMap;
+    private BlockMap<Map<LocationIdentity, Node>> blockToKillMapInit;
     private BlockMap<Map<LocationIdentity, Node>> blockToKillMap;
     private NodeMap<Map<LocationIdentity, Node>> mergeToKillMap;
     private final Map<FloatingNode, List<FixedNode>> phantomUsages = new IdentityHashMap<>();
@@ -315,8 +335,10 @@
         } else if (memsched == MemoryScheduling.OPTIMAL && selectedStrategy != SchedulingStrategy.EARLIEST && graph.getNodes(FloatingReadNode.class).isNotEmpty()) {
             mergeToKillMap = graph.createNodeMap();
 
+            blockToKillMapInit = new BlockMap<>(cfg);
             blockToKillMap = new BlockMap<>(cfg);
             for (Block b : cfg.getBlocks()) {
+                blockToKillMapInit.put(b, new HashMap<LocationIdentity, Node>());
                 blockToKillMap.put(b, new HashMap<LocationIdentity, Node>());
             }
 
@@ -328,7 +350,7 @@
                 Node first = n.lastLocationAccess();
                 assert first != null;
 
-                Map<LocationIdentity, Node> killMap = blockToKillMap.get(forKillLocation(first));
+                Map<LocationIdentity, Node> killMap = blockToKillMapInit.get(forKillLocation(first));
                 killMap.put(n.location().getLocationIdentity(), first);
             }
 
@@ -357,20 +379,27 @@
     private void printSchedule(String desc) {
         Debug.printf("=== %s / %s / %s (%s) ===\n", getCFG().getStartBlock().getBeginNode().graph(), selectedStrategy, memsched, desc);
         for (Block b : getCFG().getBlocks()) {
-            Debug.printf("==== b: %s. ", b);
+            Debug.printf("==== b: %s (loopDepth: %s). ", b, b.getLoopDepth());
             Debug.printf("dom: %s. ", b.getDominator());
             Debug.printf("post-dom: %s. ", b.getPostdominator());
             Debug.printf("preds: %s. ", b.getPredecessors());
             Debug.printf("succs: %s ====\n", b.getSuccessors());
-            BlockMap<Map<LocationIdentity, Node>> killMaps = getBlockToKillMap();
+            BlockMap<Map<LocationIdentity, Node>> killMaps = blockToKillMap;
             if (killMaps != null) {
+                if (b.getBeginNode() instanceof MergeNode) {
+                    MergeNode merge = (MergeNode) b.getBeginNode();
+                    Debug.printf("M merge kills: \n");
+                    for (LocationIdentity locId : mergeToKillMap.get(merge).keySet()) {
+                        Debug.printf("M %s killed by %s\n", locId, mergeToKillMap.get(merge).get(locId));
+                    }
+                }
                 Debug.printf("X block kills: \n");
                 for (LocationIdentity locId : killMaps.get(b).keySet()) {
                     Debug.printf("X %s killed by %s\n", locId, killMaps.get(b).get(locId));
                 }
             }
 
-            if (getBlockToNodesMap().get(b) != null) {
+            if (blockToNodesMap.get(b) != null) {
                 for (Node n : nodesFor(b)) {
                     printNode(n);
                 }
@@ -414,14 +443,6 @@
         return blockToNodesMap;
     }
 
-    public BlockMap<Map<LocationIdentity, Node>> getBlockToKillMap() {
-        return blockToKillMap;
-    }
-
-    public NodeMap<Map<LocationIdentity, Node>> getMergeToKillMap() {
-        return mergeToKillMap;
-    }
-
     /**
      * Gets the nodes in a given block.
      */
@@ -465,10 +486,11 @@
             throw new SchedulingError("%s should already have been placed in a block", node);
         }
 
+        Block earliestBlock = earliestBlock(node);
         Block block;
         switch (strategy) {
             case EARLIEST:
-                block = earliestBlock(node);
+                block = earliestBlock;
                 break;
             case LATEST:
             case LATEST_OUT_OF_LOOPS:
@@ -477,23 +499,19 @@
                 } else {
                     block = latestBlock(node, strategy);
                     if (block == null) {
-                        block = earliestBlock(node);
+                        block = earliestBlock;
                     } else if (strategy == SchedulingStrategy.LATEST_OUT_OF_LOOPS && !(node instanceof VirtualObjectNode)) {
                         // schedule at the latest position possible in the outermost loop possible
-                        Block earliestBlock = earliestBlock(node);
-                        Block before = block;
                         block = scheduleOutOfLoops(node, block, earliestBlock);
-                        if (!earliestBlock.dominates(block)) {
-                            throw new SchedulingError("%s: Graph cannot be scheduled : inconsistent for %s, %d usages, (%s needs to dominate %s (before %s))", node.graph(), node,
-                                            node.usages().count(), earliestBlock, block, before);
-                        }
                     }
                 }
                 break;
             default:
                 throw new GraalInternalError("unknown scheduling strategy");
         }
-        assert earliestBlock(node).dominates(block) : "node " + node + " in block " + block + " is not dominated by earliest " + earliestBlock(node);
+        if (!earliestBlock.dominates(block)) {
+            throw new SchedulingError("%s: Graph cannot be scheduled : inconsistent for %s, %d usages, (%s needs to dominate %s)", node.graph(), node, node.usages().count(), earliestBlock, block);
+        }
         cfg.getNodeToBlock().set(node, block);
         blockToNodesMap.get(block).add(node);
     }
@@ -541,9 +559,8 @@
         // iterate the dominator tree
         while (true) {
             iterations++;
-            assert earliestBlock.dominates(previousBlock) : "iterations: " + iterations;
             Node lastKill = blockToKillMap.get(currentBlock).get(locid);
-            boolean isAtEarliest = earliestBlock == previousBlock && previousBlock != currentBlock;
+            assert lastKill != null : "should be never null, due to init of killMaps: " + currentBlock + ", location: " + locid;
 
             if (lastKill.equals(upperBound)) {
                 // assign node to the block which kills the location
@@ -553,7 +570,6 @@
                 // schedule read out of the loop if possible, in terms of killMaps and earliest
                 // schedule
                 if (currentBlock != earliestBlock && previousBlock != earliestBlock) {
-                    assert earliestBlock.dominates(currentBlock);
                     Block t = currentBlock;
                     while (t.getLoop() != null && t.getDominator() != null && earliestBlock.dominates(t)) {
                         Block dom = t.getDominator();
@@ -568,17 +584,12 @@
 
                 if (!outOfLoop && previousBlock.getBeginNode() instanceof MergeNode) {
                     // merges kill locations right at the beginning of a block. if a merge is the
-                    // killing node, we assign it to the dominating node.
+                    // killing node, we assign it to the dominating block.
 
                     MergeNode merge = (MergeNode) previousBlock.getBeginNode();
-                    Node killer = getMergeToKillMap().get(merge).get(locid);
+                    Node killer = mergeToKillMap.get(merge).get(locid);
 
                     if (killer != null && killer == merge) {
-                        // check if we violate earliest schedule condition
-                        if (isAtEarliest) {
-                            printIterations(iterations, "earliest bound in merge: " + earliestBlock);
-                            return earliestBlock;
-                        }
                         printIterations(iterations, "kill by merge: " + currentBlock);
                         return currentBlock;
                     }
@@ -590,11 +601,6 @@
                 return previousBlock;
             }
 
-            if (isAtEarliest) {
-                printIterations(iterations, "earliest bound: " + earliestBlock);
-                return earliestBlock;
-            }
-
             if (upperBoundBlock == currentBlock) {
                 printIterations(iterations, "upper bound: " + currentBlock + ", previous: " + previousBlock);
                 return currentBlock;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/HighTierContext.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,9 +23,9 @@
 package com.oracle.graal.phases.tiers;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
 
 public class HighTierContext extends PhaseContext {
 
@@ -34,8 +34,8 @@
     private final GraphCache cache;
     private final OptimisticOptimizations optimisticOpts;
 
-    public HighTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
-        super(runtime, assumptions, replacements);
+    public HighTierContext(Providers copyFrom, Assumptions assumptions, GraphCache cache, PhasePlan plan, OptimisticOptimizations optimisticOpts) {
+        super(copyFrom, assumptions);
         this.plan = plan;
         this.cache = cache;
         this.optimisticOpts = optimisticOpts;
@@ -54,6 +54,6 @@
     }
 
     public HighTierContext replaceAssumptions(Assumptions newAssumptions) {
-        return new HighTierContext(getRuntime(), newAssumptions, getReplacements(), getGraphCache(), getPhasePlan(), getOptimisticOptimizations());
+        return new HighTierContext(this, newAssumptions, getGraphCache(), getPhasePlan(), getOptimisticOptimizations());
     }
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/LowTierContext.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,15 +23,14 @@
 package com.oracle.graal.phases.tiers;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 
 public class LowTierContext extends PhaseContext {
 
     private final TargetDescription target;
 
-    public LowTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, TargetDescription target) {
-        super(runtime, assumptions, replacements);
+    public LowTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target) {
+        super(copyFrom, assumptions);
         this.target = target;
     }
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/MidTierContext.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,17 +23,16 @@
 package com.oracle.graal.phases.tiers;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.util.*;
 
 public class MidTierContext extends PhaseContext {
 
     private final TargetDescription target;
     private final OptimisticOptimizations optimisticOpts;
 
-    public MidTierContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements, TargetDescription target, OptimisticOptimizations optimisticOpts) {
-        super(runtime, assumptions, replacements);
+    public MidTierContext(Providers copyFrom, Assumptions assumptions, TargetDescription target, OptimisticOptimizations optimisticOpts) {
+        super(copyFrom, assumptions);
         this.target = target;
         this.optimisticOpts = optimisticOpts;
     }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/PhaseContext.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,28 +25,24 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 
-public class PhaseContext {
+public class PhaseContext extends Providers {
 
-    private final MetaAccessProvider runtime;
     private final Assumptions assumptions;
-    private final Replacements replacements;
 
-    public PhaseContext(MetaAccessProvider runtime, Assumptions assumptions, Replacements replacements) {
-        this.runtime = runtime;
+    public PhaseContext(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Assumptions assumptions,
+                    Replacements replacements) {
+        super(metaAccess, codeCache, constantReflection, lowerer, replacements);
         this.assumptions = assumptions;
-        this.replacements = replacements;
     }
 
-    public MetaAccessProvider getRuntime() {
-        return runtime;
+    public PhaseContext(Providers copyFrom, Assumptions assumptions) {
+        super(copyFrom);
+        this.assumptions = assumptions;
     }
 
     public Assumptions getAssumptions() {
         return assumptions;
     }
-
-    public Replacements getReplacements() {
-        return replacements;
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Providers.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.phases.util;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * A set of providers, some of which may not be present (i.e., null).
+ */
+public class Providers {
+
+    private final MetaAccessProvider metaAccess;
+    private final CodeCacheProvider codeCache;
+    private final LoweringProvider lowerer;
+    private final ConstantReflectionProvider constantReflection;
+    private final Replacements replacements;
+
+    public Providers(MetaAccessProvider metaAccess, CodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, LoweringProvider lowerer, Replacements replacements) {
+        this.metaAccess = metaAccess;
+        this.codeCache = codeCache;
+        this.constantReflection = constantReflection;
+        this.lowerer = lowerer;
+        this.replacements = replacements;
+    }
+
+    public Providers(Providers copyFrom) {
+        this.metaAccess = copyFrom.metaAccess;
+        this.codeCache = copyFrom.codeCache;
+        this.constantReflection = copyFrom.constantReflection;
+        this.lowerer = copyFrom.lowerer;
+        this.replacements = copyFrom.replacements;
+    }
+
+    public MetaAccessProvider getMetaAccess() {
+        return metaAccess;
+    }
+
+    public CodeCacheProvider getCodeCache() {
+        return codeCache;
+    }
+
+    public LoweringProvider getLowerer() {
+        return lowerer;
+    }
+
+    public ConstantReflectionProvider getConstantReflection() {
+        return constantReflection;
+    }
+
+    public Replacements getReplacements() {
+        return replacements;
+    }
+}
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Util.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/Util.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,9 +26,6 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
 
 /**
  * The {@code Util} class contains a motley collection of utility methods used throughout the
@@ -319,14 +316,6 @@
         return (short) v;
     }
 
-    public static boolean isFixed(Node n) {
-        return n instanceof FixedNode;
-    }
-
-    public static boolean isFloating(Node n) {
-        return n instanceof FloatingNode;
-    }
-
     /**
      * Creates an array of integers of length "size", in which each number from 0 to (size - 1)
      * occurs exactly once. The integers are sorted using the given comparator. This can be used to
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/verify/VerifyUsageWithEquals.java	Fri Oct 11 17:21:14 2013 +0200
@@ -42,9 +42,9 @@
         this.klass = klass;
     }
 
-    private boolean isAssignableType(ValueNode node, MetaAccessProvider runtime) {
+    private boolean isAssignableType(ValueNode node, MetaAccessProvider metaAccess) {
         if (node.stamp() instanceof ObjectStamp) {
-            ResolvedJavaType valueType = runtime.lookupJavaType(klass);
+            ResolvedJavaType valueType = metaAccess.lookupJavaType(klass);
             ResolvedJavaType nodeType = ObjectStamp.typeOrNull(node);
 
             if (nodeType != null && valueType.isAssignableFrom(nodeType)) {
@@ -58,8 +58,8 @@
         return node.isConstant() && node.asConstant().isNull();
     }
 
-    private boolean checkUsage(ValueNode x, ValueNode y, MetaAccessProvider runtime) {
-        return isAssignableType(x, runtime) && !isNullConstant(y);
+    private boolean checkUsage(ValueNode x, ValueNode y, MetaAccessProvider metaAccess) {
+        return isAssignableType(x, metaAccess) && !isNullConstant(y);
     }
 
     private static boolean isEqualsMethod(StructuredGraph graph) {
@@ -72,8 +72,8 @@
         for (ObjectEqualsNode cn : graph.getNodes().filter(ObjectEqualsNode.class)) {
             if (!isEqualsMethod(graph)) {
                 // bail out if we compare an object of type klass with == or != (except null checks)
-                assert !(checkUsage(cn.x(), cn.y(), context.getRuntime()) && checkUsage(cn.y(), cn.x(), context.getRuntime())) : "Verifcation of " + klass.getName() + " usage failed: Comparing " +
-                                cn.x() + " and " + cn.y() + " in " + graph.method() + " must use .equals() for object equality, not '==' or '!='";
+                assert !(checkUsage(cn.x(), cn.y(), context.getMetaAccess()) && checkUsage(cn.y(), cn.x(), context.getMetaAccess())) : "Verifcation of " + klass.getName() +
+                                " usage failed: Comparing " + cn.x() + " and " + cn.y() + " in " + graph.method() + " must use .equals() for object equality, not '==' or '!='";
             }
         }
         return true;
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java	Fri Oct 11 17:21:14 2013 +0200
@@ -144,9 +144,9 @@
             cfgPrinter.cfg = cfgPrinter.lir.cfg;
         }
 
-        CodeCacheProvider runtime = Debug.contextLookup(CodeCacheProvider.class);
-        if (runtime != null) {
-            cfgPrinter.target = runtime.getTarget();
+        CodeCacheProvider codeCache = Debug.contextLookup(CodeCacheProvider.class);
+        if (codeCache != null) {
+            cfgPrinter.target = codeCache.getTarget();
         }
 
         if (object instanceof BciBlockMapping) {
@@ -171,10 +171,10 @@
 
         } else if (object instanceof CompilationResult) {
             final CompilationResult compResult = (CompilationResult) object;
-            cfgPrinter.printMachineCode(runtime.disassemble(compResult, null), message);
+            cfgPrinter.printMachineCode(codeCache.disassemble(compResult, null), message);
         } else if (isCompilationResultAndInstalledCode(object)) {
             Object[] tuple = (Object[]) object;
-            cfgPrinter.printMachineCode(runtime.disassemble((CompilationResult) tuple[0], (InstalledCode) tuple[1]), message);
+            cfgPrinter.printMachineCode(codeCache.disassemble((CompilationResult) tuple[0], (InstalledCode) tuple[1]), message);
         } else if (object instanceof Interval[]) {
             cfgPrinter.printIntervals(message, (Interval[]) object);
 
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,9 +22,10 @@
  */
 package com.oracle.graal.replacements.amd64;
 
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.calc.ConvertNode.Op;
-import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
@@ -44,6 +45,12 @@
         this.value = value;
     }
 
+    public Constant evalConst(Constant... inputs) {
+        // this node should never have been created if its input is constant
+        assert false;
+        return null;
+    }
+
     public void generate(ArithmeticLIRGenerator gen) {
         gen.setResult(this, gen.emitConvert(opcode, gen.operand(value)));
     }
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64ConvertSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -28,12 +28,12 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.calc.ConvertNode.Op;
 import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
@@ -149,8 +149,8 @@
 
         private final EnumMap<Op, SnippetInfo> snippets;
 
-        public Templates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
 
             snippets = new EnumMap<>(Op.class);
             snippets.put(Op.F2I, snippet(AMD64ConvertSnippets.class, "f2i"));
@@ -180,7 +180,7 @@
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering %s in %s: node=%s, template=%s, arguments=%s", convert.opcode, graph, convert, template, args);
-            template.instantiate(runtime, replacee, DEFAULT_REPLACER, tool, args);
+            template.instantiate(providers.getMetaAccess(), replacee, DEFAULT_REPLACER, tool, args);
             graph.removeFloating(convert);
         }
     }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/MethodSubstitutionTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -44,14 +44,15 @@
 public abstract class MethodSubstitutionTest extends GraalCompilerTest {
 
     protected StructuredGraph test(final String snippet) {
-        return Debug.scope("MethodSubstitutionTest", runtime.lookupJavaMethod(getMethod(snippet)), new Callable<StructuredGraph>() {
+        return Debug.scope("MethodSubstitutionTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)), new Callable<StructuredGraph>() {
 
             @Override
             public StructuredGraph call() {
                 StructuredGraph graph = parse(snippet);
                 PhasePlan phasePlan = getDefaultPhasePlan();
                 Assumptions assumptions = new Assumptions(true);
-                HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, phasePlan, OptimisticOptimizations.ALL);
+                HighTierContext context = new HighTierContext(getProviders(), assumptions, null, phasePlan,
+                                OptimisticOptimizations.ALL);
                 Debug.dump(graph, "Graph");
                 new InliningPhase(new CanonicalizerPhase(true)).apply(graph, context);
                 Debug.dump(graph, "Graph");
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/NewMultiArrayTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -90,7 +90,7 @@
     public void test1() {
         for (Class clazz : new Class[]{byte.class, char.class, short.class, int.class, float.class, long.class, double.class, String.class}) {
             bottomClass = clazz;
-            bottomType = runtime.lookupJavaType(clazz);
+            bottomType = getMetaAccess().lookupJavaType(clazz);
             arrayType = bottomType;
             for (int rank : new int[]{1, 2, 10, 50, 100, 200, 254, 255}) {
                 while (rank(arrayType) != rank) {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -49,15 +49,15 @@
 
     public ObjectAccessTest() {
         target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new ReplacementsImpl(runtime, new Assumptions(false), target);
+        installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), new Assumptions(false), target);
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
 
     @Override
     protected StructuredGraph parse(Method m) {
-        ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m);
-        return installer.makeGraph(resolvedMethod, null, inliningPolicy.get());
+        ResolvedJavaMethod resolvedMethod = getMetaAccess().lookupJavaMethod(m);
+        return installer.makeGraph(resolvedMethod, null, inliningPolicy.get(), false);
     }
 
     @Test
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -53,15 +53,15 @@
 
     public PointerTest() {
         target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new ReplacementsImpl(runtime, new Assumptions(false), target);
+        installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), new Assumptions(false), target);
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
 
     @Override
     protected StructuredGraph parse(Method m) {
-        ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m);
-        return installer.makeGraph(resolvedMethod, null, inliningPolicy.get());
+        ResolvedJavaMethod resolvedMethod = getMetaAccess().lookupJavaMethod(m);
+        return installer.makeGraph(resolvedMethod, null, inliningPolicy.get(), false);
     }
 
     @Test
@@ -404,7 +404,7 @@
 
     private void assertNumWordCasts(String snippetName, int expectedWordCasts) {
         Assumptions assumptions = new Assumptions(true);
-        HighTierContext context = new HighTierContext(runtime(), assumptions, replacements, null, null, OptimisticOptimizations.ALL);
+        HighTierContext context = new HighTierContext(getProviders(), assumptions, null, null, OptimisticOptimizations.ALL);
 
         StructuredGraph graph = parse(snippetName);
         new CanonicalizerPhase(false).apply(graph, context);
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/TypeCheckTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -58,7 +58,7 @@
         }
         ProfiledType[] ptypes = new ProfiledType[types.length];
         for (int i = 0; i < types.length; i++) {
-            ptypes[i] = new ProfiledType(runtime.lookupJavaType(types[i]), 1.0D / types.length);
+            ptypes[i] = new ProfiledType(getMetaAccess().lookupJavaType(types[i]), 1.0D / types.length);
         }
         return new JavaTypeProfile(nullSeen, 0.0D, ptypes);
     }
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/WordTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -43,15 +43,15 @@
 
     public WordTest() {
         TargetDescription target = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
-        installer = new ReplacementsImpl(runtime, new Assumptions(false), target);
+        installer = new ReplacementsImpl(getMetaAccess(), getConstantReflection(), getCodeCache(), getLowerer(), new Assumptions(false), target);
     }
 
     private static final ThreadLocal<SnippetInliningPolicy> inliningPolicy = new ThreadLocal<>();
 
     @Override
     protected StructuredGraph parse(Method m) {
-        ResolvedJavaMethod resolvedMethod = runtime.lookupJavaMethod(m);
-        return installer.makeGraph(resolvedMethod, null, inliningPolicy.get());
+        ResolvedJavaMethod resolvedMethod = getMetaAccess().lookupJavaMethod(m);
+        return installer.makeGraph(resolvedMethod, null, inliningPolicy.get(), false);
     }
 
     @LongTest
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Fri Oct 11 17:21:14 2013 +0200
@@ -38,6 +38,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
@@ -172,27 +173,27 @@
         return value.shortValue();
     }
 
-    public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider runtime) {
+    public static FloatingNode canonicalizeBoxing(BoxNode box, MetaAccessProvider metaAccess) {
         ValueNode value = box.getValue();
         if (value.isConstant()) {
             Constant sourceConstant = value.asConstant();
             switch (box.getBoxingKind()) {
                 case Boolean:
-                    return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asInt() != 0), runtime, box.graph());
+                    return ConstantNode.forObject(Boolean.valueOf(sourceConstant.asInt() != 0), metaAccess, box.graph());
                 case Byte:
-                    return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), runtime, box.graph());
+                    return ConstantNode.forObject(Byte.valueOf((byte) sourceConstant.asInt()), metaAccess, box.graph());
                 case Char:
-                    return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), runtime, box.graph());
+                    return ConstantNode.forObject(Character.valueOf((char) sourceConstant.asInt()), metaAccess, box.graph());
                 case Short:
-                    return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), runtime, box.graph());
+                    return ConstantNode.forObject(Short.valueOf((short) sourceConstant.asInt()), metaAccess, box.graph());
                 case Int:
-                    return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), runtime, box.graph());
+                    return ConstantNode.forObject(Integer.valueOf(sourceConstant.asInt()), metaAccess, box.graph());
                 case Long:
-                    return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), runtime, box.graph());
+                    return ConstantNode.forObject(Long.valueOf(sourceConstant.asLong()), metaAccess, box.graph());
                 case Float:
-                    return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), runtime, box.graph());
+                    return ConstantNode.forObject(Float.valueOf(sourceConstant.asFloat()), metaAccess, box.graph());
                 case Double:
-                    return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), runtime, box.graph());
+                    return ConstantNode.forObject(Double.valueOf(sourceConstant.asDouble()), metaAccess, box.graph());
                 default:
                     assert false : "Unexpected source kind for boxing";
                     break;
@@ -206,8 +207,8 @@
         private final EnumMap<Kind, SnippetInfo> boxSnippets = new EnumMap<>(Kind.class);
         private final EnumMap<Kind, SnippetInfo> unboxSnippets = new EnumMap<>(Kind.class);
 
-        public Templates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
-            super(runtime, replacements, target);
+        public Templates(Providers providers, TargetDescription target) {
+            super(providers, target);
             for (Kind kind : new Kind[]{Kind.Boolean, Kind.Byte, Kind.Char, Kind.Double, Kind.Float, Kind.Int, Kind.Long, Kind.Short}) {
                 boxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "ValueOf"));
                 unboxSnippets.put(kind, snippet(BoxingSnippets.class, kind.getJavaName() + "Value"));
@@ -215,7 +216,7 @@
         }
 
         public void lower(BoxNode box, LoweringTool tool) {
-            FloatingNode canonical = canonicalizeBoxing(box, runtime);
+            FloatingNode canonical = canonicalizeBoxing(box, providers.getMetaAccess());
             // if in AOT mode, we don't want to embed boxed constants.
             if (canonical != null && !AOTCompilation.getValue()) {
                 box.graph().replaceFloating(box, canonical);
@@ -225,7 +226,7 @@
 
                 SnippetTemplate template = template(args);
                 Debug.log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", box.graph(), box, template, args);
-                template.instantiate(runtime, box, DEFAULT_REPLACER, tool, args);
+                template.instantiate(providers.getMetaAccess(), box, DEFAULT_REPLACER, tool, args);
                 GraphUtil.killWithUnusedFloatingInputs(box);
             }
         }
@@ -236,7 +237,7 @@
 
             SnippetTemplate template = template(args);
             Debug.log("Lowering integerValueOf in %s: node=%s, template=%s, arguments=%s", unbox.graph(), unbox, template, args);
-            template.instantiate(runtime, unbox, DEFAULT_REPLACER, tool, args);
+            template.instantiate(providers.getMetaAccess(), unbox, DEFAULT_REPLACER, tool, args);
             GraphUtil.killWithUnusedFloatingInputs(unbox);
         }
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/GraalMethodSubstitutions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -35,7 +35,7 @@
 @ServiceProvider(ReplacementsProvider.class)
 public class GraalMethodSubstitutions implements ReplacementsProvider {
 
-    public void registerReplacements(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
+    public void registerReplacements(MetaAccessProvider metaAccess, Replacements replacements, TargetDescription target) {
         for (Class<?> clazz : BoxingSubstitutions.getClasses()) {
             replacements.registerSubstitutions(clazz);
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/InstanceOfSnippetsTemplates.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,13 +27,13 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
 import com.oracle.graal.replacements.SnippetTemplate.UsageReplacer;
@@ -53,8 +53,8 @@
  */
 public abstract class InstanceOfSnippetsTemplates extends AbstractTemplates {
 
-    public InstanceOfSnippetsTemplates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
-        super(runtime, replacements, target);
+    public InstanceOfSnippetsTemplates(Providers providers, TargetDescription target) {
+        super(providers, target);
     }
 
     /**
@@ -77,7 +77,7 @@
                 replacer.replaceUsingInstantiation();
             } else {
                 Arguments args = makeArguments(replacer, tool);
-                template(args).instantiate(runtime, instanceOf, replacer, tool, args);
+                template(args).instantiate(providers.getMetaAccess(), instanceOf, replacer, tool, args);
             }
         }
 
@@ -206,7 +206,7 @@
         }
 
         @Override
-        public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap<Node> mmap) {
+        public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) {
             assert newNode instanceof PhiNode;
             assert oldNode == instanceOf;
             newNode.inferStamp();
@@ -238,7 +238,7 @@
         }
 
         @Override
-        public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap<Node> mmap) {
+        public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) {
             assert newNode instanceof PhiNode;
             assert oldNode == instanceOf;
             newNode.inferStamp();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeClassSubstitutions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -64,22 +64,22 @@
 
     @MethodSubstitution
     private static Node getNode(Node node, long offset) {
-        return PiNode.piCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), Node.class, false, false);
+        return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object), Node.class, false, false);
     }
 
     @MethodSubstitution
     private static NodeList getNodeList(Node node, long offset) {
-        return PiNode.piCast(UnsafeLoadNode.load(node, 0, offset, Kind.Object), NodeList.class, false, false);
+        return PiNode.piCast(UnsafeLoadNode.load(node, offset, Kind.Object), NodeList.class, false, false);
     }
 
     @MethodSubstitution
     private static void putNode(Node node, long offset, Node value) {
-        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
+        UnsafeStoreNode.store(node, offset, value, Kind.Object);
     }
 
     @MethodSubstitution
     private static void putNodeList(Node node, long offset, NodeList value) {
-        UnsafeStoreNode.store(node, 0, offset, value, Kind.Object);
+        UnsafeStoreNode.store(node, offset, value, Kind.Object);
     }
 
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -49,10 +49,10 @@
  */
 public class NodeIntrinsificationPhase extends Phase {
 
-    private final MetaAccessProvider runtime;
+    private final MetaAccessProvider metaAccess;
 
-    public NodeIntrinsificationPhase(MetaAccessProvider runtime) {
-        this.runtime = runtime;
+    public NodeIntrinsificationPhase(MetaAccessProvider metaAccess) {
+        this.metaAccess = metaAccess;
     }
 
     @Override
@@ -113,7 +113,7 @@
 
             if (constant != null) {
                 // Replace the invoke with the result of the call
-                ConstantNode node = ConstantNode.forConstant(constant, runtime, methodCallTargetNode.graph());
+                ConstantNode node = ConstantNode.forConstant(constant, metaAccess, methodCallTargetNode.graph());
                 methodCallTargetNode.invoke().intrinsify(node);
 
                 // Clean up checkcast instructions inserted by javac if the return type is generic.
@@ -158,8 +158,8 @@
                 Constant constant = constantNode.asConstant();
                 Object o = constant.asBoxedValue();
                 if (o instanceof Class<?>) {
-                    reflectionCallArguments[i] = Constant.forObject(runtime.lookupJavaType((Class<?>) o));
-                    parameterTypes[i] = runtime.lookupJavaType(ResolvedJavaType.class);
+                    reflectionCallArguments[i] = Constant.forObject(metaAccess.lookupJavaType((Class<?>) o));
+                    parameterTypes[i] = metaAccess.lookupJavaType(ResolvedJavaType.class);
                 } else {
                     if (parameterTypes[i].getKind() == Kind.Boolean) {
                         reflectionCallArguments[i] = Constant.forObject(Boolean.valueOf(constant.asInt() != 0));
@@ -175,7 +175,7 @@
                 }
             } else {
                 reflectionCallArguments[i] = Constant.forObject(argument);
-                parameterTypes[i] = runtime.lookupJavaType(ValueNode.class);
+                parameterTypes[i] = metaAccess.lookupJavaType(ValueNode.class);
             }
         }
         return reflectionCallArguments;
@@ -186,9 +186,9 @@
         if (intrinsic.value() == NodeIntrinsic.class) {
             result = target.getDeclaringClass();
         } else {
-            result = runtime.lookupJavaType(intrinsic.value());
+            result = metaAccess.lookupJavaType(intrinsic.value());
         }
-        assert runtime.lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + toJavaName(result, false) + " derived from @" + NodeIntrinsic.class.getSimpleName() +
+        assert metaAccess.lookupJavaType(ValueNode.class).isAssignableFrom(result) : "Node intrinsic class " + toJavaName(result, false) + " derived from @" + NodeIntrinsic.class.getSimpleName() +
                         " annotation on " + format("%H.%n(%p)", target) + " is not a subclass of " + ValueNode.class;
         return result;
     }
@@ -230,7 +230,7 @@
         boolean needsMetaAccessProviderArgument = false;
 
         ResolvedJavaType[] signature = MetaUtil.resolveJavaTypes(MetaUtil.signatureToTypes(c.getSignature(), null), c.getDeclaringClass());
-        if (signature.length != 0 && signature[0].equals(runtime.lookupJavaType(MetaAccessProvider.class))) {
+        if (signature.length != 0 && signature[0].equals(metaAccess.lookupJavaType(MetaAccessProvider.class))) {
             // Chop off the MetaAccessProvider first parameter
             signature = Arrays.copyOfRange(signature, 1, signature.length);
             needsMetaAccessProviderArgument = true;
@@ -273,7 +273,7 @@
         if (needsMetaAccessProviderArgument) {
             Constant[] copy = new Constant[arguments.length + 1];
             System.arraycopy(arguments, 0, copy, 1, arguments.length);
-            copy[0] = Constant.forObject(runtime);
+            copy[0] = Constant.forObject(metaAccess);
             arguments = copy;
         }
         return arguments;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Fri Oct 11 17:21:14 2013 +0200
@@ -45,13 +45,14 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.Snippet.DefaultSnippetInliningPolicy;
 import com.oracle.graal.replacements.Snippet.SnippetInliningPolicy;
 import com.oracle.graal.word.phases.*;
 
 public class ReplacementsImpl implements Replacements {
 
-    protected final MetaAccessProvider runtime;
+    protected final Providers providers;
     protected final TargetDescription target;
     protected final Assumptions assumptions;
 
@@ -67,8 +68,9 @@
     private final Set<ResolvedJavaMethod> forcedSubstitutions;
     private final Map<Class<? extends SnippetTemplateCache>, SnippetTemplateCache> snippetTemplateCache;
 
-    public ReplacementsImpl(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target) {
-        this.runtime = runtime;
+    public ReplacementsImpl(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, CodeCacheProvider codeCache, LoweringProvider lowerer, Assumptions assumptions,
+                    TargetDescription target) {
+        this.providers = new Providers(metaAccess, codeCache, constantReflection, lowerer, this);
         this.target = target;
         this.assumptions = assumptions;
         this.graphs = new ConcurrentHashMap<>();
@@ -84,7 +86,7 @@
 
         StructuredGraph graph = graphs.get(method);
         if (graph == null) {
-            graphs.putIfAbsent(method, makeGraph(method, null, inliningPolicy(method)));
+            graphs.putIfAbsent(method, makeGraph(method, null, inliningPolicy(method), method.getAnnotation(Snippet.class).removeAllFrameStates()));
             graph = graphs.get(method);
         }
         return graph;
@@ -97,7 +99,7 @@
         }
         StructuredGraph graph = graphs.get(substitute);
         if (graph == null) {
-            graphs.putIfAbsent(substitute, makeGraph(substitute, original, inliningPolicy(substitute)));
+            graphs.putIfAbsent(substitute, makeGraph(substitute, original, inliningPolicy(substitute), false));
             graph = graphs.get(substitute);
         }
         return graph;
@@ -167,12 +169,13 @@
      * @return the original method
      */
     protected ResolvedJavaMethod registerMethodSubstitution(Member originalMember, Method substituteMethod) {
-        ResolvedJavaMethod substitute = runtime.lookupJavaMethod(substituteMethod);
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
+        ResolvedJavaMethod substitute = metaAccess.lookupJavaMethod(substituteMethod);
         ResolvedJavaMethod original;
         if (originalMember instanceof Method) {
-            original = runtime.lookupJavaMethod((Method) originalMember);
+            original = metaAccess.lookupJavaMethod((Method) originalMember);
         } else {
-            original = runtime.lookupJavaConstructor((Constructor) originalMember);
+            original = metaAccess.lookupJavaConstructor((Constructor) originalMember);
         }
         Debug.log("substitution: " + MetaUtil.format("%H.%n(%p)", original) + " --> " + MetaUtil.format("%H.%n(%p)", substitute));
 
@@ -189,10 +192,11 @@
      */
     protected ResolvedJavaMethod registerMacroSubstitution(Member originalMethod, Class<? extends FixedWithNextNode> macro) {
         ResolvedJavaMethod originalJavaMethod;
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
         if (originalMethod instanceof Method) {
-            originalJavaMethod = runtime.lookupJavaMethod((Method) originalMethod);
+            originalJavaMethod = metaAccess.lookupJavaMethod((Method) originalMethod);
         } else {
-            originalJavaMethod = runtime.lookupJavaConstructor((Constructor) originalMethod);
+            originalJavaMethod = metaAccess.lookupJavaConstructor((Constructor) originalMethod);
         }
         registeredMacroSubstitutions.put(originalJavaMethod, macro);
         return originalJavaMethod;
@@ -205,7 +209,7 @@
             policyClass = snippet.inlining();
         }
         if (policyClass == SnippetInliningPolicy.class) {
-            return new DefaultSnippetInliningPolicy(runtime);
+            return new DefaultSnippetInliningPolicy(providers.getMetaAccess());
         }
         try {
             return policyClass.getConstructor().newInstance();
@@ -221,9 +225,10 @@
      * @param original the original method if {@code method} is a {@linkplain MethodSubstitution
      *            substitution} otherwise null
      * @param policy the inlining policy to use during preprocessing
+     * @param removeAllFrameStates removes all frame states from side effecting instructions
      */
-    public StructuredGraph makeGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, SnippetInliningPolicy policy) {
-        return createGraphMaker(method, original).makeGraph(policy);
+    public StructuredGraph makeGraph(ResolvedJavaMethod method, ResolvedJavaMethod original, SnippetInliningPolicy policy, boolean removeAllFrameStates) {
+        return createGraphMaker(method, original).makeGraph(policy, removeAllFrameStates);
     }
 
     /**
@@ -261,7 +266,7 @@
             this.original = original;
         }
 
-        public StructuredGraph makeGraph(final SnippetInliningPolicy policy) {
+        public StructuredGraph makeGraph(final SnippetInliningPolicy policy, final boolean removeAllFrameStates) {
             return Debug.scope("BuildSnippetGraph", new Object[]{method}, new Callable<StructuredGraph>() {
 
                 @Override
@@ -271,7 +276,7 @@
                     // Cannot have a finalized version of a graph in the cache
                     graph = graph.copy();
 
-                    finalizeGraph(graph);
+                    finalizeGraph(graph, removeAllFrameStates);
 
                     Debug.dump(graph, "%s: Final", method.getName());
 
@@ -283,15 +288,23 @@
         /**
          * Does final processing of a snippet graph.
          */
-        protected void finalizeGraph(StructuredGraph graph) {
-            new NodeIntrinsificationPhase(runtime).apply(graph);
+        protected void finalizeGraph(StructuredGraph graph, boolean removeAllFrameStates) {
+            new NodeIntrinsificationPhase(providers.getMetaAccess()).apply(graph);
             if (!SnippetTemplate.hasConstantParameter(method)) {
                 NodeIntrinsificationVerificationPhase.verify(graph);
             }
             new ConvertDeoptimizeToGuardPhase().apply(graph);
 
             if (original == null) {
-                new SnippetFrameStateCleanupPhase().apply(graph);
+                if (removeAllFrameStates) {
+                    for (Node node : graph.getNodes()) {
+                        if (node instanceof StateSplit) {
+                            ((StateSplit) node).setStateAfter(null);
+                        }
+                    }
+                } else {
+                    new SnippetFrameStateCleanupPhase().apply(graph);
+                }
             }
             new DeadCodeEliminationPhase().apply(graph);
         }
@@ -322,12 +335,13 @@
 
                 @Override
                 public void run() {
-                    new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
-                    new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph);
-                    new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph);
+                    MetaAccessProvider metaAccess = providers.getMetaAccess();
+                    new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
+                    new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
+                    new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
 
                     if (OptCanonicalizer.getValue()) {
-                        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime, assumptions, ReplacementsImpl.this));
+                        new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
                     }
                 }
             });
@@ -347,7 +361,7 @@
          */
         protected void afterInline(StructuredGraph caller, StructuredGraph callee, Object beforeInlineData) {
             if (OptCanonicalizer.getValue()) {
-                new CanonicalizerPhase(true).apply(caller, new PhaseContext(runtime, assumptions, ReplacementsImpl.this));
+                new CanonicalizerPhase(true).apply(caller, new PhaseContext(providers, assumptions));
             }
         }
 
@@ -355,10 +369,10 @@
          * Called after all inlining for a given graph is complete.
          */
         protected void afterInlining(StructuredGraph graph) {
-            new NodeIntrinsificationPhase(runtime).apply(graph);
+            new NodeIntrinsificationPhase(providers.getMetaAccess()).apply(graph);
             new DeadCodeEliminationPhase().apply(graph);
             if (OptCanonicalizer.getValue()) {
-                new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime, assumptions, ReplacementsImpl.this));
+                new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
             }
         }
 
@@ -373,9 +387,10 @@
                         ResolvedJavaMethod callee = callTarget.targetMethod();
                         if (callee == method) {
                             final StructuredGraph originalGraph = new StructuredGraph(original);
-                            new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph);
-                            new WordTypeVerificationPhase(runtime, target.wordKind).apply(graph);
-                            new WordTypeRewriterPhase(runtime, target.wordKind).apply(graph);
+                            MetaAccessProvider metaAccess = providers.getMetaAccess();
+                            new GraphBuilderPhase(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(originalGraph);
+                            new WordTypeVerificationPhase(metaAccess, target.wordKind).apply(graph);
+                            new WordTypeRewriterPhase(metaAccess, target.wordKind).apply(graph);
 
                             InliningUtil.inline(callTarget.invoke(), originalGraph, true);
 
@@ -468,7 +483,7 @@
                 parameters = Arrays.copyOfRange(parameters, 1, parameters.length);
             }
         } else {
-            Signature signature = runtime.parseMethodDescriptor(methodSubstitution);
+            Signature signature = providers.getMetaAccess().parseMethodDescriptor(methodSubstitution);
             parameters = new Class[signature.getParameterCount(false)];
             for (int i = 0; i < parameters.length; i++) {
                 parameters[i] = resolveType(signature.getParameterType(i, null));
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java	Fri Oct 11 17:21:14 2013 +0200
@@ -45,6 +45,13 @@
     Class<? extends SnippetInliningPolicy> inlining() default SnippetInliningPolicy.class;
 
     /**
+     * Specifies whether all FrameStates within this snippet should always be removed. If this is
+     * false, FrameStates are only removed if there are no side-effecting instructions in the
+     * snippet.
+     */
+    boolean removeAllFrameStates() default false;
+
+    /**
      * Guides inlining decisions used when installing a snippet.
      */
     public interface SnippetInliningPolicy {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Fri Oct 11 17:21:14 2013 +0200
@@ -34,6 +34,7 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.StructuredGraph.GuardsStage;
@@ -46,6 +47,7 @@
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.FloatingReadPhase.MemoryMapImpl;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
 import com.oracle.graal.replacements.Snippet.VarargsParameter;
 import com.oracle.graal.replacements.nodes.*;
@@ -320,14 +322,12 @@
      */
     public abstract static class AbstractTemplates implements SnippetTemplateCache {
 
-        protected final MetaAccessProvider runtime;
-        protected final Replacements replacements;
+        protected final Providers providers;
         protected final TargetDescription target;
         private final ConcurrentHashMap<CacheKey, SnippetTemplate> templates;
 
-        protected AbstractTemplates(MetaAccessProvider runtime, Replacements replacements, TargetDescription target) {
-            this.runtime = runtime;
-            this.replacements = replacements;
+        protected AbstractTemplates(Providers providers, TargetDescription target) {
+            this.providers = providers;
             this.target = target;
             this.templates = new ConcurrentHashMap<>();
         }
@@ -346,7 +346,7 @@
                 }
             }
             assert found != null : "did not find @" + Snippet.class.getSimpleName() + " method in " + declaringClass + (methodName == null ? "" : " named " + methodName);
-            return new SnippetInfo(runtime.lookupJavaMethod(found));
+            return new SnippetInfo(providers.getMetaAccess().lookupJavaMethod(found));
         }
 
         /**
@@ -360,7 +360,7 @@
 
                         @Override
                         public SnippetTemplate call() throws Exception {
-                            return new SnippetTemplate(runtime, replacements, args);
+                            return new SnippetTemplate(providers, args);
                         }
                     });
                     templates.put(args.cacheKey, template);
@@ -391,20 +391,22 @@
     /**
      * Creates a snippet template.
      */
-    protected SnippetTemplate(final MetaAccessProvider runtime, final Replacements replacements, Arguments args) {
-        StructuredGraph snippetGraph = replacements.getSnippet(args.info.method);
+    protected SnippetTemplate(final Providers providers, Arguments args) {
+        StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method);
 
         ResolvedJavaMethod method = snippetGraph.method();
         Signature signature = method.getSignature();
 
-        PhaseContext context = new PhaseContext(runtime, replacements.getAssumptions(), replacements);
+        Assumptions assumptions = providers.getReplacements().getAssumptions();
+        PhaseContext phaseContext = new PhaseContext(providers, assumptions);
 
         // Copy snippet graph, replacing constant parameters with given arguments
         final StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method());
         IdentityHashMap<Node, Node> nodeReplacements = new IdentityHashMap<>();
         nodeReplacements.put(snippetGraph.start(), snippetCopy.start());
 
-        assert checkTemplate(runtime, args, method, signature);
+        MetaAccessProvider metaAccess = providers.getMetaAccess();
+        assert checkTemplate(metaAccess, args, method, signature);
 
         int parameterCount = args.info.getParameterCount();
         ConstantNode[] placeholders = new ConstantNode[parameterCount];
@@ -419,11 +421,11 @@
                 } else {
                     constantArg = Constant.forBoxed(kind, arg);
                 }
-                nodeReplacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(constantArg, runtime, snippetCopy));
+                nodeReplacements.put(snippetGraph.getLocal(i), ConstantNode.forConstant(constantArg, metaAccess, snippetCopy));
             } else if (args.info.isVarargsParameter(i)) {
                 Varargs varargs = (Varargs) args.values[i];
                 Object array = Array.newInstance(varargs.componentType, varargs.length);
-                ConstantNode placeholder = ConstantNode.forObject(array, runtime, snippetCopy);
+                ConstantNode placeholder = ConstantNode.forObject(array, metaAccess, snippetCopy);
                 nodeReplacements.put(snippetGraph.getLocal(i), placeholder);
                 placeholders[i] = placeholder;
             }
@@ -433,8 +435,8 @@
         Debug.dump(snippetCopy, "Before specialization");
         if (!nodeReplacements.isEmpty()) {
             // Do deferred intrinsification of node intrinsics
-            new NodeIntrinsificationPhase(runtime).apply(snippetCopy);
-            new CanonicalizerPhase(true).apply(snippetCopy, context);
+            new NodeIntrinsificationPhase(metaAccess).apply(snippetCopy);
+            new CanonicalizerPhase(true).apply(snippetCopy, phaseContext);
         }
         NodeIntrinsificationVerificationPhase.verify(snippetCopy);
 
@@ -490,8 +492,8 @@
                 if (loopBegin != null) {
                     LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
                     int mark = snippetCopy.getMark();
-                    LoopTransformations.fullUnroll(loop, context, new CanonicalizerPhase(true));
-                    new CanonicalizerPhase(true).applyIncremental(snippetCopy, context, mark);
+                    LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase(true));
+                    new CanonicalizerPhase(true).applyIncremental(snippetCopy, phaseContext, mark);
                 }
                 FixedNode explodeLoopNext = explodeLoop.next();
                 explodeLoop.clearSuccessors();
@@ -507,7 +509,7 @@
         Debug.scope("LoweringSnippetTemplate", snippetCopy, new Runnable() {
 
             public void run() {
-                PhaseContext c = new PhaseContext(runtime, new Assumptions(false), replacements);
+                PhaseContext c = new PhaseContext(providers, new Assumptions(false));
                 new LoweringPhase(new CanonicalizerPhase(true)).apply(snippetCopy, c);
             }
         });
@@ -540,7 +542,6 @@
         }
 
         new DeadCodeEliminationPhase().apply(snippetCopy);
-        new CanonicalizerPhase(true).apply(snippetCopy, context);
 
         assert checkAllVarargPlaceholdersAreDeleted(parameterCount, placeholders);
 
@@ -552,7 +553,7 @@
         StartNode entryPointNode = snippet.start();
         nodes = new ArrayList<>(snippet.getNodeCount());
         boolean seenReturn = false;
-        boolean containsMemoryState = false;
+        boolean containsMemoryMap = false;
         for (Node node : snippet.getNodes()) {
             if (node == entryPointNode || node == entryPointNode.stateAfter()) {
                 // Do nothing.
@@ -560,18 +561,20 @@
                 nodes.add(node);
                 if (node instanceof ReturnNode) {
                     retNode = (ReturnNode) node;
-                    for (MemoryState memstate : retNode.usages().filter(MemoryState.class).snapshot()) {
-                        this.memoryMap = memstate.getMemoryMap();
-                        memstate.safeDelete();
-                    }
+                    NodeIterable<MemoryMapNode> memstates = retNode.inputs().filter(MemoryMapNode.class);
+                    assert memstates.count() == 1;
+                    memoryMap = memstates.first();
+                    retNode.replaceFirstInput(memoryMap, null);
+                    memoryMap.safeDelete();
+
                     assert !seenReturn : "can handle only one ReturnNode";
                     seenReturn = true;
-                } else if (node instanceof MemoryState) {
-                    containsMemoryState = true;
+                } else if (node instanceof MemoryMapNode) {
+                    containsMemoryMap = true;
                 }
             }
         }
-        assert !containsMemoryState;
+        assert !containsMemoryMap;
 
         this.sideEffectNodes = curSideEffectNodes;
         this.deoptNodes = curDeoptNodes;
@@ -591,9 +594,9 @@
         return true;
     }
 
-    private static boolean checkConstantArgument(MetaAccessProvider runtime, final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) {
+    private static boolean checkConstantArgument(MetaAccessProvider metaAccess, final ResolvedJavaMethod method, Signature signature, int i, String name, Object arg, Kind kind) {
         ResolvedJavaType type = signature.getParameterType(i, method.getDeclaringClass()).resolve(method.getDeclaringClass());
-        if (runtime.lookupJavaType(WordBase.class).isAssignableFrom(type)) {
+        if (metaAccess.lookupJavaType(WordBase.class).isAssignableFrom(type)) {
             assert arg instanceof Constant : method + ": word constant parameters must be passed boxed in a Constant value: " + arg;
             return true;
         }
@@ -606,10 +609,10 @@
         return true;
     }
 
-    private static boolean checkVarargs(MetaAccessProvider runtime, final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) {
+    private static boolean checkVarargs(MetaAccessProvider metaAccess, final ResolvedJavaMethod method, Signature signature, int i, String name, Varargs varargs) {
         ResolvedJavaType type = (ResolvedJavaType) signature.getParameterType(i, method.getDeclaringClass());
         assert type.isArray() : "varargs parameter must be an array type";
-        assert type.getComponentType().isAssignableFrom(runtime.lookupJavaType(varargs.componentType)) : "componentType for " + name + " not matching " + MetaUtil.toJavaName(type) + " instance: " +
+        assert type.getComponentType().isAssignableFrom(metaAccess.lookupJavaType(varargs.componentType)) : "componentType for " + name + " not matching " + MetaUtil.toJavaName(type) + " instance: " +
                         varargs.componentType;
         return true;
     }
@@ -657,14 +660,14 @@
     /**
      * map of killing locations to memory checkpoints (nodes).
      */
-    private MemoryMap<Node> memoryMap;
+    private MemoryMapNode memoryMap;
 
     /**
      * Gets the instantiation-time bindings to this template's parameters.
      * 
      * @return the map that will be used to bind arguments to parameters when inlining this template
      */
-    private IdentityHashMap<Node, Node> bind(StructuredGraph replaceeGraph, MetaAccessProvider runtime, Arguments args) {
+    private IdentityHashMap<Node, Node> bind(StructuredGraph replaceeGraph, MetaAccessProvider metaAccess, Arguments args) {
         IdentityHashMap<Node, Node> replacements = new IdentityHashMap<>();
         assert args.info.getParameterCount() == parameters.length : "number of args (" + args.info.getParameterCount() + ") != number of parameters (" + parameters.length + ")";
         for (int i = 0; i < parameters.length; i++) {
@@ -678,7 +681,7 @@
                     Kind kind = ((LocalNode) parameter).kind();
                     assert argument != null || kind == Kind.Object : this + " cannot accept null for non-object parameter named " + args.info.names[i];
                     Constant constant = forBoxed(argument, kind);
-                    replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, runtime, replaceeGraph));
+                    replacements.put((LocalNode) parameter, ConstantNode.forConstant(constant, metaAccess, replaceeGraph));
                 }
             } else if (parameter instanceof LocalNode[]) {
                 LocalNode[] locals = (LocalNode[]) parameter;
@@ -703,7 +706,7 @@
                         replacements.put(local, (ValueNode) value);
                     } else {
                         Constant constant = forBoxed(value, local.kind());
-                        ConstantNode element = ConstantNode.forConstant(constant, runtime, replaceeGraph);
+                        ConstantNode element = ConstantNode.forConstant(constant, metaAccess, replaceeGraph);
                         replacements.put(local, element);
                     }
                 }
@@ -751,7 +754,7 @@
         /**
          * Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}.
          */
-        void replace(ValueNode oldNode, ValueNode newNode, MemoryMap<Node> mmap);
+        void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap);
     }
 
     /**
@@ -761,7 +764,7 @@
     public static final UsageReplacer DEFAULT_REPLACER = new UsageReplacer() {
 
         @Override
-        public void replace(ValueNode oldNode, ValueNode newNode, MemoryMap<Node> mmap) {
+        public void replace(ValueNode oldNode, ValueNode newNode, MemoryMapNode mmap) {
             oldNode.replaceAtUsages(newNode);
             if (mmap == null || newNode == null) {
                 return;
@@ -792,7 +795,7 @@
             return true;
         }
 
-        Set<LocationIdentity> kills = ((MemoryMapImpl) memoryMap).getLocations();
+        Set<LocationIdentity> kills = new HashSet<>(((MemoryMapImpl) memoryMap).getLocations());
 
         if (replacee instanceof MemoryCheckpoint.Single) {
             // check if some node in snippet graph also kills the same location
@@ -828,7 +831,7 @@
         return true;
     }
 
-    private class DuplicateMapper implements MemoryMap<Node> {
+    private class DuplicateMapper extends MemoryMapNode {
 
         Map<Node, Node> duplicates;
         StartNode replaceeStart;
@@ -854,13 +857,13 @@
     /**
      * Replaces a given fixed node with this specialized snippet.
      * 
-     * @param runtime
+     * @param metaAccess
      * @param replacee the node that will be replaced
      * @param replacer object that replaces the usages of {@code replacee}
      * @param args the arguments to be bound to the flattened positional parameters of the snippet
      * @return the map of duplicated nodes (original -> duplicate)
      */
-    public Map<Node, Node> instantiate(MetaAccessProvider runtime, FixedNode replacee, UsageReplacer replacer, Arguments args) {
+    public Map<Node, Node> instantiate(MetaAccessProvider metaAccess, FixedNode replacee, UsageReplacer replacer, Arguments args) {
         assert checkSnippetKills(replacee);
         try (TimerCloseable a = instantiationTimer.start()) {
             instantiationCounter.increment();
@@ -868,7 +871,7 @@
             StartNode entryPointNode = snippet.start();
             FixedNode firstCFGNode = entryPointNode.next();
             StructuredGraph replaceeGraph = replacee.graph();
-            IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, runtime, args);
+            IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, metaAccess, args);
             replacements.put(entryPointNode, replaceeGraph.start());
             Map<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements);
             Debug.dump(replaceeGraph, "After inlining snippet %s", snippet.method());
@@ -915,7 +918,7 @@
                     returnValue = (ValueNode) duplicates.get(returnNode.result());
                 }
                 Node returnDuplicate = duplicates.get(returnNode);
-                MemoryMap<Node> mmap = new DuplicateMapper(duplicates, replaceeGraph.start());
+                MemoryMapNode mmap = new DuplicateMapper(duplicates, replaceeGraph.start());
                 if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) {
                     replacer.replace(replacee, (ValueNode) returnDuplicate.predecessor(), mmap);
                 } else {
@@ -948,12 +951,12 @@
     /**
      * Replaces a given floating node with this specialized snippet.
      * 
-     * @param runtime
+     * @param metaAccess
      * @param replacee the node that will be replaced
      * @param replacer object that replaces the usages of {@code replacee}
      * @param args the arguments to be bound to the flattened positional parameters of the snippet
      */
-    public void instantiate(MetaAccessProvider runtime, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, Arguments args) {
+    public void instantiate(MetaAccessProvider metaAccess, FloatingNode replacee, UsageReplacer replacer, LoweringTool tool, Arguments args) {
         assert checkSnippetKills(replacee);
         try (TimerCloseable a = instantiationTimer.start()) {
             instantiationCounter.increment();
@@ -964,7 +967,7 @@
             StartNode entryPointNode = snippet.start();
             FixedNode firstCFGNode = entryPointNode.next();
             StructuredGraph replaceeGraph = replacee.graph();
-            IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, runtime, args);
+            IdentityHashMap<Node, Node> replacements = bind(replaceeGraph, metaAccess, args);
             replacements.put(entryPointNode, replaceeGraph.start());
             Map<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements);
             Debug.dump(replaceeGraph, "After inlining snippet %s", snippetCopy.method());
@@ -1036,16 +1039,16 @@
         return buf.append(')').toString();
     }
 
-    private static boolean checkTemplate(MetaAccessProvider runtime, Arguments args, ResolvedJavaMethod method, Signature signature) {
+    private static boolean checkTemplate(MetaAccessProvider metaAccess, Arguments args, ResolvedJavaMethod method, Signature signature) {
         for (int i = 0; i < args.info.getParameterCount(); i++) {
             if (args.info.isConstantParameter(i)) {
                 Kind kind = signature.getParameterKind(i);
-                assert checkConstantArgument(runtime, method, signature, i, args.info.names[i], args.values[i], kind);
+                assert checkConstantArgument(metaAccess, method, signature, i, args.info.names[i], args.values[i], kind);
 
             } else if (args.info.isVarargsParameter(i)) {
                 assert args.values[i] instanceof Varargs;
                 Varargs varargs = (Varargs) args.values[i];
-                assert checkVarargs(runtime, method, signature, i, args.info.names[i], varargs);
+                assert checkVarargs(metaAccess, method, signature, i, args.info.names[i], varargs);
             }
         }
         return true;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/UnsafeSubstitutions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -53,7 +53,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static Object getObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        return UnsafeLoadNode.load(o, 0, offset, Kind.Object);
+        return UnsafeLoadNode.load(o, offset, Kind.Object);
     }
 
     @MethodSubstitution(isStatic = false)
@@ -66,7 +66,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static void putObject(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, Object x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Object);
+        UnsafeStoreNode.store(o, offset, x, Kind.Object);
     }
 
     @MethodSubstitution(isStatic = false)
@@ -85,7 +85,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static int getInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
-        Integer value = UnsafeLoadNode.load(o, 0, offset, Kind.Int);
+        Integer value = UnsafeLoadNode.load(o, offset, Kind.Int);
         return value;
     }
 
@@ -99,7 +99,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static void putInt(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, int x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Int);
+        UnsafeStoreNode.store(o, offset, x, Kind.Int);
     }
 
     @MethodSubstitution(isStatic = false)
@@ -119,7 +119,7 @@
     @MethodSubstitution(isStatic = false)
     public static boolean getBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         @JavacBug(id = 6995200)
-        Boolean result = UnsafeLoadNode.load(o, 0, offset, Kind.Boolean);
+        Boolean result = UnsafeLoadNode.load(o, offset, Kind.Boolean);
         return result;
     }
 
@@ -133,7 +133,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static void putBoolean(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, boolean x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Boolean);
+        UnsafeStoreNode.store(o, offset, x, Kind.Boolean);
     }
 
     @MethodSubstitution(isStatic = false)
@@ -146,7 +146,7 @@
     @MethodSubstitution(isStatic = false)
     public static byte getByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         @JavacBug(id = 6995200)
-        Byte result = UnsafeLoadNode.load(o, 0, offset, Kind.Byte);
+        Byte result = UnsafeLoadNode.load(o, offset, Kind.Byte);
         return result;
     }
 
@@ -160,7 +160,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static void putByte(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, byte x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Byte);
+        UnsafeStoreNode.store(o, offset, x, Kind.Byte);
     }
 
     @MethodSubstitution(isStatic = false)
@@ -173,7 +173,7 @@
     @MethodSubstitution(isStatic = false)
     public static short getShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         @JavacBug(id = 6995200)
-        Short result = UnsafeLoadNode.load(o, 0, offset, Kind.Short);
+        Short result = UnsafeLoadNode.load(o, offset, Kind.Short);
         return result;
     }
 
@@ -187,7 +187,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static void putShort(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, short x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Short);
+        UnsafeStoreNode.store(o, offset, x, Kind.Short);
     }
 
     @MethodSubstitution(isStatic = false)
@@ -200,7 +200,7 @@
     @MethodSubstitution(isStatic = false)
     public static char getChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         @JavacBug(id = 6995200)
-        Character result = UnsafeLoadNode.load(o, 0, offset, Kind.Char);
+        Character result = UnsafeLoadNode.load(o, offset, Kind.Char);
         return result;
     }
 
@@ -214,7 +214,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static void putChar(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, char x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Char);
+        UnsafeStoreNode.store(o, offset, x, Kind.Char);
     }
 
     @MethodSubstitution(isStatic = false)
@@ -227,7 +227,7 @@
     @MethodSubstitution(isStatic = false)
     public static long getLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         @JavacBug(id = 6995200)
-        Long result = UnsafeLoadNode.load(o, 0, offset, Kind.Long);
+        Long result = UnsafeLoadNode.load(o, offset, Kind.Long);
         return result;
     }
 
@@ -241,7 +241,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static void putLong(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, long x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Long);
+        UnsafeStoreNode.store(o, offset, x, Kind.Long);
     }
 
     @MethodSubstitution(isStatic = false)
@@ -261,7 +261,7 @@
     @MethodSubstitution(isStatic = false)
     public static float getFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         @JavacBug(id = 6995200)
-        Float result = UnsafeLoadNode.load(o, 0, offset, Kind.Float);
+        Float result = UnsafeLoadNode.load(o, offset, Kind.Float);
         return result;
     }
 
@@ -275,7 +275,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static void putFloat(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, float x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Float);
+        UnsafeStoreNode.store(o, offset, x, Kind.Float);
     }
 
     @MethodSubstitution(isStatic = false)
@@ -288,7 +288,7 @@
     @MethodSubstitution(isStatic = false)
     public static double getDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset) {
         @JavacBug(id = 6995200)
-        Double result = UnsafeLoadNode.load(o, 0, offset, Kind.Double);
+        Double result = UnsafeLoadNode.load(o, offset, Kind.Double);
         return result;
     }
 
@@ -302,7 +302,7 @@
 
     @MethodSubstitution(isStatic = false)
     public static void putDouble(@SuppressWarnings("unused") final Object thisObj, Object o, long offset, double x) {
-        UnsafeStoreNode.store(o, 0, offset, x, Kind.Double);
+        UnsafeStoreNode.store(o, offset, x, Kind.Double);
     }
 
     @MethodSubstitution(isStatic = false)
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitCountNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,10 +25,11 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 public class BitCountNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
@@ -41,7 +42,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
             long v = value.asConstant().asLong();
             if (value.kind().getStackKind() == Kind.Int) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanForwardNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,10 +25,11 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 public class BitScanForwardNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
@@ -41,7 +42,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
             long v = value.asConstant().asLong();
             if (value.kind().getStackKind() == Kind.Int) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BitScanReverseNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,10 +25,11 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 public class BitScanReverseNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
@@ -41,7 +42,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
             long v = value.asConstant().asLong();
             if (value.kind().getStackKind() == Kind.Int) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/LoadSnippetVarargParameterNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,8 +22,9 @@
  */
 package com.oracle.graal.replacements.nodes;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.replacements.Snippet.*;
 
@@ -43,7 +44,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (index.isConstant()) {
             return locals[index.asConstant().asInt()];
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MacroNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -96,7 +96,7 @@
      */
     protected StructuredGraph lowerReplacement(final StructuredGraph replacementGraph, LoweringTool tool) {
         replacementGraph.setGuardsStage(graph().getGuardsStage());
-        final PhaseContext c = new PhaseContext(tool.getRuntime(), tool.assumptions(), tool.getReplacements());
+        final PhaseContext c = new PhaseContext(tool.getMetaAccess(), tool.getCodeCache(), tool.getConstantReflection(), tool.getLowerer(), tool.assumptions(), tool.getReplacements());
         Debug.scope("LoweringReplacement", replacementGraph, new Runnable() {
 
             public void run() {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/MathIntrinsicNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,6 +24,7 @@
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -85,28 +86,15 @@
         gen.setResult(this, result);
     }
 
+    public Constant evalConst(Constant... inputs) {
+        assert inputs.length == 1;
+        return Constant.forDouble(compute(inputs[0].asDouble(), operation()));
+    }
+
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant()) {
-            double value = x().asConstant().asDouble();
-            switch (operation()) {
-                case ABS:
-                    return ConstantNode.forDouble(Math.abs(value), graph());
-                case SQRT:
-                    return ConstantNode.forDouble(Math.sqrt(value), graph());
-                case LOG:
-                    return ConstantNode.forDouble(Math.log(value), graph());
-                case LOG10:
-                    return ConstantNode.forDouble(Math.log10(value), graph());
-                case SIN:
-                    return ConstantNode.forDouble(Math.sin(value), graph());
-                case COS:
-                    return ConstantNode.forDouble(Math.cos(value), graph());
-                case TAN:
-                    return ConstantNode.forDouble(Math.tan(value), graph());
-                default:
-                    throw GraalInternalError.shouldNotReachHere();
-            }
+            return ConstantNode.forPrimitive(evalConst(x().asConstant()), graph());
         }
         return this;
     }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/PureFunctionMacroNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,8 +23,9 @@
 package com.oracle.graal.replacements.nodes;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 
 /**
  * This node class can be used to create {@link MacroNode}s for simple pure functions like
@@ -42,15 +43,16 @@
      */
     protected abstract Constant evaluate(Constant param, MetaAccessProvider metaAccess);
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (usages().isEmpty()) {
             return null;
         } else {
             ValueNode param = arguments.get(0);
             if (param.isConstant()) {
-                Constant constant = evaluate(param.asConstant(), tool.runtime());
+                Constant constant = evaluate(param.asConstant(), tool.getMetaAccess());
                 if (constant != null) {
-                    return ConstantNode.forConstant(constant, tool.runtime(), graph());
+                    return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
                 }
             }
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/ReverseBytesNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,10 +25,11 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 
 public class ReverseBytesNode extends FloatingNode implements LIRGenLowerable, Canonicalizable {
@@ -42,7 +43,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (value.isConstant()) {
             long v = value.asConstant().asLong();
             if (kind().getStackKind() == Kind.Int) {
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -36,10 +36,12 @@
 import com.oracle.graal.loop.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.truffle.*;
 import com.oracle.graal.truffle.printer.*;
@@ -56,8 +58,10 @@
     public PartialEvaluationTest() {
         // Make sure Truffle runtime is initialized.
         Assert.assertTrue(Truffle.getRuntime() instanceof GraalTruffleRuntime);
-        this.partialEvaluator = new PartialEvaluator(runtime, ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements(), new TruffleCache(runtime, GraphBuilderConfiguration.getDefault(),
-                        TruffleCompilerImpl.Optimizations, ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements()));
+        Replacements truffleReplacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements();
+        Providers providers = new Providers(getMetaAccess(), getCodeCache(), getConstantReflection(), getLowerer(), truffleReplacements);
+        TruffleCache truffleCache = new TruffleCache(providers, GraphBuilderConfiguration.getDefault(), TruffleCompilerImpl.Optimizations);
+        this.partialEvaluator = new PartialEvaluator(providers, truffleCache);
 
         DebugEnvironment.initialize(System.out);
     }
@@ -105,7 +109,7 @@
             public StructuredGraph call() {
                 StructuredGraph resultGraph = partialEvaluator.createGraph(compilable, assumptions);
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(canonicalizeReads);
-                PhaseContext context = new PhaseContext(runtime, assumptions, replacements);
+                PhaseContext context = new PhaseContext(getProviders(), assumptions);
 
                 if (resultGraph.hasLoops()) {
                     boolean unrolled;
@@ -160,7 +164,7 @@
             frameState.replaceAtUsages(null);
             frameState.safeDelete();
         }
-        new CanonicalizerPhase(true).apply(graph, new PhaseContext(runtime, new Assumptions(false), replacements));
+        new CanonicalizerPhase(true).apply(graph, new PhaseContext(getProviders(), new Assumptions(false)));
         new DeadCodeEliminationPhase().apply(graph);
     }
 
@@ -172,13 +176,13 @@
             public StructuredGraph call() {
                 Assumptions assumptions = new Assumptions(false);
                 StructuredGraph graph = parse(methodName);
-                PhaseContext context = new PhaseContext(runtime, assumptions, replacements);
+                PhaseContext context = new PhaseContext(getProviders(), assumptions);
                 CanonicalizerPhase canonicalizer = new CanonicalizerPhase(true);
                 canonicalizer.apply(graph, context);
 
                 // Additional inlining.
                 final PhasePlan plan = new PhasePlan();
-                GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations);
+                GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(getMetaAccess(), GraphBuilderConfiguration.getEagerDefault(), TruffleCompilerImpl.Optimizations);
                 plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
                 canonicalizer.addToPhasePlan(plan, context);
                 plan.addPhase(PhasePosition.AFTER_PARSING, new DeadCodeEliminationPhase());
@@ -187,7 +191,8 @@
                 canonicalizer.apply(graph, context);
                 new DeadCodeEliminationPhase().apply(graph);
 
-                HighTierContext highTierContext = new HighTierContext(runtime, assumptions, replacements, null, plan, OptimisticOptimizations.NONE);
+                HighTierContext highTierContext = new HighTierContext(getProviders(), assumptions, null, plan,
+                                OptimisticOptimizations.NONE);
                 InliningPhase inliningPhase = new InliningPhase(canonicalizer);
                 inliningPhase.apply(graph, highTierContext);
                 removeFrameStates(graph);
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/AbstractTestNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,5 +27,9 @@
 
 public abstract class AbstractTestNode extends Node {
 
+    protected AbstractTestNode() {
+        super(null);
+    }
+
     public abstract int execute(VirtualFrame frame);
 }
--- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/RootTestNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/nodes/RootTestNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -31,6 +31,7 @@
     @Child AbstractTestNode node;
 
     public RootTestNode(String name, AbstractTestNode node) {
+        super(null);
         this.name = name;
         this.node = node;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/FrameWithoutBoxing.java	Fri Oct 11 17:21:14 2013 +0200
@@ -57,7 +57,7 @@
 
     @Override
     public <T extends Arguments> T getArguments(Class<T> clazz) {
-        return CompilerDirectives.unsafeCast(arguments, clazz);
+        return CompilerDirectives.unsafeCast(arguments, clazz, true);
     }
 
     @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Fri Oct 11 17:21:14 2013 +0200
@@ -69,6 +69,11 @@
     }
 
     @Override
+    public VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor) {
+        return OptimizedCallTarget.createFrame(frameDescriptor, caller, arguments);
+    }
+
+    @Override
     public MaterializedFrame createMaterializedFrame(Arguments arguments) {
         return createMaterializedFrame(arguments);
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Fri Oct 11 17:21:14 2013 +0200
@@ -166,7 +166,7 @@
         return rootNode.execute(frame);
     }
 
-    private static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) {
+    protected static FrameWithoutBoxing createFrame(FrameDescriptor descriptor, PackedFrame caller, Arguments args) {
         return new FrameWithoutBoxing(descriptor, caller, args);
     }
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -35,6 +35,7 @@
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.java.*;
@@ -49,6 +50,7 @@
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.truffle.nodes.asserts.*;
 import com.oracle.graal.truffle.nodes.frame.*;
 import com.oracle.graal.truffle.nodes.frame.NewFrameNode.VirtualOnlyInstanceNode;
@@ -65,26 +67,24 @@
  */
 public class PartialEvaluator {
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final Providers providers;
     private final ResolvedJavaMethod executeHelperMethod;
     private final CanonicalizerPhase canonicalizer;
     private final ResolvedJavaType[] skippedExceptionTypes;
-    private final Replacements replacements;
     private Set<Constant> constantReceivers;
     private final HotSpotGraphCache cache;
     private final TruffleCache truffleCache;
 
-    public PartialEvaluator(MetaAccessProvider metaAccessProvider, Replacements replacements, TruffleCache truffleCache) {
-        this.metaAccessProvider = metaAccessProvider;
-        CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(metaAccessProvider);
+    public PartialEvaluator(Providers providers, TruffleCache truffleCache) {
+        this.providers = providers;
+        CustomCanonicalizer customCanonicalizer = new PartialEvaluatorCanonicalizer(providers.getMetaAccess(), providers.getConstantReflection());
         this.canonicalizer = new CanonicalizerPhase(!AOTCompilation.getValue(), customCanonicalizer);
-        this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(metaAccessProvider);
-        this.replacements = replacements;
+        this.skippedExceptionTypes = TruffleCompilerImpl.getSkippedExceptionTypes(providers.getMetaAccess());
         this.cache = HotSpotGraalRuntime.graalRuntime().getCache();
         this.truffleCache = truffleCache;
 
         try {
-            executeHelperMethod = metaAccessProvider.lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("executeHelper", PackedFrame.class, Arguments.class));
+            executeHelperMethod = providers.getMetaAccess().lookupJavaMethod(OptimizedCallTarget.class.getDeclaredMethod("executeHelper", PackedFrame.class, Arguments.class));
         } catch (NoSuchMethodException ex) {
             throw new RuntimeException(ex);
         }
@@ -115,18 +115,18 @@
 
             @Override
             public void run() {
-                new GraphBuilderPhase(metaAccessProvider, config, TruffleCompilerImpl.Optimizations).apply(graph);
+                new GraphBuilderPhase(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations).apply(graph);
 
                 // Replace thisNode with constant.
                 LocalNode thisNode = graph.getLocal(0);
-                thisNode.replaceAndDelete(ConstantNode.forObject(node, metaAccessProvider, graph));
+                thisNode.replaceAndDelete(ConstantNode.forObject(node, providers.getMetaAccess(), graph));
 
                 // Canonicalize / constant propagate.
-                PhaseContext baseContext = new PhaseContext(metaAccessProvider, assumptions, replacements);
+                PhaseContext baseContext = new PhaseContext(providers, assumptions);
                 canonicalizer.apply(graph, baseContext);
 
                 // Intrinsify methods.
-                new ReplaceIntrinsicsPhase(replacements).apply(graph);
+                new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
 
                 NewFrameNode newFrameNode = graph.getNodes(NewFrameNode.class).first();
                 if (newFrameNode == null) {
@@ -156,7 +156,7 @@
                 // Additional inlining.
                 final PhasePlan plan = new PhasePlan();
                 canonicalizer.apply(graph, baseContext);
-                HighTierContext context = new HighTierContext(metaAccessProvider, assumptions, replacements, cache, plan, OptimisticOptimizations.NONE);
+                HighTierContext tierContext = new HighTierContext(providers, assumptions, cache, plan, OptimisticOptimizations.NONE);
 
                 for (NeverPartOfCompilationNode neverPartOfCompilationNode : graph.getNodes(NeverPartOfCompilationNode.class)) {
                     Throwable exception = new VerificationError(neverPartOfCompilationNode.getMessage());
@@ -164,7 +164,7 @@
                 }
 
                 // EA frame and clean up.
-                new PartialEscapePhase(false, canonicalizer).apply(graph, context);
+                new PartialEscapePhase(false, canonicalizer).apply(graph, tierContext);
                 new VerifyNoIntrinsicsLeftPhase().apply(graph, false);
                 for (MaterializeFrameNode materializeNode : graph.getNodes(MaterializeFrameNode.class).snapshot()) {
                     materializeNode.replaceAtUsages(materializeNode.getFrame());
@@ -189,7 +189,7 @@
     }
 
     private void expandTree(StructuredGraph graph, Assumptions assumptions) {
-        PhaseContext context = new PhaseContext(metaAccessProvider, assumptions, replacements);
+        PhaseContext phaseContext = new PhaseContext(providers, assumptions);
         boolean changed;
         do {
             changed = false;
@@ -203,6 +203,7 @@
                         ConstantNode constantNode = (ConstantNode) methodCallTargetNode.arguments().first();
                         constantReceivers.add(constantNode.asConstant());
                     }
+                    Replacements replacements = providers.getReplacements();
                     StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod());
 
                     if (inlineGraph == null) {
@@ -216,7 +217,7 @@
 
                     if (inlineGraph == null && !Modifier.isNative(methodCallTargetNode.targetMethod().getModifiers()) &&
                                     methodCallTargetNode.targetMethod().getAnnotation(CompilerDirectives.SlowPath.class) == null) {
-                        inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, context);
+                        inlineGraph = parseGraph(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), assumptions, phaseContext);
                     }
 
                     if (inlineGraph != null) {
@@ -227,7 +228,7 @@
                             int nodeCountAfter = graph.getNodeCount();
                             Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter);
                         }
-                        canonicalizer.applyIncremental(graph, context, mark);
+                        canonicalizer.applyIncremental(graph, phaseContext, mark);
                         changed = true;
                     }
                 }
@@ -239,7 +240,7 @@
         } while (changed);
     }
 
-    private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext context) {
+    private StructuredGraph parseGraph(final ResolvedJavaMethod targetMethod, final NodeInputList<ValueNode> arguments, final Assumptions assumptions, final PhaseContext phaseContext) {
 
         StructuredGraph graph = truffleCache.lookup(targetMethod, arguments, assumptions, canonicalizer);
 
@@ -251,7 +252,7 @@
                 ValueNode arg = arguments.get(local.index());
                 if (arg.isConstant()) {
                     Constant constant = arg.asConstant();
-                    ConstantNode constantNode = ConstantNode.forConstant(constant, metaAccessProvider, graphCopy);
+                    ConstantNode constantNode = ConstantNode.forConstant(constant, phaseContext.getMetaAccess(), graphCopy);
                     local.replaceAndDelete(constantNode);
                     for (Node usage : constantNode.usages()) {
                         if (usage instanceof Canonicalizable) {
@@ -265,7 +266,7 @@
                 @Override
                 public void run() {
 
-                    canonicalizer.applyIncremental(graphCopy, context, modifiedNodes);
+                    canonicalizer.applyIncremental(graphCopy, phaseContext, modifiedNodes);
                     boolean unrolled;
                     do {
                         unrolled = false;
@@ -274,7 +275,7 @@
                         for (LoopEx ex : innerLoopsFirst(loopsData.countedLoops())) {
                             if (ex.counted().isConstantMaxTripCount()) {
                                 long constant = ex.counted().constantMaxTripCount();
-                                LoopTransformations.fullUnroll(ex, context, canonicalizer);
+                                LoopTransformations.fullUnroll(ex, phaseContext, canonicalizer);
                                 Debug.dump(graphCopy, "After loop unrolling %d times", constant);
                                 unrolled = true;
                                 break;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluatorCanonicalizer.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,7 @@
 import sun.misc.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.Node;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.common.*;
@@ -35,14 +36,16 @@
 
 final class PartialEvaluatorCanonicalizer implements CanonicalizerPhase.CustomCanonicalizer {
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final MetaAccessProvider metaAccess;
+    private final ConstantReflectionProvider constantReflection;
 
-    PartialEvaluatorCanonicalizer(MetaAccessProvider metaAccessProvider) {
-        this.metaAccessProvider = metaAccessProvider;
+    PartialEvaluatorCanonicalizer(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection) {
+        this.metaAccess = metaAccess;
+        this.constantReflection = constantReflection;
     }
 
     @Override
-    public ValueNode canonicalize(ValueNode node) {
+    public Node canonicalize(Node node) {
         if (node instanceof LoadFieldNode) {
             LoadFieldNode loadFieldNode = (LoadFieldNode) node;
             if (!loadFieldNode.isStatic() && loadFieldNode.object().isConstant() && !loadFieldNode.object().isNullConstant()) {
@@ -50,7 +53,7 @@
                                 loadFieldNode.field().getAnnotation(CompilerDirectives.CompilationFinal.class) != null) {
                     Constant constant = loadFieldNode.field().readValue(loadFieldNode.object().asConstant());
                     assert verifyFieldValue(loadFieldNode.field(), constant);
-                    return ConstantNode.forConstant(constant, metaAccessProvider, node.graph());
+                    return ConstantNode.forConstant(constant, metaAccess, node.graph());
                 }
             }
         } else if (node instanceof LoadIndexedNode) {
@@ -61,9 +64,9 @@
                 if (index >= 0 && index < Array.getLength(array)) {
                     int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass());
                     int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass());
-                    Constant constant = metaAccessProvider.readUnsafeConstant(loadIndexedNode.elementKind(), array, arrayBaseOffset + index * arrayIndexScale,
+                    Constant constant = constantReflection.readUnsafeConstant(loadIndexedNode.elementKind(), array, arrayBaseOffset + index * arrayIndexScale,
                                     loadIndexedNode.elementKind() == Kind.Object);
-                    return ConstantNode.forConstant(constant, metaAccessProvider, loadIndexedNode.graph());
+                    return ConstantNode.forConstant(constant, metaAccess, loadIndexedNode.graph());
                 }
             }
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCache.java	Fri Oct 11 17:21:14 2013 +0200
@@ -33,16 +33,17 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.truffle.phases.*;
 import com.oracle.graal.virtual.phases.ea.*;
 import com.oracle.truffle.api.*;
@@ -53,21 +54,19 @@
  */
 public final class TruffleCache {
 
-    private final MetaAccessProvider metaAccessProvider;
+    private final Providers providers;
     private final GraphBuilderConfiguration config;
     private final OptimisticOptimizations optimisticOptimizations;
-    private final Replacements replacements;
 
     private final HashMap<List<Object>, StructuredGraph> cache = new HashMap<>();
     private final StructuredGraph markerGraph = new StructuredGraph();
     private final ResolvedJavaType stringBuilderClass;
 
-    public TruffleCache(MetaAccessProvider metaAccessProvider, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations, Replacements replacements) {
-        this.metaAccessProvider = metaAccessProvider;
+    public TruffleCache(Providers providers, GraphBuilderConfiguration config, OptimisticOptimizations optimisticOptimizations) {
+        this.providers = providers;
         this.config = config;
         this.optimisticOptimizations = optimisticOptimizations;
-        this.replacements = replacements;
-        this.stringBuilderClass = metaAccessProvider.lookupJavaType(StringBuilder.class);
+        this.stringBuilderClass = providers.getMetaAccess().lookupJavaType(StringBuilder.class);
     }
 
     @SuppressWarnings("unused")
@@ -91,13 +90,13 @@
         }
 
         cache.put(key, markerGraph);
-        resultGraph = Debug.scope("TruffleCache", new Object[]{metaAccessProvider, method}, new Callable<StructuredGraph>() {
+        resultGraph = Debug.scope("TruffleCache", new Object[]{providers.getMetaAccess(), method}, new Callable<StructuredGraph>() {
 
             public StructuredGraph call() {
 
                 final StructuredGraph graph = new StructuredGraph(method);
-                PhaseContext context = new PhaseContext(metaAccessProvider, new Assumptions(false), replacements);
-                new GraphBuilderPhase(metaAccessProvider, config, optimisticOptimizations).apply(graph);
+                PhaseContext phaseContext = new PhaseContext(providers, new Assumptions(false));
+                new GraphBuilderPhase(phaseContext.getMetaAccess(), config, optimisticOptimizations).apply(graph);
 
                 for (LocalNode l : graph.getNodes(LocalNode.class)) {
                     if (l.kind() == Kind.Object) {
@@ -107,7 +106,7 @@
                 }
 
                 // Intrinsify methods.
-                new ReplaceIntrinsicsPhase(replacements).apply(graph);
+                new ReplaceIntrinsicsPhase(providers.getReplacements()).apply(graph);
 
                 // Convert deopt to guards.
                 new ConvertDeoptimizeToGuardPhase().apply(graph);
@@ -118,14 +117,14 @@
                 int mark = 0;
                 while (true) {
 
-                    partialEscapePhase.apply(graph, context);
+                    partialEscapePhase.apply(graph, phaseContext);
 
                     // Conditional elimination.
-                    ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(metaAccessProvider);
+                    ConditionalEliminationPhase conditionalEliminationPhase = new ConditionalEliminationPhase(phaseContext.getMetaAccess());
                     conditionalEliminationPhase.apply(graph);
 
                     // Canonicalize / constant propagate.
-                    canonicalizerPhase.apply(graph, context);
+                    canonicalizerPhase.apply(graph, phaseContext);
 
                     boolean inliningProgress = false;
                     for (MethodCallTargetNode methodCallTarget : graph.getNodes(MethodCallTargetNode.class)) {
@@ -135,7 +134,7 @@
                             for (Node newNode : graph.getNewNodes(mark)) {
                                 if (newNode instanceof MethodCallTargetNode) {
                                     MethodCallTargetNode methodCallTargetNode = (MethodCallTargetNode) newNode;
-                                    Class<? extends FixedWithNextNode> macroSubstitution = replacements.getMacroSubstitution(methodCallTargetNode.targetMethod());
+                                    Class<? extends FixedWithNextNode> macroSubstitution = providers.getReplacements().getMacroSubstitution(methodCallTargetNode.targetMethod());
                                     if (macroSubstitution != null) {
                                         InliningUtil.inlineMacroNode(methodCallTargetNode.invoke(), methodCallTargetNode.targetMethod(), methodCallTargetNode.graph(), macroSubstitution);
                                     } else {
@@ -165,13 +164,15 @@
                                     }
                                 }
                             }
-                            canonicalizerPhase.applyIncremental(graph, context, canonicalizerUsages);
+                            canonicalizerPhase.applyIncremental(graph, phaseContext, canonicalizerUsages);
                         }
                     }
 
                     // Convert deopt to guards.
                     new ConvertDeoptimizeToGuardPhase().apply(graph);
 
+                    new EarlyReadEliminationPhase(canonicalizerPhase).apply(graph, phaseContext);
+
                     if (!inliningProgress) {
                         break;
                     }
@@ -188,7 +189,7 @@
     }
 
     private void expandInvoke(MethodCallTargetNode methodCallTargetNode) {
-        StructuredGraph inlineGraph = replacements.getMethodSubstitution(methodCallTargetNode.targetMethod());
+        StructuredGraph inlineGraph = providers.getReplacements().getMethodSubstitution(methodCallTargetNode.targetMethod());
         if (inlineGraph == null) {
             inlineGraph = TruffleCache.this.lookup(methodCallTargetNode.targetMethod(), methodCallTargetNode.arguments(), null, null);
         }
@@ -203,8 +204,8 @@
 
     private boolean tryCutOffRuntimeExceptions(MethodCallTargetNode methodCallTargetNode) {
         if (methodCallTargetNode.targetMethod().isConstructor()) {
-            ResolvedJavaType runtimeException = metaAccessProvider.lookupJavaType(RuntimeException.class);
-            ResolvedJavaType controlFlowException = metaAccessProvider.lookupJavaType(ControlFlowException.class);
+            ResolvedJavaType runtimeException = providers.getMetaAccess().lookupJavaType(RuntimeException.class);
+            ResolvedJavaType controlFlowException = providers.getMetaAccess().lookupJavaType(ControlFlowException.class);
             ResolvedJavaType exceptionType = Objects.requireNonNull(ObjectStamp.typeOrNull(methodCallTargetNode.receiver().stamp()));
             if (runtimeException.isAssignableFrom(methodCallTargetNode.targetMethod().getDeclaringClass()) && !controlFlowException.isAssignableFrom(exceptionType)) {
                 DeoptimizeNode deoptNode = methodCallTargetNode.graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.UnreachedCode));
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Fri Oct 11 17:21:14 2013 +0200
@@ -43,6 +43,7 @@
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.PhasePlan.PhasePosition;
 import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 import com.oracle.graal.printer.*;
 import com.oracle.graal.truffle.nodes.*;
 import com.oracle.truffle.api.*;
@@ -53,11 +54,9 @@
  */
 public class TruffleCompilerImpl implements TruffleCompiler {
 
-    private final GraalCodeCacheProvider runtime;
+    private final Providers providers;
     private final Suites suites;
     private final PartialEvaluator partialEvaluator;
-    private final MetaAccessProvider metaAccessProvider;
-    private final Replacements replacements;
     private final Backend backend;
     private final ResolvedJavaType[] skippedExceptionTypes;
     private final HotSpotGraalRuntime graalRuntime;
@@ -69,29 +68,29 @@
                     OptimisticOptimizations.Optimization.RemoveNeverExecutedCode, OptimisticOptimizations.Optimization.UseTypeCheckedInlining, OptimisticOptimizations.Optimization.UseTypeCheckHints);
 
     public TruffleCompilerImpl() {
-        this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class);
+        this.providers = new Providers(Graal.getRequiredCapability(MetaAccessProvider.class), Graal.getRequiredCapability(CodeCacheProvider.class),
+                        Graal.getRequiredCapability(ConstantReflectionProvider.class), Graal.getRequiredCapability(LoweringProvider.class),
+                        ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements());
         this.suites = Graal.getRequiredCapability(SuitesProvider.class).createSuites();
-        this.metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
         this.backend = Graal.getRequiredCapability(Backend.class);
-        this.replacements = ((GraalTruffleRuntime) Truffle.getRuntime()).getReplacements();
         this.graalRuntime = HotSpotGraalRuntime.graalRuntime();
-        this.skippedExceptionTypes = getSkippedExceptionTypes(metaAccessProvider);
+        this.skippedExceptionTypes = getSkippedExceptionTypes(providers.getMetaAccess());
 
         final GraphBuilderConfiguration config = GraphBuilderConfiguration.getEagerDefault();
         config.setSkippedExceptionTypes(skippedExceptionTypes);
-        this.truffleCache = new TruffleCache(this.runtime, config, TruffleCompilerImpl.Optimizations, this.replacements);
+        this.truffleCache = new TruffleCache(providers, config, TruffleCompilerImpl.Optimizations);
 
-        this.partialEvaluator = new PartialEvaluator(metaAccessProvider, replacements, truffleCache);
+        this.partialEvaluator = new PartialEvaluator(providers, truffleCache);
 
         if (Debug.isEnabled()) {
             DebugEnvironment.initialize(System.out);
         }
     }
 
-    static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccessProvider) {
+    static ResolvedJavaType[] getSkippedExceptionTypes(MetaAccessProvider metaAccess) {
         ResolvedJavaType[] skippedExceptionTypes = new ResolvedJavaType[SKIPPED_EXCEPTION_CLASSES.length];
         for (int i = 0; i < SKIPPED_EXCEPTION_CLASSES.length; i++) {
-            skippedExceptionTypes[i] = metaAccessProvider.lookupJavaType(SKIPPED_EXCEPTION_CLASSES[i]);
+            skippedExceptionTypes[i] = metaAccess.lookupJavaType(SKIPPED_EXCEPTION_CLASSES[i]);
         }
         return skippedExceptionTypes;
     }
@@ -150,9 +149,10 @@
             @Override
             public CompilationResult call() {
                 try (TimerCloseable a = CompilationTime.start()) {
-                    CallingConvention cc = getCallingConvention(runtime, Type.JavaCallee, graph.method(), false);
-                    return GraalCompiler.compileGraph(graph, cc, graph.method(), runtime, replacements, backend, runtime.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(),
-                                    suites, new CompilationResult());
+                    CodeCacheProvider codeCache = providers.getCodeCache();
+                    CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
+                    return GraalCompiler.compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, plan, OptimisticOptimizations.ALL, new SpeculationLog(), suites,
+                                    new CompilationResult());
                 }
             }
         });
@@ -178,7 +178,7 @@
             @Override
             public InstalledCode call() throws Exception {
                 try (TimerCloseable a = CodeInstallationTime.start()) {
-                    InstalledCode installedCode = runtime.addMethod(graph.method(), result);
+                    InstalledCode installedCode = providers.getCodeCache().addMethod(graph.method(), result);
                     if (installedCode != null) {
                         Debug.dump(new Object[]{result, installedCode}, "After code installation");
                     }
@@ -192,7 +192,7 @@
         }
 
         if (Debug.isLogEnabled()) {
-            Debug.log(runtime.disassemble(result, compiledMethod));
+            Debug.log(providers.getCodeCache().disassemble(result, compiledMethod));
         }
         if (compilable != null) {
             compilable.codeSize = result.getTargetCodeSize();
@@ -202,7 +202,7 @@
 
     private PhasePlan createPhasePlan(final GraphBuilderConfiguration config) {
         final PhasePlan phasePlan = new PhasePlan();
-        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(metaAccessProvider, config, TruffleCompilerImpl.Optimizations);
+        GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(providers.getMetaAccess(), config, TruffleCompilerImpl.Optimizations);
         phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase);
         return phasePlan;
     }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -34,7 +34,7 @@
     /**
      * Instructs the Truffle Compiler to compile call targets only if their name contains at least one element of a comma-separated list of includes.
      * Excludes are prefixed with a tilde (~).
-     * 
+     *
      * The format in EBNF:
      * <pre>
      * CompileOnly = Element, { ',', Element } ;
@@ -56,10 +56,6 @@
     @Option(help = "")
     public static final OptionValue<Boolean> TruffleFunctionInlining = new OptionValue<>(true);
     @Option(help = "")
-    public static final OptionValue<Integer> TruffleConstantUnrollLimit = new OptionValue<>(32);
-    @Option(help = "")
-    public static final OptionValue<Integer> TruffleOperationCacheMaxNodes = new OptionValue<>(350);
-    @Option(help = "")
     public static final OptionValue<Integer> TruffleGraphMaxNodes = new OptionValue<>(20000);
     @Option(help = "")
     public static final OptionValue<Integer> TruffleInliningMaxRecursiveDepth = new OptionValue<>(2);
@@ -83,8 +79,6 @@
     @Option(help = "")
     public static final OptionValue<Boolean> TraceTruffleCacheDetails = new OptionValue<>(false);
     @Option(help = "")
-    public static final OptionValue<Boolean> TraceTrufflePerformanceWarnings = 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);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleReplacements.java	Fri Oct 11 17:21:14 2013 +0200
@@ -41,16 +41,20 @@
 
     private final Replacements graalReplacements;
 
-    private TruffleReplacements(MetaAccessProvider runtime, Assumptions assumptions, TargetDescription target, Replacements graalReplacements) {
-        super(runtime, assumptions, target);
+    private TruffleReplacements(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, CodeCacheProvider codeCache, LoweringProvider lowerer, Assumptions assumptions,
+                    TargetDescription target, Replacements graalReplacements) {
+        super(metaAccess, constantReflection, codeCache, lowerer, assumptions, target);
         this.graalReplacements = graalReplacements;
     }
 
     static Replacements makeInstance() {
-        MetaAccessProvider metaAccessProvider = Graal.getRequiredCapability(MetaAccessProvider.class);
+        MetaAccessProvider metaAccess = Graal.getRequiredCapability(MetaAccessProvider.class);
+        CodeCacheProvider codeCache = Graal.getRequiredCapability(CodeCacheProvider.class);
+        ConstantReflectionProvider constantReflection = Graal.getRequiredCapability(ConstantReflectionProvider.class);
+        LoweringProvider lowerer = Graal.getRequiredCapability(LoweringProvider.class);
         TargetDescription targetDescription = Graal.getRequiredCapability(CodeCacheProvider.class).getTarget();
         Replacements graalReplacements = Graal.getRequiredCapability(Replacements.class);
-        Replacements truffleReplacements = new TruffleReplacements(metaAccessProvider, graalReplacements.getAssumptions(), targetDescription, graalReplacements);
+        Replacements truffleReplacements = new TruffleReplacements(metaAccess, constantReflection, codeCache, lowerer, graalReplacements.getAssumptions(), targetDescription, graalReplacements);
 
         truffleReplacements.registerSubstitutions(CompilerAssertsSubstitutions.class);
         truffleReplacements.registerSubstitutions(CompilerDirectivesSubstitutions.class);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/AssumptionNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,10 +22,9 @@
  */
 package com.oracle.graal.truffle.nodes;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 import com.oracle.graal.truffle.*;
 
@@ -40,6 +39,7 @@
         return arguments.first();
     }
 
+    @Override
     public void simplify(SimplifierTool tool) {
         ValueNode assumption = getAssumption();
         if (tool.assumptions() != null && assumption.isConstant()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/BailoutNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,8 +23,9 @@
 package com.oracle.graal.truffle.nodes;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.nodes.*;
 
 public class BailoutNode extends MacroNode implements Canonicalizable {
@@ -35,7 +36,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         ValueNode arg = arguments.get(0);
         String message = "";
         if (arg.isConstant()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/LoadIndexedFinalNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,8 @@
 import sun.misc.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
@@ -49,15 +51,15 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (array().isConstant() && !array().isNullConstant() && index().isConstant()) {
             Object array = array().asConstant().asObject();
             long index = index().asConstant().asLong();
             if (index >= 0 && index < Array.getLength(array)) {
                 int arrayBaseOffset = Unsafe.getUnsafe().arrayBaseOffset(array.getClass());
                 int arrayIndexScale = Unsafe.getUnsafe().arrayIndexScale(array.getClass());
-                Constant constant = tool.runtime().readUnsafeConstant(elementKind(), array, arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object);
-                return ConstantNode.forConstant(constant, tool.runtime(), graph());
+                Constant constant = tool.getConstantReflection().readUnsafeConstant(elementKind(), array().asConstant(), arrayBaseOffset + index * arrayIndexScale, elementKind() == Kind.Object);
+                return ConstantNode.forConstant(constant, tool.getMetaAccess(), graph());
             }
         }
         return this;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerAddExactNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.truffle.nodes.arithmetic;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -47,7 +49,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
             return graph().unique(new IntegerAddExactNode(y(), x()));
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerExactArithmeticSplitNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.truffle.nodes.arithmetic;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.compiler.target.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerMulExactNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.truffle.nodes.arithmetic;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -40,7 +42,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x().isConstant() && !y().isConstant()) {
             return graph().unique(new IntegerMulExactNode(y(), x()));
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/arithmetic/IntegerSubExactNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.truffle.nodes.arithmetic;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.spi.*;
@@ -47,7 +49,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (x() == y()) {
             return ConstantNode.forIntegerKind(kind(), 0, graph());
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/asserts/CompilationConstantNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,8 +22,9 @@
  */
 package com.oracle.graal.truffle.nodes.asserts;
 
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 
 public class CompilationConstantNode extends NeverPartOfCompilationNode implements Canonicalizable {
 
@@ -33,7 +34,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (arguments.get(0).isConstant()) {
             return arguments.get(0);
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameAccessNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,8 +25,8 @@
 import java.lang.reflect.*;
 import java.util.*;
 
-import com.oracle.graal.api.code.*;
 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.*;
@@ -95,11 +95,11 @@
         }
     }
 
-    protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccessProvider) {
+    protected final ValueNode getSlotOffset(int scale, MetaAccessProvider metaAccess) {
         if (isConstantFrameSlot()) {
             return ConstantNode.forInt(getSlotIndex() * scale, graph());
         } else {
-            LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccessProvider.lookupJavaField(getFrameSlotIndexField())));
+            LoadFieldNode loadFrameSlotIndex = graph().add(new LoadFieldNode(getSlot(), metaAccess.lookupJavaField(getFrameSlotIndexField())));
             graph().addBeforeFixed(this, loadFrameSlotIndex);
             return scale == 1 ? loadFrameSlotIndex : IntegerArithmeticNode.mul(loadFrameSlotIndex, ConstantNode.forInt(scale, graph()));
         }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameGetNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,7 @@
 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.*;
@@ -78,14 +79,15 @@
         structuredGraph.addBeforeFixed(this, loadFieldNode);
         FixedWithNextNode loadNode;
         if (isTagAccess()) {
-            ValueNode slotIndex = getSlotOffset(1, tool.getRuntime());
+            ValueNode slotIndex = getSlotOffset(1, tool.getMetaAccess());
             loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, getSlotKind()));
         } else if (!getSlotKind().isPrimitive()) {
-            ValueNode slotIndex = getSlotOffset(1, tool.getRuntime());
+            ValueNode slotIndex = getSlotOffset(1, tool.getMetaAccess());
             loadNode = graph().add(new LoadIndexedNode(loadFieldNode, slotIndex, Kind.Object));
         } else {
-            ValueNode slotOffset = getSlotOffset(Unsafe.ARRAY_LONG_INDEX_SCALE, tool.getRuntime());
-            loadNode = graph().add(new UnsafeLoadNode(loadFieldNode, Unsafe.ARRAY_LONG_BASE_OFFSET, slotOffset, getSlotKind()));
+            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);
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/FrameSetNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -77,7 +77,7 @@
         LoadFieldNode loadFieldNode = graph().add(new LoadFieldNode(getFrame(), field));
         structuredGraph.addBeforeFixed(this, loadFieldNode);
         FixedWithNextNode storeNode;
-        ValueNode slotIndex = getSlotOffset(1, tool.getRuntime());
+        ValueNode slotIndex = getSlotOffset(1, tool.getMetaAccess());
         if (isTagAccess()) {
             storeNode = graph().add(new StoreIndexedNode(loadFieldNode, slotIndex, getSlotKind(), value));
         } else if (!getSlotKind().isPrimitive()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/frame/NewFrameNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
@@ -205,7 +206,7 @@
     }
 
     @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
+    public Node canonical(CanonicalizerTool tool) {
         if (usages().isEmpty()) {
             return null;
         } else {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckMacroNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +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.typesystem;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.truffle.nodes.asserts.*;
-import com.oracle.truffle.api.*;
-
-/**
- * Macro node for method {@link CompilerDirectives#customTypeCheck(boolean, Object, Object)}.
- */
-public class CustomTypeCheckMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
-
-    private static final int ARGUMENT_COUNT = 3;
-    private static final int CONDITION_ARGUMENT_INDEX = 0;
-    private static final int OBJECT_ARGUMENT_INDEX = 1;
-    private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 2;
-
-    public CustomTypeCheckMacroNode(Invoke invoke) {
-        super(invoke, "The custom type parameter could not be reduced to a compile time constant.");
-        assert arguments.size() == ARGUMENT_COUNT;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX);
-        if (customTypeArgument.isConstant()) {
-            Object typeToken = customTypeArgument.asConstant().asObject();
-            ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX);
-            ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
-            return graph().unique(new ConditionalNode(graph().unique(new CustomTypeCheckNode(conditionArgument, objectArgument, typeToken))));
-        }
-        return this;
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomTypeCheckNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 2012, 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.typesystem;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-
-public final class CustomTypeCheckNode extends LogicNode implements Lowerable, Virtualizable, com.oracle.graal.graph.IterableNodeType {
-
-    @Input private ValueNode condition;
-    @Input private ValueNode object;
-    private final Object customType;
-
-    public CustomTypeCheckNode(ValueNode condition, ValueNode object, Object customType) {
-        this.condition = condition;
-        this.object = object;
-        this.customType = customType;
-    }
-
-    public ValueNode getObject() {
-        return object;
-    }
-
-    public ValueNode getCondition() {
-        return condition;
-    }
-
-    public Object getCustomType() {
-        return customType;
-    }
-
-    public void lower(LoweringTool tool) {
-        if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) {
-            this.replaceAtUsages(graph().unique(new IntegerEqualsNode(condition, ConstantNode.forInt(1, graph()))));
-            this.safeDelete();
-        }
-    }
-
-    public void virtualize(VirtualizerTool tool) {
-        if (getObject() != null) {
-            State objectState = tool.getObjectState(getObject());
-            if (objectState != null && objectState.getState() == EscapeState.Virtual) {
-                // The object is escape analyzed => cut the connection.
-                this.updateUsages(this.object, null);
-                this.object = null;
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeLoadMacroNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,70 @@
+/*
+ * 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.typesystem;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}.
+ */
+public class CustomizedUnsafeLoadMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
+
+    private static final int ARGUMENT_COUNT = 4;
+    private static final int OBJECT_ARGUMENT_INDEX = 0;
+    private static final int OFFSET_ARGUMENT_INDEX = 1;
+    private static final int CONDITION_ARGUMENT_INDEX = 2;
+    private static final int LOCATION_ARGUMENT_INDEX = 3;
+
+    public CustomizedUnsafeLoadMacroNode(Invoke invoke) {
+        super(invoke, "The location argument could not be resolved to a constant.");
+        assert arguments.size() == ARGUMENT_COUNT;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        ValueNode locationArgument = arguments.get(LOCATION_ARGUMENT_INDEX);
+        if (locationArgument.isConstant()) {
+            ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
+            ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX);
+            ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX);
+            Object locationIdentityObject = locationArgument.asConstant().asObject();
+            LocationIdentity locationIdentity;
+            if (locationIdentityObject == null) {
+                locationIdentity = LocationIdentity.ANY_LOCATION;
+            } 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()))));
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/CustomizedUnsafeStoreMacroNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,70 @@
+/*
+ * 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.typesystem;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}.
+ */
+public class CustomizedUnsafeStoreMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
+
+    private static final int ARGUMENT_COUNT = 4;
+    private static final int OBJECT_ARGUMENT_INDEX = 0;
+    private static final int OFFSET_ARGUMENT_INDEX = 1;
+    private static final int VALUE_ARGUMENT_INDEX = 2;
+    private static final int LOCATION_ARGUMENT_INDEX = 3;
+
+    public CustomizedUnsafeStoreMacroNode(Invoke invoke) {
+        super(invoke, "The location argument could not be resolved to a constant.");
+        assert arguments.size() == ARGUMENT_COUNT;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        ValueNode locationArgument = arguments.get(LOCATION_ARGUMENT_INDEX);
+        if (locationArgument.isConstant()) {
+            ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
+            ValueNode offsetArgument = arguments.get(OFFSET_ARGUMENT_INDEX);
+            ValueNode valueArgument = arguments.get(VALUE_ARGUMENT_INDEX);
+            Object locationIdentityObject = locationArgument.asConstant().asObject();
+            LocationIdentity locationIdentity;
+            if (locationIdentityObject == null) {
+                locationIdentity = LocationIdentity.ANY_LOCATION;
+            } else {
+                locationIdentity = ObjectLocationIdentity.create(locationIdentityObject);
+            }
+
+            UnsafeStoreNode unsafeStoreNode = graph().add(new UnsafeStoreNode(objectArgument, offsetArgument, valueArgument, valueArgument.kind(), locationIdentity));
+            unsafeStoreNode.setStateAfter(this.stateAfter());
+            return unsafeStoreNode;
+        }
+        return this;
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastMacroNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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.typesystem;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.truffle.nodes.asserts.*;
-import com.oracle.truffle.api.*;
-
-/**
- * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class)} and
- * {@link CompilerDirectives#unsafeCast(Object, Class, Object, Object)}.
- */
-public class TypeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
-
-    private static final int ARGUMENT_COUNT = 4;
-    private static final int OBJECT_ARGUMENT_INDEX = 0;
-    private static final int CLASS_ARGUMENT_INDEX = 1;
-    private static final int RECEIVER_ARGUMENT_INDEX = 2;
-    private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 3;
-
-    public TypeCastMacroNode(Invoke invoke) {
-        super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant.");
-        assert arguments.size() == ARGUMENT_COUNT;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        ValueNode classArgument = arguments.get(CLASS_ARGUMENT_INDEX);
-        ValueNode customTypeArgument = arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX);
-        if (classArgument.isConstant() && customTypeArgument.isConstant()) {
-            Class c = (Class) classArgument.asConstant().asObject();
-            ResolvedJavaType lookupJavaType = tool.runtime().lookupJavaType(c);
-            ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
-            ValueNode receiverArgument = arguments.get(RECEIVER_ARGUMENT_INDEX);
-            Object customType = customTypeArgument.asConstant().asObject();
-            return graph().add(new TypeCastNode(objectArgument, lookupJavaType, receiverArgument, customType));
-        }
-        return this;
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/TypeCastNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2012, 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.typesystem;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public final class TypeCastNode extends FixedWithNextNode implements Lowerable, com.oracle.graal.graph.IterableNodeType, ValueProxy, Virtualizable {
-
-    @Input private ValueNode receiver;
-    @Input private ValueNode object;
-    private final Object customType;
-    private final ResolvedJavaType castTarget;
-
-    public TypeCastNode(ValueNode object, ResolvedJavaType castTarget, ValueNode receiver, Object customType) {
-        super(StampFactory.declaredNonNull(castTarget));
-        this.receiver = receiver;
-        this.object = object;
-        this.customType = customType;
-        this.castTarget = castTarget;
-    }
-
-    public ValueNode getObject() {
-        return object;
-    }
-
-    public ValueNode getReceiver() {
-        return receiver;
-    }
-
-    public ResolvedJavaType getCastTarget() {
-        return castTarget;
-    }
-
-    public Object getCustomType() {
-        return customType;
-    }
-
-    public void lower(LoweringTool tool) {
-        if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FLOATING_GUARDS) {
-            ValueAnchorNode valueAnchorNode = graph().add(new ValueAnchorNode(null));
-            PiNode piCast = graph().unique(new PiNode(object, this.stamp(), valueAnchorNode));
-            this.replaceAtUsages(piCast);
-            graph().replaceFixedWithFixed(this, valueAnchorNode);
-        }
-    }
-
-    public ValueNode getOriginalValue() {
-        return object;
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        State state = tool.getObjectState(object);
-        if (state != null && state.getState() == EscapeState.Virtual) {
-            tool.replaceWithVirtual(state.getVirtualObject());
-        }
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationMacroNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +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.typesystem;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.truffle.nodes.asserts.*;
-import com.oracle.truffle.api.*;
-
-/**
- * Macro node for method {@link CompilerDirectives#unsafeCustomization(Object, Object, Object)}.
- */
-public class UnsafeCustomizationMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
-
-    private static final int ARGUMENT_COUNT = 3;
-    private static final int RECEIVER_ARGUMENT_INDEX = 0;
-    private static final int CUSTOM_TYPE_ARGUMENT_INDEX = 1;
-    private static final int LOCATION_IDENTITY_ARGUMENT_INDEX = 2;
-
-    public UnsafeCustomizationMacroNode(Invoke invoke) {
-        super(invoke, "The custom type parameter and/or the location identity could not be reduced to a compile time constant.");
-        assert arguments.size() == ARGUMENT_COUNT;
-    }
-
-    @Override
-    public ValueNode canonical(CanonicalizerTool tool) {
-        ValueNode customTypeArgument = this.arguments.get(CUSTOM_TYPE_ARGUMENT_INDEX);
-        ValueNode locationIdentityArgument = this.arguments.get(LOCATION_IDENTITY_ARGUMENT_INDEX);
-        if (customTypeArgument.isConstant() && locationIdentityArgument.isConstant()) {
-            Object customType = customTypeArgument.asConstant().asObject();
-            Object locationIdentity = locationIdentityArgument.asConstant().asObject();
-            ValueNode receiverArgument = this.arguments.get(RECEIVER_ARGUMENT_INDEX);
-            return graph().unique(new UnsafeCustomizationNode(receiverArgument, customType, locationIdentity));
-        }
-        return this;
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeCustomizationNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2012, 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.typesystem;
-
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.calc.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-
-public final class UnsafeCustomizationNode extends FloatingNode implements LIRLowerable, com.oracle.graal.graph.IterableNodeType {
-
-    @Input private ValueNode receiver;
-    private final Object customType;
-    private final Object locationIdentity;
-
-    public UnsafeCustomizationNode(ValueNode receiver, Object customType, Object locationIdentity) {
-        super(StampFactory.object());
-        this.receiver = receiver;
-        this.customType = customType;
-        this.locationIdentity = locationIdentity;
-    }
-
-    public ValueNode getReceiver() {
-        return receiver;
-    }
-
-    public Object getCustomType() {
-        return customType;
-    }
-
-    public Object getLocationIdentity() {
-        return locationIdentity;
-    }
-
-    public void generate(LIRGeneratorTool generator) {
-        generator.setResult(this, generator.operand(receiver));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/nodes/typesystem/UnsafeTypeCastMacroNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,68 @@
+/*
+ * 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.typesystem;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.type.*;
+import com.oracle.graal.truffle.nodes.asserts.*;
+import com.oracle.truffle.api.*;
+
+/**
+ * Macro node for method {@link CompilerDirectives#unsafeCast(Object, Class, boolean)}.
+ */
+public class UnsafeTypeCastMacroNode extends NeverPartOfCompilationNode implements Canonicalizable {
+
+    private static final int ARGUMENT_COUNT = 3;
+    private static final int OBJECT_ARGUMENT_INDEX = 0;
+    private static final int CLASS_ARGUMENT_INDEX = 1;
+    private static final int CONDITION_ARGUMENT_INDEX = 2;
+
+    public UnsafeTypeCastMacroNode(Invoke invoke) {
+        super(invoke, "The class of the unsafe cast could not be reduced to a compile time constant.");
+        assert arguments.size() == ARGUMENT_COUNT;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        ValueNode classArgument = arguments.get(CLASS_ARGUMENT_INDEX);
+        if (classArgument.isConstant()) {
+            ValueNode objectArgument = arguments.get(OBJECT_ARGUMENT_INDEX);
+            ValueNode conditionArgument = arguments.get(CONDITION_ARGUMENT_INDEX);
+            Class c = (Class) classArgument.asConstant().asObject();
+            if (c == null) {
+                return objectArgument;
+            }
+            ResolvedJavaType lookupJavaType = tool.getMetaAccess().lookupJavaType(c);
+            ConditionAnchorNode valueAnchorNode = graph().add(new ConditionAnchorNode(CompareNode.createCompareNode(Condition.EQ, conditionArgument, ConstantNode.forBoolean(true, graph()))));
+            UnsafeCastNode piCast = graph().unique(new UnsafeCastNode(objectArgument, StampFactory.declaredNonNull(lookupJavaType), valueAnchorNode));
+            this.replaceAtUsages(piCast);
+            return valueAnchorNode;
+        }
+        return this;
+    }
+}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/phases/ReplaceLoadFinalPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +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.phases;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.phases.*;
-import com.oracle.graal.truffle.nodes.*;
-import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.Node.Children;
-
-public class ReplaceLoadFinalPhase extends Phase {
-
-    @Override
-    protected void run(StructuredGraph graph) {
-        for (LoadIndexedNode loadIndexedNode : graph.getNodes(LoadIndexedNode.class)) {
-            if (loadIndexedNode.array() instanceof LoadFieldNode) {
-                LoadFieldNode loadFieldNode = (LoadFieldNode) loadIndexedNode.array();
-                if (!loadFieldNode.isStatic() && isCompilationFinal(loadFieldNode.field())) {
-                    graph.replaceFixedWithFixed(loadIndexedNode, graph.add(new LoadIndexedFinalNode(loadIndexedNode.array(), loadIndexedNode.index(), loadIndexedNode.elementKind())));
-                }
-            } else if (loadIndexedNode.array() instanceof ConstantNode) {
-                graph.replaceFixedWithFixed(loadIndexedNode, graph.add(new LoadIndexedFinalNode(loadIndexedNode.array(), loadIndexedNode.index(), loadIndexedNode.elementKind())));
-            }
-        }
-    }
-
-    private static boolean isCompilationFinal(ResolvedJavaField field) {
-        assert (field.getAnnotation(Children.class) == null && field.getAnnotation(CompilerDirectives.CompilationFinal.class) == null) || Modifier.isFinal(field.getModifiers()) : "field needs to be declared as final";
-        return Modifier.isFinal(field.getModifiers()) && (field.getAnnotation(Children.class) != null || field.getAnnotation(CompilerDirectives.CompilationFinal.class) != null);
-    }
-}
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/CompilerDirectivesSubstitutions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,7 +24,6 @@
 
 import java.util.concurrent.*;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.*;
@@ -64,12 +63,51 @@
     @MacroSubstitution(macro = BailoutNode.class, isStatic = true)
     public static native void bailout(String reason);
 
-    @MacroSubstitution(macro = TypeCastMacroNode.class, isStatic = true)
-    public static native Object unsafeCast(Object value, Class clazz, Object receiver, Object customType);
+    @MacroSubstitution(macro = UnsafeTypeCastMacroNode.class, isStatic = true)
+    public static native Object unsafeCast(Object value, Class clazz, boolean condition);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
+    public static native boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
+    public static native byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
+    public static native short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
+    public static native int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
+    public static native float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
+    public static native double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeLoadMacroNode.class, isStatic = true)
+    public static native Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity);
 
-    @MacroSubstitution(macro = CustomTypeCheckMacroNode.class, isStatic = true)
-    public static native boolean customTypeCheck(boolean condition, Object value, Object customType);
+    @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
+    public static native void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
+    public static native void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
+    public static native void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
+    public static native void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity);
 
-    @MacroSubstitution(macro = UnsafeCustomizationMacroNode.class, isStatic = true)
-    public static native Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity);
+    @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
+    public static native void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
+    public static native void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
+    public static native void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity);
+
+    @MacroSubstitution(macro = CustomizedUnsafeStoreMacroNode.class, isStatic = true)
+    public static native void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity);
 }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/FrameWithoutBoxingSubstitutions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.truffle.substitutions;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.api.runtime.*;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/UnexpectedResultExceptionSubstitutions.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/substitutions/UnexpectedResultExceptionSubstitutions.java	Fri Oct 11 17:21:14 2013 +0200
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.truffle.substitutions;
 
-import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/MaterializedObjectState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -29,7 +29,7 @@
 /**
  * This class encapsulated the materialized state of an escape analyzed object.
  */
-public final class MaterializedObjectState extends EscapeObjectState implements IterableNodeType, Node.ValueNumberable {
+public final class MaterializedObjectState extends EscapeObjectState implements Node.ValueNumberable {
 
     @Input private ValueNode materializedValue;
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/nodes/VirtualObjectState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -31,7 +31,7 @@
 /**
  * This class encapsulated the virtual state of an escape analyzed object.
  */
-public final class VirtualObjectState extends EscapeObjectState implements IterableNodeType, Node.ValueNumberable {
+public final class VirtualObjectState extends EscapeObjectState implements Node.ValueNumberable {
 
     @Input private final NodeInputList<ValueNode> fieldValues;
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectList.java	Fri Oct 11 17:21:14 2013 +0200
@@ -30,8 +30,7 @@
 
 /**
  * An {@link EffectList} can be used to maintain a list of {@link Effect}s and backtrack to a
- * previous state by truncating the list. It can also maintain a level for each effect, which helps
- * in creating a string representation for the list.
+ * previous state by truncating the list.
  */
 public class EffectList implements Iterable<EffectList.Effect> {
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsBlockState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,48 +24,14 @@
 
 import java.util.*;
 
-import com.oracle.graal.nodes.*;
-
 public abstract class EffectsBlockState<T extends EffectsBlockState<T>> {
 
-    protected final IdentityHashMap<ValueNode, ValueNode> scalarAliases;
-
-    protected EffectsBlockState() {
-        scalarAliases = new IdentityHashMap<>();
-    }
-
-    protected EffectsBlockState(EffectsBlockState<T> other) {
-        scalarAliases = new IdentityHashMap<>(other.scalarAliases);
-    }
-
-    public void addScalarAlias(ValueNode alias, ValueNode value) {
-        scalarAliases.put(alias, value);
-    }
-
-    public ValueNode getScalarAlias(ValueNode alias) {
-        ValueNode result = scalarAliases.get(alias);
-        return result == null ? alias : result;
-    }
-
     @Override
     public String toString() {
-        return "Scalar Aliases: " + scalarAliases.toString();
+        return "";
     }
 
-    public void meetAliases(List<T> states) {
-        scalarAliases.putAll(states.get(0).scalarAliases);
-        for (int i = 1; i < states.size(); i++) {
-            EffectsBlockState<T> state = states.get(i);
-            meetMaps(scalarAliases, state.scalarAliases);
-        }
-    }
-
-    public boolean equivalentTo(T other) {
-        if (this == other) {
-            return true;
-        }
-        return scalarAliases.equals(other.scalarAliases);
-    }
+    protected abstract boolean equivalentTo(T other);
 
     protected static <K, V> boolean compareMaps(Map<K, V> left, Map<K, V> right) {
         if (left.size() != right.size()) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Fri Oct 11 17:21:14 2013 +0200
@@ -30,6 +30,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.graph.*;
 import com.oracle.graal.phases.graph.ReentrantBlockIterator.BlockIteratorClosure;
 import com.oracle.graal.phases.graph.ReentrantBlockIterator.LoopInfo;
@@ -40,6 +41,7 @@
 
     private final SchedulePhase schedule;
 
+    protected final NodeMap<ValueNode> aliases;
     protected final BlockMap<GraphEffectList> blockEffects;
     private final IdentityHashMap<Loop, GraphEffectList> loopMergeEffects = new IdentityHashMap<>();
 
@@ -47,6 +49,7 @@
 
     public EffectsClosure(SchedulePhase schedule) {
         this.schedule = schedule;
+        this.aliases = schedule.getCFG().graph.createNodeMap();
         this.blockEffects = new BlockMap<>(schedule.getCFG());
         for (Block block : schedule.getCFG().getBlocks()) {
             blockEffects.put(block, new GraphEffectList());
@@ -118,6 +121,7 @@
         GraphEffectList effects = blockEffects.get(block);
         FixedWithNextNode lastFixedNode = null;
         for (Node node : schedule.getBlockToNodesMap().get(block)) {
+            aliases.set(node, null);
             changed |= processNode(node, state, effects, lastFixedNode);
             if (node instanceof FixedWithNextNode) {
                 lastFixedNode = (FixedWithNextNode) node;
@@ -202,9 +206,11 @@
             this.afterMergeEffects = new GraphEffectList();
         }
 
+        /**
+         * @param states the states that should be merged.
+         */
         protected void merge(List<BlockT> states) {
             newState = getInitialState();
-            newState.meetAliases(states);
             mergeEffects.clear();
             afterMergeEffects.clear();
         }
@@ -213,4 +219,18 @@
         protected void commitEnds(List<BlockT> states) {
         }
     }
+
+    public void addScalarAlias(ValueNode node, ValueNode alias) {
+        assert !(alias instanceof VirtualObjectNode);
+        aliases.set(node, alias);
+    }
+
+    public ValueNode getScalarAlias(ValueNode node) {
+        assert !(node instanceof VirtualObjectNode);
+        if (node == null || !node.isAlive() || aliases.isNew(node)) {
+            return node;
+        }
+        ValueNode result = aliases.get(node);
+        return (result == null || result instanceof VirtualObjectNode) ? node : result;
+    }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsPhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,8 +26,8 @@
 
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.util.*;
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/GraphEffectList.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -35,9 +34,6 @@
 public class GraphEffectList extends EffectList {
 
     public void addCounterBefore(final String group, final String name, final int increment, final boolean addContext, final FixedNode position) {
-        if (!DynamicCounterNode.enabled) {
-            return;
-        }
         add(new Effect() {
 
             @Override
@@ -48,28 +44,23 @@
             @Override
             public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) {
                 assert position.isAlive();
-                DynamicCounterNode node = graph.add(new DynamicCounterNode(group, name, increment, addContext));
-                graph.addBeforeFixed(position, node);
+                DynamicCounterNode.addCounterBefore(group, name, increment, addContext, position);
             }
         });
     }
 
-    public void addSurvivingCounterBefore(final String group, final String name, final int increment, final boolean addContext, final ValueNode checkedValue, final FixedNode position) {
-        if (!DynamicCounterNode.enabled) {
-            return;
-        }
+    public void addWeakCounterCounterBefore(final String group, final String name, final int increment, final boolean addContext, final ValueNode checkedValue, final FixedNode position) {
         add(new Effect() {
 
             @Override
             public String name() {
-                return "addSurvivingCounterBefore";
+                return "addWeakCounterBefore";
             }
 
             @Override
             public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) {
                 assert position.isAlive();
-                DynamicCounterNode node = graph.add(new SurvivingCounterNode(group, name, increment, addContext, checkedValue));
-                graph.addBeforeFixed(position, node);
+                WeakCounterNode.addCounterBefore(group, name, increment, addContext, checkedValue, position);
             }
         });
     }
@@ -368,24 +359,4 @@
             }
         });
     }
-
-    public void addLowLevelCounterBefore(final String group, final String name, final int increment, final boolean addContext, final FixedNode position, final MetaAccessProvider runtime) {
-        add(new Effect() {
-
-            @Override
-            public String name() {
-                return "addLowLevelCounterBefore";
-            }
-
-            @Override
-            public void apply(StructuredGraph graph, ArrayList<Node> obsoleteNodes) {
-                DynamicCounterNode.addLowLevel(group, name, increment, addContext, position, runtime);
-            }
-
-            @Override
-            public boolean isVisible() {
-                return true;
-            }
-        });
-    }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ObjectState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -137,7 +137,7 @@
     }
 
     public void escape(ValueNode materialized, EscapeState newState) {
-        assert state == EscapeState.Virtual || (state == EscapeState.ThreadLocal && newState == EscapeState.Global);
+        assert state == EscapeState.Virtual && newState == EscapeState.Materialized;
         state = newState;
         materializedValue = materialized;
         entries = null;
@@ -146,7 +146,7 @@
 
     @Override
     public ValueNode getMaterializedValue() {
-        assert state == EscapeState.ThreadLocal || state == EscapeState.Global;
+        assert state == EscapeState.Materialized;
         return materializedValue;
     }
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationBlockState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -92,9 +92,9 @@
         return super.equivalentTo(other);
     }
 
-    public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value) {
+    public void addReadCache(ValueNode object, ResolvedJavaField identity, ValueNode value, PartialEscapeClosure<?> closure) {
         ValueNode cacheObject;
-        ObjectState obj = getObjectState(object);
+        ObjectState obj = closure.getObjectState(this, object);
         if (obj != null) {
             assert !obj.isVirtual();
             cacheObject = obj.getMaterializedValue();
@@ -104,9 +104,9 @@
         readCache.put(new ReadCacheEntry(identity, cacheObject), value);
     }
 
-    public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity) {
+    public ValueNode getReadCache(ValueNode object, ResolvedJavaField identity, PartialEscapeClosure<?> closure) {
         ValueNode cacheObject;
-        ObjectState obj = getObjectState(object);
+        ObjectState obj = closure.getObjectState(this, object);
         if (obj != null) {
             assert !obj.isVirtual();
             cacheObject = obj.getMaterializedValue();
@@ -114,13 +114,13 @@
             cacheObject = object;
         }
         ValueNode cacheValue = readCache.get(new ReadCacheEntry(identity, cacheObject));
-        obj = getObjectState(cacheValue);
+        obj = closure.getObjectState(this, cacheValue);
         if (obj != null) {
             assert !obj.isVirtual();
             cacheValue = obj.getMaterializedValue();
         } else {
             // assert !scalarAliases.containsKey(cacheValue);
-            cacheValue = getScalarAlias(cacheValue);
+            cacheValue = closure.getScalarAlias(cacheValue);
         }
         return cacheValue;
     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Fri Oct 11 17:21:14 2013 +0200
@@ -57,13 +57,13 @@
                 LoadFieldNode load = (LoadFieldNode) node;
                 if (!load.isVolatile()) {
                     ValueNode object = GraphUtil.unproxify(load.object());
-                    ValueNode cachedValue = state.getReadCache(object, load.field());
+                    ValueNode cachedValue = state.getReadCache(object, load.field(), this);
                     if (cachedValue != null) {
                         effects.replaceAtUsages(load, cachedValue);
-                        state.addScalarAlias(load, cachedValue);
+                        addScalarAlias(load, cachedValue);
                         deleted = true;
                     } else {
-                        state.addReadCache(object, load.field(), load);
+                        state.addReadCache(object, load.field(), load, this);
                     }
                 } else {
                     processIdentity(state, ANY_LOCATION);
@@ -72,24 +72,24 @@
                 StoreFieldNode store = (StoreFieldNode) node;
                 if (!store.isVolatile()) {
                     ValueNode object = GraphUtil.unproxify(store.object());
-                    ValueNode cachedValue = state.getReadCache(object, store.field());
+                    ValueNode cachedValue = state.getReadCache(object, store.field(), this);
 
-                    ValueNode value = state.getScalarAlias(store.value());
+                    ValueNode value = getScalarAlias(store.value());
                     if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
                         effects.deleteFixedNode(store);
                         deleted = true;
                     }
                     state.killReadCache(store.field());
-                    state.addReadCache(object, store.field(), value);
+                    state.addReadCache(object, store.field(), value, this);
                 } else {
                     processIdentity(state, ANY_LOCATION);
                 }
             } else if (node instanceof MemoryCheckpoint.Single) {
-                METRIC_MEMORYCHECKOINT.increment();
+                METRIC_MEMORYCHECKPOINT.increment();
                 LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
                 processIdentity(state, identity);
             } else if (node instanceof MemoryCheckpoint.Multi) {
-                METRIC_MEMORYCHECKOINT.increment();
+                METRIC_MEMORYCHECKPOINT.increment();
                 for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
                     processIdentity(state, identity);
                 }
@@ -112,7 +112,7 @@
 
         for (Map.Entry<ReadCacheEntry, ValueNode> entry : exitState.getReadCache().entrySet()) {
             if (initialState.getReadCache().get(entry.getKey()) != entry.getValue()) {
-                ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity);
+                ValueNode value = exitState.getReadCache(entry.getKey().object, entry.getKey().identity, this);
                 if (!(value instanceof ProxyNode) || ((ProxyNode) value).proxyPoint() != exitNode) {
                     ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value, null);
                     effects.addFloatingNode(proxy, "readCacheProxy");
@@ -165,7 +165,7 @@
                     PhiNode phiNode = getCachedPhi(entry, value.kind());
                     mergeEffects.addFloatingNode(phiNode, "mergeReadCache");
                     for (int i = 0; i < states.size(); i++) {
-                        afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity));
+                        afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, PEReadEliminationClosure.this));
                     }
                     newState.readCache.put(key, phiNode);
                 } else if (value != null) {
@@ -187,7 +187,7 @@
         private void mergeReadCachePhi(PhiNode phi, ResolvedJavaField identity, List<PEReadEliminationBlockState> states) {
             ValueNode[] values = new ValueNode[phi.valueCount()];
             for (int i = 0; i < phi.valueCount(); i++) {
-                ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity);
+                ValueNode value = states.get(i).getReadCache(phi.valueAt(i), identity, PEReadEliminationClosure.this);
                 if (value == null) {
                     return;
                 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -24,7 +24,6 @@
 
 import java.util.*;
 
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
 import com.oracle.graal.nodes.virtual.*;
@@ -32,7 +31,6 @@
 public abstract class PartialEscapeBlockState<T extends PartialEscapeBlockState<T>> extends EffectsBlockState<T> {
 
     protected final IdentityHashMap<VirtualObjectNode, ObjectState> objectStates = new IdentityHashMap<>();
-    protected final IdentityHashMap<ValueNode, VirtualObjectNode> objectAliases;
 
     /**
      * Final subclass of PartialEscapeBlockState, for performance and to make everything behave
@@ -49,15 +47,12 @@
     }
 
     protected PartialEscapeBlockState() {
-        objectAliases = new IdentityHashMap<>();
     }
 
     protected PartialEscapeBlockState(PartialEscapeBlockState<T> other) {
-        super(other);
         for (Map.Entry<VirtualObjectNode, ObjectState> entry : other.objectStates.entrySet()) {
             objectStates.put(entry.getKey(), entry.getValue().cloneState());
         }
-        objectAliases = new IdentityHashMap<>(other.objectAliases);
     }
 
     public ObjectState getObjectState(VirtualObjectNode object) {
@@ -69,11 +64,6 @@
         return objectStates.get(object);
     }
 
-    public ObjectState getObjectState(ValueNode value) {
-        VirtualObjectNode object = objectAliases.get(value);
-        return object == null ? null : getObjectState(object);
-    }
-
     public void materializeBefore(FixedNode fixed, VirtualObjectNode virtual, EscapeState state, GraphEffectList materializeEffects) {
         PartialEscapeClosure.METRIC_MATERIALIZATIONS.increment();
         List<AllocatedObjectNode> objects = new ArrayList<>(2);
@@ -100,8 +90,8 @@
                 values.add(null);
             }
             for (int i = 0; i < entries.length; i++) {
-                ObjectState entryObj = getObjectState(entries[i]);
-                if (entryObj != null) {
+                if (entries[i] instanceof VirtualObjectNode) {
+                    ObjectState entryObj = getObjectState((VirtualObjectNode) entries[i]);
                     if (entryObj.isVirtual()) {
                         materializeWithCommit(fixed, entryObj.getVirtualObject(), objects, locks, values, otherAllocations, state);
                     }
@@ -122,26 +112,6 @@
         VirtualUtil.trace("materialized %s as %s with values %s", virtual, representation, values);
     }
 
-    void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node, NodeBitMap usages) {
-        objectAliases.put(node, virtual);
-        if (node.isAlive()) {
-            for (Node usage : node.usages()) {
-                markVirtualUsages(usage, usages);
-            }
-        }
-    }
-
-    private void markVirtualUsages(Node node, NodeBitMap usages) {
-        if (!usages.isNew(node)) {
-            usages.mark(node);
-        }
-        if (node instanceof VirtualState) {
-            for (Node usage : node.usages()) {
-                markVirtualUsages(usage, usages);
-            }
-        }
-    }
-
     public void addObject(VirtualObjectNode virtual, ObjectState state) {
         objectStates.put(virtual, state);
     }
@@ -150,30 +120,18 @@
         return objectStates.values();
     }
 
-    public Collection<VirtualObjectNode> getVirtualObjects() {
-        return objectAliases.values();
+    public Set<VirtualObjectNode> getVirtualObjects() {
+        return objectStates.keySet();
     }
 
     @Override
     public String toString() {
-        return super.toString() + ", Object Aliases: " + objectAliases + ", Object States: " + objectStates;
-    }
-
-    @Override
-    public void meetAliases(List<T> states) {
-        super.meetAliases(states);
-        objectAliases.putAll(states.get(0).objectAliases);
-        for (int i = 1; i < states.size(); i++) {
-            meetMaps(objectAliases, states.get(i).objectAliases);
-        }
+        return super.toString() + ", Object States: " + objectStates;
     }
 
     @Override
     public boolean equivalentTo(T other) {
-        if (!compareMaps(objectAliases, other.objectAliases) || !compareMaps(objectStates, other.objectStates)) {
-            return false;
-        }
-        return super.equivalentTo(other);
+        return compareMaps(objectStates, other.objectStates);
     }
 
     protected static <K, V> boolean compareMaps(Map<K, V> left, Map<K, V> right) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Fri Oct 11 17:21:14 2013 +0200
@@ -49,7 +49,7 @@
     public static final DebugMetric METRIC_MATERIALIZATIONS_LOOP_END = Debug.metric("MaterializationsLoopEnd");
     public static final DebugMetric METRIC_ALLOCATION_REMOVED = Debug.metric("AllocationsRemoved");
 
-    public static final DebugMetric METRIC_MEMORYCHECKOINT = Debug.metric("MemoryCheckpoint");
+    public static final DebugMetric METRIC_MEMORYCHECKPOINT = Debug.metric("MemoryCheckpoint");
 
     private final NodeBitMap usages;
     private final VirtualizerToolImpl tool;
@@ -79,7 +79,7 @@
     public PartialEscapeClosure(SchedulePhase schedule, MetaAccessProvider metaAccess, Assumptions assumptions) {
         super(schedule);
         this.usages = schedule.getCFG().graph.createNodeBitMap();
-        this.tool = new VirtualizerToolImpl(usages, metaAccess, assumptions);
+        this.tool = new VirtualizerToolImpl(metaAccess, assumptions, this);
     }
 
     public Map<Invoke, Double> getHints() {
@@ -129,7 +129,7 @@
 
                         @Override
                         public void apply(Node usage, ValueNode value) {
-                            ObjectState valueObj = state.getObjectState(value);
+                            ObjectState valueObj = getObjectState(state, value);
                             if (valueObj != null) {
                                 virtual.add(valueObj);
                                 effects.replaceFirstInput(usage, value, valueObj.virtual);
@@ -158,8 +158,8 @@
                         ObjectState obj = queue.removeLast();
                         if (obj.isVirtual()) {
                             for (ValueNode field : obj.getEntries()) {
-                                ObjectState fieldObj = state.getObjectState(field);
-                                if (fieldObj != null) {
+                                if (field instanceof VirtualObjectNode) {
+                                    ObjectState fieldObj = state.getObjectState((VirtualObjectNode) field);
                                     if (fieldObj.isVirtual() && !virtual.contains(fieldObj)) {
                                         virtual.add(fieldObj);
                                         queue.addLast(fieldObj);
@@ -173,7 +173,7 @@
                         if (obj.isVirtual()) {
                             ValueNode[] fieldState = obj.getEntries().clone();
                             for (int i = 0; i < fieldState.length; i++) {
-                                ObjectState valueObj = state.getObjectState(fieldState[i]);
+                                ObjectState valueObj = getObjectState(state, fieldState[i]);
                                 if (valueObj != null) {
                                     if (valueObj.isVirtual()) {
                                         fieldState[i] = valueObj.virtual;
@@ -191,7 +191,7 @@
                 }
             }
             for (ValueNode input : node.inputs().filter(ValueNode.class)) {
-                ObjectState obj = state.getObjectState(input);
+                ObjectState obj = getObjectState(state, input);
                 if (obj != null) {
                     if (obj.isVirtual() && node instanceof MethodCallTargetNode) {
                         Invoke invoke = ((MethodCallTargetNode) node).invoke();
@@ -205,18 +205,18 @@
         return false;
     }
 
-    private static void ensureMaterialized(PartialEscapeBlockState state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) {
+    private void ensureMaterialized(BlockT state, ObjectState obj, FixedNode materializeBefore, GraphEffectList effects, DebugMetric metric) {
         assert obj != null;
         if (obj.getState() == EscapeState.Virtual) {
             metric.increment();
-            state.materializeBefore(materializeBefore, obj.virtual, EscapeState.Global, effects);
+            state.materializeBefore(materializeBefore, obj.virtual, EscapeState.Materialized, effects);
         } else {
-            assert obj.getState() == EscapeState.Global;
+            assert obj.getState() == EscapeState.Materialized;
         }
         assert !obj.isVirtual();
     }
 
-    private static void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, PartialEscapeBlockState state, ObjectState obj, GraphEffectList effects, DebugMetric metric) {
+    private void replaceWithMaterialized(ValueNode value, Node usage, FixedNode materializeBefore, BlockT state, ObjectState obj, GraphEffectList effects, DebugMetric metric) {
         ensureMaterialized(state, obj, materializeBefore, effects, metric);
         effects.replaceFirstInput(usage, value, obj.getMaterializedValue());
     }
@@ -226,7 +226,7 @@
         HashMap<VirtualObjectNode, ProxyNode> proxies = new HashMap<>();
 
         for (ProxyNode proxy : exitNode.proxies()) {
-            ObjectState obj = exitState.getObjectState(proxy.value());
+            ObjectState obj = getObjectState(exitState, proxy.value());
             if (obj != null) {
                 proxies.put(obj.virtual, proxy);
             }
@@ -236,8 +236,7 @@
             if (obj.isVirtual()) {
                 for (int i = 0; i < obj.getEntries().length; i++) {
                     ValueNode value = obj.getEntry(i);
-                    ObjectState valueObj = exitState.getObjectState(value);
-                    if (valueObj == null) {
+                    if (!(value instanceof VirtualObjectNode)) {
                         if (exitNode.loopBegin().isPhiAtMerge(value) || initialObj == null || !initialObj.isVirtual() || initialObj.getEntry(i) != value) {
                             ProxyNode proxy = new ProxyNode(value, exitNode, PhiType.Value, null);
                             obj.setEntry(i, proxy);
@@ -327,16 +326,21 @@
              * and so on.
              */
 
-            HashSet<VirtualObjectNode> virtualObjects = new HashSet<>(newState.getVirtualObjects());
+            HashSet<VirtualObjectNode> virtualObjTemp = new HashSet<>(states.get(0).getVirtualObjects());
+            for (int i = 1; i < states.size(); i++) {
+                virtualObjTemp.retainAll(states.get(i).getVirtualObjects());
+            }
+
             boolean materialized;
             do {
                 mergeEffects.clear();
                 afterMergeEffects.clear();
                 materialized = false;
-                for (VirtualObjectNode object : virtualObjects) {
+                for (VirtualObjectNode object : virtualObjTemp) {
                     ObjectState[] objStates = new ObjectState[states.size()];
                     for (int i = 0; i < states.size(); i++) {
-                        objStates[i] = states.get(i).getObjectState(object);
+                        objStates[i] = states.get(i).getObjectStateOptional(object);
+                        assert objStates[i] != null;
                     }
                     int virtual = 0;
                     ObjectState startObj = objStates[0];
@@ -359,16 +363,16 @@
                             PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object);
                             mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi");
                             for (int i = 0; i < states.size(); i++) {
-                                PartialEscapeBlockState state = states.get(i);
+                                BlockT state = states.get(i);
                                 ObjectState obj = objStates[i];
                                 materialized |= obj.isVirtual();
                                 Block predecessor = mergeBlock.getPredecessors().get(i);
                                 ensureMaterialized(state, obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE);
                                 afterMergeEffects.addPhiInput(materializedValuePhi, obj.getMaterializedValue());
                             }
-                            newState.addObject(object, new ObjectState(object, materializedValuePhi, EscapeState.Global, null));
+                            newState.addObject(object, new ObjectState(object, materializedValuePhi, EscapeState.Materialized, null));
                         } else {
-                            newState.addObject(object, new ObjectState(object, singleValue, EscapeState.Global, null));
+                            newState.addObject(object, new ObjectState(object, singleValue, EscapeState.Materialized, null));
                         }
                     } else {
                         assert virtual == states.size();
@@ -396,8 +400,8 @@
                                         break outer;
                                     }
                                     ValueNode[] fields = objStates[i].getEntries();
-                                    ObjectState obj = states.get(i).getObjectState(fields[index]);
-                                    if (obj != null) {
+                                    if (fields[index] instanceof VirtualObjectNode) {
+                                        ObjectState obj = states.get(i).getObjectState((VirtualObjectNode) fields[index]);
                                         materialized |= obj.isVirtual();
                                         Block predecessor = mergeBlock.getPredecessors().get(i);
                                         ensureMaterialized(states.get(i), obj, predecessor.getEndNode(), blockEffects.get(predecessor), METRIC_MATERIALIZATIONS_MERGE);
@@ -421,6 +425,7 @@
         }
 
         private boolean processPhi(PhiNode phi, List<BlockT> states) {
+            aliases.set(phi, null);
             assert states.size() == phi.valueCount();
             int virtualInputs = 0;
             boolean materialized = false;
@@ -430,7 +435,7 @@
             boolean hasIdentity = false;
             for (int i = 0; i < phi.valueCount(); i++) {
                 ValueNode value = phi.valueAt(i);
-                ObjectState obj = states.get(i).getObjectState(value);
+                ObjectState obj = getObjectState(states.get(i), value);
                 if (obj != null) {
                     if (obj.isVirtual()) {
                         virtualInputs++;
@@ -460,10 +465,10 @@
                 // nothing to do...
             } else if (virtualInputs == phi.valueCount()) {
                 if (sameObject != null) {
-                    newState.addAndMarkAlias(sameObject, phi, usages);
+                    addAndMarkAlias(sameObject, phi);
                 } else if (sameType != null && sameEntryCount != -1) {
                     if (!hasIdentity) {
-                        VirtualObjectNode virtual = getValueObjectVirtual(phi, states.get(0).getObjectState(phi.valueAt(0)).virtual);
+                        VirtualObjectNode virtual = getValueObjectVirtual(phi, getObjectState(states.get(0), phi.valueAt(0)).virtual);
 
                         PhiNode[] phis = getValueObjectMergePhis(phi, virtual.entryCount());
                         for (int i = 0; i < virtual.entryCount(); i++) {
@@ -473,13 +478,13 @@
                             }
                             mergeEffects.addFloatingNode(phis[i], "valueObjectPhi");
                             for (int i2 = 0; i2 < phi.valueCount(); i2++) {
-                                afterMergeEffects.addPhiInput(phis[i], states.get(i2).getObjectState(phi.valueAt(i2)).getEntry(i));
+                                afterMergeEffects.addPhiInput(phis[i], getObjectState(states.get(i2), phi.valueAt(i2)).getEntry(i));
                             }
                         }
                         mergeEffects.addFloatingNode(virtual, "valueObjectNode");
                         newState.addObject(virtual, new ObjectState(virtual, Arrays.copyOf(phis, phis.length, ValueNode[].class), EscapeState.Virtual, null));
-                        newState.addAndMarkAlias(virtual, virtual, usages);
-                        newState.addAndMarkAlias(virtual, phi, usages);
+                        addAndMarkAlias(virtual, virtual);
+                        addAndMarkAlias(virtual, phi);
                     } else {
                         materialize = true;
                     }
@@ -493,7 +498,7 @@
             if (materialize) {
                 for (int i = 0; i < phi.valueCount(); i++) {
                     ValueNode value = phi.valueAt(i);
-                    ObjectState obj = states.get(i).getObjectState(value);
+                    ObjectState obj = getObjectState(states.get(i), value);
                     if (obj != null) {
                         materialized |= obj.isVirtual();
                         Block predecessor = mergeBlock.getPredecessors().get(i);
@@ -504,4 +509,39 @@
             return materialized;
         }
     }
+
+    public ObjectState getObjectState(PartialEscapeBlockState<?> state, ValueNode value) {
+        if (value == null) {
+            return null;
+        }
+        if (value.isAlive() && !aliases.isNew(value)) {
+            ValueNode object = aliases.get(value);
+            return object instanceof VirtualObjectNode ? state.getObjectStateOptional((VirtualObjectNode) object) : null;
+        } else {
+            if (value instanceof VirtualObjectNode) {
+                return state.getObjectStateOptional((VirtualObjectNode) value);
+            }
+            return null;
+        }
+    }
+
+    void addAndMarkAlias(VirtualObjectNode virtual, ValueNode node) {
+        if (node.isAlive()) {
+            aliases.set(node, virtual);
+            for (Node usage : node.usages()) {
+                markVirtualUsages(usage);
+            }
+        }
+    }
+
+    private void markVirtualUsages(Node node) {
+        if (!usages.isNew(node)) {
+            usages.mark(node);
+        }
+        if (node instanceof VirtualState) {
+            for (Node usage : node.usages()) {
+                markVirtualUsages(usage);
+            }
+        }
+    }
 }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java	Fri Oct 11 17:21:14 2013 +0200
@@ -72,9 +72,9 @@
     @Override
     protected Closure<?> createEffectsClosure(PhaseContext context, SchedulePhase schedule) {
         if (readElimination) {
-            return new PEReadEliminationClosure(schedule, context.getRuntime(), context.getAssumptions());
+            return new PEReadEliminationClosure(schedule, context.getMetaAccess(), context.getAssumptions());
         } else {
-            return new PartialEscapeClosure.Final(schedule, context.getRuntime(), context.getAssumptions());
+            return new PartialEscapeClosure.Final(schedule, context.getMetaAccess(), context.getAssumptions());
         }
     }
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java	Fri Oct 11 17:21:14 2013 +0200
@@ -64,14 +64,14 @@
         public abstract boolean conflicts(LocationIdentity other);
     }
 
-    static class LoadCacheEntry extends CacheEntry<ResolvedJavaField> {
+    static class LoadCacheEntry extends CacheEntry<LocationIdentity> {
 
-        public LoadCacheEntry(ValueNode object, ResolvedJavaField identity) {
+        public LoadCacheEntry(ValueNode object, LocationIdentity identity) {
             super(object, identity);
         }
 
         @Override
-        public CacheEntry<ResolvedJavaField> duplicateWithObject(ValueNode newObject) {
+        public CacheEntry<LocationIdentity> duplicateWithObject(ValueNode newObject) {
             return new LoadCacheEntry(newObject, identity);
         }
 
@@ -103,7 +103,6 @@
     }
 
     public ReadEliminationBlockState(ReadEliminationBlockState other) {
-        super(other);
         readCache = new HashMap<>(other.readCache);
     }
 
@@ -114,10 +113,7 @@
 
     @Override
     public boolean equivalentTo(ReadEliminationBlockState other) {
-        if (!compareMapsNoSize(readCache, other.readCache)) {
-            return false;
-        }
-        return super.equivalentTo(other);
+        return compareMapsNoSize(readCache, other.readCache);
     }
 
     public void addCacheEntry(CacheEntry<?> identifier, ValueNode value) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Fri Oct 11 17:21:14 2013 +0200
@@ -61,7 +61,7 @@
                 ValueNode cachedValue = state.getCacheEntry(identifier);
                 if (cachedValue != null) {
                     effects.replaceAtUsages(load, cachedValue);
-                    state.addScalarAlias(load, cachedValue);
+                    addScalarAlias(load, cachedValue);
                     deleted = true;
                 } else {
                     state.addCacheEntry(identifier, load);
@@ -76,12 +76,12 @@
                 LoadCacheEntry identifier = new LoadCacheEntry(object, store.field());
                 ValueNode cachedValue = state.getCacheEntry(identifier);
 
-                ValueNode value = state.getScalarAlias(store.value());
+                ValueNode value = getScalarAlias(store.value());
                 if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
                     effects.deleteFixedNode(store);
                     deleted = true;
                 }
-                state.killReadCache((LocationIdentity) store.field());
+                state.killReadCache(store.field());
                 state.addCacheEntry(identifier, value);
             } else {
                 processIdentity(state, ANY_LOCATION);
@@ -94,12 +94,26 @@
                 ValueNode cachedValue = state.getCacheEntry(identifier);
                 if (cachedValue != null) {
                     effects.replaceAtUsages(read, cachedValue);
-                    state.addScalarAlias(read, cachedValue);
+                    addScalarAlias(read, cachedValue);
                     deleted = true;
                 } else {
                     state.addCacheEntry(identifier, read);
                 }
             }
+        } else if (node instanceof UnsafeLoadNode) {
+            UnsafeLoadNode load = (UnsafeLoadNode) node;
+            if (load.offset().isConstant() && load.getLocationIdentity() != LocationIdentity.ANY_LOCATION) {
+                ValueNode object = GraphUtil.unproxify(load.object());
+                LoadCacheEntry identifier = new LoadCacheEntry(object, load.getLocationIdentity());
+                ValueNode cachedValue = state.getCacheEntry(identifier);
+                if (cachedValue != null) {
+                    effects.replaceAtUsages(load, cachedValue);
+                    addScalarAlias(load, cachedValue);
+                    deleted = true;
+                } else {
+                    state.addCacheEntry(identifier, load);
+                }
+            }
         } else if (node instanceof WriteNode) {
             WriteNode write = (WriteNode) node;
             if (write.location() instanceof ConstantLocationNode) {
@@ -107,7 +121,7 @@
                 ReadCacheEntry identifier = new ReadCacheEntry(object, write.location());
                 ValueNode cachedValue = state.getCacheEntry(identifier);
 
-                ValueNode value = state.getScalarAlias(write.value());
+                ValueNode value = getScalarAlias(write.value());
                 if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
                     effects.deleteFixedNode(write);
                     deleted = true;
@@ -117,6 +131,23 @@
             } else {
                 processIdentity(state, write.location().getLocationIdentity());
             }
+        } else if (node instanceof UnsafeStoreNode) {
+            UnsafeStoreNode write = (UnsafeStoreNode) node;
+            if (write.offset().isConstant() && write.getLocationIdentity() != LocationIdentity.ANY_LOCATION) {
+                ValueNode object = GraphUtil.unproxify(write.object());
+                LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity());
+                ValueNode cachedValue = state.getCacheEntry(identifier);
+
+                ValueNode value = getScalarAlias(write.value());
+                if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
+                    effects.deleteFixedNode(write);
+                    deleted = true;
+                }
+                processIdentity(state, write.getLocationIdentity());
+                state.addCacheEntry(identifier, value);
+            } else {
+                processIdentity(state, write.getLocationIdentity());
+            }
         } else if (node instanceof MemoryCheckpoint.Single) {
             LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
             processIdentity(state, identity);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualizerToolImpl.java	Fri Oct 11 17:21:14 2013 +0200
@@ -36,18 +36,18 @@
 
 class VirtualizerToolImpl implements VirtualizerTool {
 
-    private final NodeBitMap usages;
     private final MetaAccessProvider metaAccess;
     private final Assumptions assumptions;
+    private final PartialEscapeClosure<?> closure;
 
-    VirtualizerToolImpl(NodeBitMap usages, MetaAccessProvider metaAccess, Assumptions assumptions) {
-        this.usages = usages;
+    VirtualizerToolImpl(MetaAccessProvider metaAccess, Assumptions assumptions, PartialEscapeClosure<?> closure) {
         this.metaAccess = metaAccess;
         this.assumptions = assumptions;
+        this.closure = closure;
     }
 
     private boolean deleted;
-    private PartialEscapeBlockState state;
+    private PartialEscapeBlockState<?> state;
     private ValueNode current;
     private FixedNode position;
     private GraphEffectList effects;
@@ -76,15 +76,15 @@
 
     @Override
     public State getObjectState(ValueNode value) {
-        return state.getObjectState(value);
+        return closure.getObjectState(state, value);
     }
 
     @Override
     public void setVirtualEntry(State objectState, int index, ValueNode value) {
         ObjectState obj = (ObjectState) objectState;
         assert obj != null && obj.isVirtual() : "not virtual: " + obj;
-        ObjectState valueState = state.getObjectState(value);
-        ValueNode newValue = value;
+        ObjectState valueState = closure.getObjectState(state, value);
+        ValueNode newValue;
         if (valueState == null) {
             newValue = getReplacedValue(value);
             assert obj.getEntry(index) == null || obj.getEntry(index).kind() == newValue.kind() || (isObjectEntry(obj.getEntry(index)) && isObjectEntry(newValue));
@@ -105,19 +105,13 @@
     }
 
     @Override
-    public ValueNode getMaterializedValue(ValueNode value) {
-        ObjectState obj = state.getObjectState(value);
-        return obj != null && !obj.isVirtual() ? obj.getMaterializedValue() : null;
-    }
-
-    @Override
     public ValueNode getReplacedValue(ValueNode original) {
-        return state.getScalarAlias(original);
+        return closure.getScalarAlias(original);
     }
 
     @Override
     public void replaceWithVirtual(VirtualObjectNode virtual) {
-        state.addAndMarkAlias(virtual, current, usages);
+        closure.addAndMarkAlias(virtual, current);
         if (current instanceof FixedWithNextNode) {
             effects.deleteFixedNode((FixedWithNextNode) current);
         }
@@ -126,8 +120,8 @@
 
     @Override
     public void replaceWithValue(ValueNode replacement) {
-        effects.replaceAtUsages(current, state.getScalarAlias(replacement));
-        state.addScalarAlias(current, replacement);
+        effects.replaceAtUsages(current, closure.getScalarAlias(replacement));
+        closure.addScalarAlias(current, replacement);
         deleted = true;
     }
 
@@ -154,16 +148,21 @@
     @Override
     public void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, int[] locks) {
         VirtualUtil.trace("{{%s}} ", current);
-        if (virtualObject.isAlive()) {
-            state.addAndMarkAlias(virtualObject, virtualObject, usages);
-        } else {
+        if (!virtualObject.isAlive()) {
             effects.addFloatingNode(virtualObject, "newVirtualObject");
         }
         for (int i = 0; i < entryState.length; i++) {
-            entryState[i] = state.getScalarAlias(entryState[i]);
+            if (!(entryState[i] instanceof VirtualObjectNode)) {
+                ObjectState v = closure.getObjectState(state, entryState[i]);
+                if (v != null) {
+                    entryState[i] = v.isVirtual() ? v.getVirtualObject() : v.getMaterializedValue();
+                } else {
+                    entryState[i] = closure.getScalarAlias(entryState[i]);
+                }
+            }
         }
         state.addObject(virtualObject, new ObjectState(virtualObject, entryState, EscapeState.Virtual, locks));
-        state.addAndMarkAlias(virtualObject, virtualObject, usages);
+        closure.addAndMarkAlias(virtualObject, virtualObject);
         PartialEscapeClosure.METRIC_ALLOCATION_REMOVED.increment();
     }
 
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.word.nodes;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
@@ -55,7 +57,8 @@
         return input;
     }
 
-    public ValueNode canonical(CanonicalizerTool tool) {
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
         if (usages().count() == 0) {
             /* If the cast is unused, it can be eliminated. */
             return input;
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/TypeSystemTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -58,6 +58,10 @@
     @TypeSystemReference(SimpleTypes.class)
     public abstract static class ValueNode extends Node {
 
+        public ValueNode() {
+            super(null);
+        }
+
         public int executeInt(VirtualFrame frame) throws UnexpectedResultException {
             return SimpleTypesGen.SIMPLETYPES.expectInteger(execute(frame));
         }
@@ -105,6 +109,7 @@
         @Child private E node;
 
         public TestRootNode(E node) {
+            super(null);
             this.node = adoptChild(node);
         }
 
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ArgumentsTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -75,6 +75,7 @@
         @Children private TestArgumentNode[] children;
 
         TestRootNode(TestArgumentNode[] children) {
+            super(null);
             this.children = adoptChildren(children);
         }
 
@@ -93,6 +94,7 @@
         private final int index;
 
         TestArgumentNode(int index) {
+            super(null);
             this.index = index;
         }
 
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/CallTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -60,6 +60,7 @@
         private final CallTarget secondTarget;
 
         DualCallNode(CallTarget firstTarget, CallTarget secondTarget) {
+            super(null);
             this.firstTarget = firstTarget;
             this.secondTarget = secondTarget;
         }
@@ -75,6 +76,7 @@
         private final int value;
 
         public ConstantRootNode(int value) {
+            super(null);
             this.value = value;
         }
 
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildNodeTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -78,6 +78,7 @@
         @Child private TestChildNode right;
 
         public TestRootNode(TestChildNode left, TestChildNode right) {
+            super(null);
             this.left = adoptChild(left);
             this.right = adoptChild(right);
         }
@@ -90,6 +91,10 @@
 
     class TestChildNode extends Node {
 
+        public TestChildNode() {
+            super(null);
+        }
+
         public int execute() {
             return 21;
         }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ChildrenNodesTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -71,6 +71,7 @@
         @Children private final TestChildNode[] children;
 
         public TestRootNode(TestChildNode[] children) {
+            super(null);
             this.children = adoptChildren(children);
         }
 
@@ -86,6 +87,10 @@
 
     class TestChildNode extends Node {
 
+        public TestChildNode() {
+            super(null);
+        }
+
         public int execute() {
             return 21;
         }
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FinalFieldTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -65,6 +65,7 @@
         @Children TestChildNode[] children;
 
         public TestRootNode(TestChildNode[] children) {
+            super(null);
             this.children = adoptChildren(children);
         }
 
@@ -83,6 +84,7 @@
         private final int value;
 
         public TestChildNode(int value) {
+            super(null);
             this.value = value;
         }
 
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameSlotTypeSpecializationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -63,6 +63,7 @@
         @Child TestChildNode right;
 
         public TestRootNode(TestChildNode left, TestChildNode right) {
+            super(null);
             this.left = adoptChild(left);
             this.right = adoptChild(right);
         }
@@ -76,6 +77,10 @@
 
     abstract class TestChildNode extends Node {
 
+        protected TestChildNode() {
+            super(null);
+        }
+
         abstract Object execute(VirtualFrame frame);
     }
 
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/FrameTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -77,6 +77,7 @@
         @Child TestChildNode right;
 
         public TestRootNode(TestChildNode left, TestChildNode right) {
+            super(null);
             this.left = adoptChild(left);
             this.right = adoptChild(right);
         }
@@ -89,6 +90,10 @@
 
     abstract class TestChildNode extends Node {
 
+        public TestChildNode() {
+            super(null);
+        }
+
         abstract int execute(VirtualFrame frame);
     }
 
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReplaceTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -84,6 +84,7 @@
         @Children private final ValueNode[] children;
 
         public TestRootNode(ValueNode[] children) {
+            super(null);
             this.children = adoptChildren(children);
         }
 
@@ -99,6 +100,10 @@
 
     abstract class ValueNode extends Node {
 
+        public ValueNode() {
+            super(null);
+        }
+
         abstract int execute();
     }
 
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/ReturnTypeSpecializationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -62,6 +62,7 @@
         @Child TestChildNode right;
 
         public TestRootNode(TestChildNode left, TestChildNode right) {
+            super(null);
             this.left = adoptChild(left);
             this.right = adoptChild(right);
         }
@@ -75,6 +76,10 @@
 
     abstract class TestChildNode extends Node {
 
+        public TestChildNode() {
+            super(null);
+        }
+
         abstract Object execute(VirtualFrame frame);
 
         int executeInt(VirtualFrame frame) throws UnexpectedResultException {
--- a/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api.test/src/com/oracle/truffle/api/test/RootNodeTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -59,6 +59,10 @@
 
     class TestRootNode extends RootNode {
 
+        public TestRootNode() {
+            super(null);
+        }
+
         @Override
         public Object execute(VirtualFrame frame) {
             return 42;
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/CompilerDirectives.java	Fri Oct 11 17:21:14 2013 +0200
@@ -25,13 +25,16 @@
 package com.oracle.truffle.api;
 
 import java.lang.annotation.*;
+import java.lang.reflect.*;
 import java.util.concurrent.*;
 
+import sun.misc.*;
+
 /**
  * Directives that influence the optimizations of the Truffle compiler. All of the operations have
  * no effect when executed in the Truffle interpreter.
  */
-public class CompilerDirectives {
+public final class CompilerDirectives {
 
     public static final double LIKELY_PROBABILITY = 0.75;
     public static final double UNLIKELY_PROBABILITY = 1.0 - LIKELY_PROBABILITY;
@@ -39,6 +42,22 @@
     public static final double SLOWPATH_PROBABILITY = 0.0001;
     public static final double FASTPATH_PROBABILITY = 1.0 - SLOWPATH_PROBABILITY;
 
+    private static final Unsafe UNSAFE = getUnsafe();
+
+    private static Unsafe getUnsafe() {
+        try {
+            return Unsafe.getUnsafe();
+        } catch (SecurityException e) {
+        }
+        try {
+            Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafeInstance.setAccessible(true);
+            return (Unsafe) theUnsafeInstance.get(Unsafe.class);
+        } catch (Exception e) {
+            throw new RuntimeException("exception while trying to get Unsafe.theUnsafe via reflection:", e);
+        }
+    }
+
     /**
      * Directive for the compiler to discontinue compilation at this code position and instead
      * insert a transfer to the interpreter.
@@ -130,72 +149,275 @@
     }
 
     /**
-     * Marks methods that are considered unsafe. Wrong usage of those methods can lead to unexpected
-     * behavior including a crash of the runtime. Therefore, special care should be taken.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target({ElementType.METHOD})
-    public @interface Unsafe {
-    }
-
-    /**
-     * Treats the given value as a value of the given class. The class must evaluate to a constant.
+     * Casts the given value to the value of the given type without any checks. The class must
+     * evaluate to a constant. The condition parameter gives a hint to the compiler under which
+     * circumstances this cast can be moved to an earlier location in the program.
      * 
      * @param value the value that is known to have the specified type
-     * @param clazz the specified type of the value
-     * @return the value
-     */
-    @Unsafe
-    public static <T> T unsafeCast(Object value, Class<T> clazz) {
-        return unsafeCast(value, clazz, null, null);
-    }
-
-    /**
-     * Associates the given type token with the given value for the case that condition is true.
-     * 
-     * @param condition the custom type check
-     * @param value the value that is of the given custom type after the check
-     * @param customType the custom type that should be associated with the value
-     * @return the type check condition
-     */
-    public static boolean customTypeCheck(boolean condition, Object value, Object customType) {
-        return condition;
-    }
-
-    /**
-     * Treats the given value as a value of the given class. The class must evaluate to a constant.
-     * If the compiler can prove that the given value is of the given custom type, the cast is safe.
-     * 
-     * @param value the value that is known to have the specified type
-     * @param clazz the specified type of the value
-     * @param receiver the receiver on which the custom type is tested
-     * @param customType the custom type that if present on a value makes this unsafe cast safe
-     * @return the value
+     * @param type the specified new type of the value
+     * @param condition the condition that makes this cast safe also at an earlier location of the
+     *            program
+     * @return the value to be casted to the new type
      */
     @SuppressWarnings("unchecked")
-    @Unsafe
-    public static <T> T unsafeCast(Object value, Class<T> clazz, Object receiver, Object customType) {
+    public static <T> T unsafeCast(Object value, Class<T> type, boolean condition) {
         return (T) value;
     }
 
     /**
-     * Proxies an object instance into an instance that adds a custom location identity on its
-     * accesses via sun.misc.Unsafe. This means that the accesses on these kind of location
-     * identities can only alias among themselves. It also allows to specify a custom type for the
-     * receiver values of follow-up unsafe accesses. Both the custom type and the location identity
-     * must evaluate to a constant. Furthermore, you should use the proxied receiver object
-     * immediately for one read or write access via a sun.misc.Unsafe method and not store it
-     * anywhere.
+     * 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
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static boolean unsafeGetBoolean(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getBoolean(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a byte 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
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static byte unsafeGetByte(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getByte(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a short 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
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static short unsafeGetShort(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getShort(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a int 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
+     * numbering.
      * 
-     * @param receiver the object that is accessed via sun.misc.Unsafe
-     * @param customType the expected type of the receiver object of follow-up unsafe accesses
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static int unsafeGetInt(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getInt(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a long 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
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static long unsafeGetLong(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getLong(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a float 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
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static float unsafeGetFloat(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getFloat(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a double 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
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
      * @param locationIdentity the location identity token that can be used for improved global
      *            value numbering or null
      * @return the accessed value
      */
-    @Unsafe
-    public static Object unsafeCustomization(Object receiver, Object customType, Object locationIdentity) {
-        return receiver;
+    public static double unsafeGetDouble(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getDouble(receiver, offset);
+    }
+
+    /**
+     * Unsafe access to a Object 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
+     * numbering.
+     * 
+     * @param receiver the object that is accessed
+     * @param offset the offset at which to access the object in bytes
+     * @param condition the condition that makes this access safe also at an earlier location in the
+     *            program
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     * @return the accessed value
+     */
+    public static Object unsafeGetObject(Object receiver, long offset, boolean condition, Object locationIdentity) {
+        return UNSAFE.getObject(receiver, offset);
+    }
+
+    /**
+     * Write a boolean value within an object. The location identity gives a hint to the compiler
+     * for improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutBoolean(Object receiver, long offset, boolean value, Object locationIdentity) {
+        UNSAFE.putBoolean(receiver, offset, value);
+    }
+
+    /**
+     * Write a byte value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutByte(Object receiver, long offset, byte value, Object locationIdentity) {
+        UNSAFE.putByte(receiver, offset, value);
+    }
+
+    /**
+     * Write a short value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutShort(Object receiver, long offset, short value, Object locationIdentity) {
+        UNSAFE.putShort(receiver, offset, value);
+    }
+
+    /**
+     * Write a int value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutInt(Object receiver, long offset, int value, Object locationIdentity) {
+        UNSAFE.putInt(receiver, offset, value);
+    }
+
+    /**
+     * Write a long value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutLong(Object receiver, long offset, long value, Object locationIdentity) {
+        UNSAFE.putLong(receiver, offset, value);
+    }
+
+    /**
+     * Write a float value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutFloat(Object receiver, long offset, float value, Object locationIdentity) {
+        UNSAFE.putFloat(receiver, offset, value);
+    }
+
+    /**
+     * Write a double value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutDouble(Object receiver, long offset, double value, Object locationIdentity) {
+        UNSAFE.putDouble(receiver, offset, value);
+    }
+
+    /**
+     * Write a Object value within an object. The location identity gives a hint to the compiler for
+     * improved global value numbering.
+     * 
+     * @param receiver the object that is written to
+     * @param offset the offset at which to write to the object in bytes
+     * @param value the value to be written
+     * @param locationIdentity the location identity token that can be used for improved global
+     *            value numbering or null
+     */
+    public static void unsafePutObject(Object receiver, long offset, Object value, Object locationIdentity) {
+        UNSAFE.putObject(receiver, offset, value);
     }
 
     /**
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntime.java	Fri Oct 11 17:21:14 2013 +0200
@@ -77,6 +77,14 @@
     Assumption createAssumption(String name);
 
     /**
+     * Creates a new virtual frame object that can be used to store values and is potentially
+     * optimizable by the runtime.
+     * 
+     * @return the newly created virtual frame object
+     */
+    VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor);
+
+    /**
      * Creates a new materialized frame object that can be used to store values.
      * 
      * @return the newly created materialized frame object
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/frame/Frame.java	Fri Oct 11 17:21:14 2013 +0200
@@ -47,7 +47,6 @@
      * @param clazz the known type of the arguments object as a compile time constant
      * @return the arguments used when calling this method
      */
-    @CompilerDirectives.Unsafe
     <T extends Arguments> T getArguments(Class<T> clazz);
 
     /**
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultTruffleRuntime.java	Fri Oct 11 17:21:14 2013 +0200
@@ -50,6 +50,11 @@
     }
 
     @Override
+    public VirtualFrame createVirtualFrame(PackedFrame caller, Arguments arguments, FrameDescriptor frameDescriptor) {
+        return new DefaultVirtualFrame(frameDescriptor, caller, arguments);
+    }
+
+    @Override
     public MaterializedFrame createMaterializedFrame(Arguments arguments) {
         return createMaterializedFrame(arguments, new FrameDescriptor());
     }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -31,6 +31,7 @@
 
 import sun.misc.*;
 
+import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.nodes.Node.Child;
 import com.oracle.truffle.api.nodes.Node.Children;
 
@@ -346,14 +347,14 @@
         return nodes;
     }
 
-    public static void replaceChild(Node parent, Node oldChild, Node newChild) {
+    public static boolean replaceChild(Node parent, Node oldChild, Node newChild) {
         NodeClass nodeClass = NodeClass.get(parent.getClass());
 
         for (long fieldOffset : nodeClass.getChildOffsets()) {
             if (unsafe.getObject(parent, fieldOffset) == oldChild) {
                 assert assertAssignable(nodeClass, fieldOffset, newChild);
                 unsafe.putObject(parent, fieldOffset, newChild);
-                return;
+                return true;
             }
         }
 
@@ -366,11 +367,12 @@
                     if (array[i] == oldChild) {
                         assert assertAssignable(nodeClass, fieldOffset, newChild);
                         array[i] = newChild;
-                        return;
+                        return true;
                     }
                 }
             }
         }
+        return false;
     }
 
     private static boolean assertAssignable(NodeClass clazz, long fieldOffset, Object newValue) {
@@ -637,6 +639,66 @@
         p.flush();
     }
 
+    public static String printSourceAttributionTree(Node node) {
+        StringWriter out = new StringWriter();
+        printSourceAttributionTree(new PrintWriter(out), null, node, 1);
+        return out.toString();
+    }
+
+    public static void printSourceAttributionTree(OutputStream out, Node node) {
+        printSourceAttributionTree(new PrintWriter(out), null, node, 1);
+    }
+
+    private static void printSourceAttributionTree(PrintWriter p, Node parent, Node node, int level) {
+        if (node == null) {
+            return;
+        }
+        if (parent == null) {
+            // Add some preliminary information before starting with the root node
+            final SourceSection sourceSection = node.getSourceSection();
+            if (sourceSection != null) {
+                final String txt = sourceSection.getSource().getCode();
+                p.println("Full source len=(" + txt.length() + ")  ___" + txt + "___");
+                p.println("AST source attribution:");
+            }
+        }
+        final StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < level; i++) {
+            sb.append("| ");
+        }
+
+        if (parent != null) {
+            String childName = "";
+            NodeField[] fields = NodeClass.get(parent.getClass()).fields;
+            for (NodeField field : fields) {
+                Object value = field.loadValue(parent);
+                if (value == node) {
+                    childName = field.getName();
+                    break;
+                } else if (value instanceof Node[]) {
+                    int index = 0;
+                    for (Node arrayNode : (Node[]) value) {
+                        if (arrayNode == node) {
+                            childName = field.getName() + "[" + index + "]";
+                            break;
+                        }
+                        index++;
+                    }
+                }
+            }
+            sb.append(childName);
+        }
+
+        sb.append("  (" + node.getClass().getSimpleName() + ")  ");
+        sb.append(displaySourceAttribution(node));
+        p.println(sb.toString());
+
+        for (Node child : node.getChildren()) {
+            printSourceAttributionTree(p, node, child, level + 1);
+        }
+        p.flush();
+    }
+
     /**
      * Prints a human readable form of a {@link Node} AST to the given {@link PrintStream}. This
      * print method does not check for cycles in the node structure.
@@ -724,4 +786,34 @@
     private static String nodeName(Node node) {
         return node.getClass().getSimpleName();
     }
+
+    private static String displaySourceAttribution(Node node) {
+        final SourceSection section = node.getSourceSection();
+        if (section != null) {
+            final String srcText = section.getCode();
+            final StringBuilder sb = new StringBuilder();
+            sb.append("source:  len=" + srcText.length());
+            sb.append(" (" + section.getCharIndex() + "," + (section.getCharEndIndex() - 1) + ")");
+            sb.append(" ___" + srcText + "___");
+            return sb.toString();
+        }
+        return "";
+    }
+
+    public static boolean verify(Node root) {
+        Iterable<Node> children = root.getChildren();
+        for (Node child : children) {
+            if (child != null) {
+                if (child.getParent() != root) {
+                    throw new AssertionError(toStringWithClass(child) + ": actual parent=" + toStringWithClass(child.getParent()) + " expected parent=" + toStringWithClass(root));
+                }
+                verify(child);
+            }
+        }
+        return true;
+    }
+
+    private static String toStringWithClass(Object obj) {
+        return obj == null ? "null" : obj + "(" + obj.getClass().getName() + ")";
+    }
 }
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -28,6 +28,11 @@
 @TypeSystemReference(SLTypes.class)
 public class SLNode extends Node {
 
+    public SLNode() {
+        // No source attribution
+        super(null);
+    }
+
     @Override
     public String toString() {
         return NodeUtil.printTreeToString(this);
--- a/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/graal/com.oracle.truffle.sl/src/com/oracle/truffle/sl/nodes/FunctionDefinitionNode.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -35,6 +35,7 @@
     private final String name;
 
     public FunctionDefinitionNode(StatementNode body, FrameDescriptor frameDescriptor, String name, TypedNode returnValue) {
+        super(null);
         this.body = adoptChild(body);
         this.frameDescriptor = frameDescriptor;
         this.name = name;
--- a/make/bsd/makefiles/adlc.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/bsd/makefiles/adlc.make	Fri Oct 11 17:21:14 2013 +0200
@@ -41,13 +41,11 @@
 
 ifeq ("${Platform_arch_model}", "${Platform_arch}")
   SOURCES.AD = \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
+  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) 
 else
   SOURCES.AD = \
   $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
+  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) 
 endif
 
 EXEC	= $(OUTDIR)/adlc
--- a/make/bsd/makefiles/minimal1.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/bsd/makefiles/minimal1.make	Fri Oct 11 17:21:14 2013 +0200
@@ -24,16 +24,20 @@
 
 TYPE=MINIMAL1
 
-INCLUDE_JVMTI ?= false
-INCLUDE_FPROF ?= false
-INCLUDE_VM_STRUCTS ?= false
-INCLUDE_JNI_CHECK ?= false
-INCLUDE_SERVICES ?= false
-INCLUDE_MANAGEMENT ?= false
-INCLUDE_ALL_GCS ?= false
-INCLUDE_NMT ?= false
-INCLUDE_TRACE ?= false
-INCLUDE_CDS ?= false
+# Force all variables to false, overriding any other
+# setting that may have occurred in the makefiles. These
+# can still be overridden by passing the variable as an
+# argument to 'make'
+INCLUDE_JVMTI := false
+INCLUDE_FPROF := false
+INCLUDE_VM_STRUCTS := false
+INCLUDE_JNI_CHECK := false
+INCLUDE_SERVICES := false
+INCLUDE_MANAGEMENT := false
+INCLUDE_ALL_GCS := false
+INCLUDE_NMT := false
+INCLUDE_TRACE := false
+INCLUDE_CDS := false
 
 CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
 CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/make/hotspot_version	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/hotspot_version	Fri Oct 11 17:21:14 2013 +0200
@@ -35,7 +35,7 @@
 
 HS_MAJOR_VER=25
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=43
+HS_BUILD_NUMBER=46
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=8
--- a/make/linux/makefiles/adlc.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/linux/makefiles/adlc.make	Fri Oct 11 17:21:14 2013 +0200
@@ -41,13 +41,11 @@
 
 ifeq ("${Platform_arch_model}", "${Platform_arch}")
   SOURCES.AD = \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
+  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) 
 else
   SOURCES.AD = \
   $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
+  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) 
 endif
 
 EXEC	= $(OUTDIR)/adlc
--- a/make/linux/makefiles/minimal1.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/linux/makefiles/minimal1.make	Fri Oct 11 17:21:14 2013 +0200
@@ -24,16 +24,20 @@
 
 TYPE=MINIMAL1
 
-INCLUDE_JVMTI ?= false
-INCLUDE_FPROF ?= false
-INCLUDE_VM_STRUCTS ?= false
-INCLUDE_JNI_CHECK ?= false
-INCLUDE_SERVICES ?= false
-INCLUDE_MANAGEMENT ?= false
-INCLUDE_ALL_GCS ?= false
-INCLUDE_NMT ?= false
-INCLUDE_TRACE ?= false
-INCLUDE_CDS ?= false
+# Force all variables to false, overriding any other
+# setting that may have occurred in the makefiles. These
+# can still be overridden by passing the variable as an
+# argument to 'make'
+INCLUDE_JVMTI := false
+INCLUDE_FPROF := false
+INCLUDE_VM_STRUCTS := false
+INCLUDE_JNI_CHECK := false
+INCLUDE_SERVICES := false
+INCLUDE_MANAGEMENT := false
+INCLUDE_ALL_GCS := false
+INCLUDE_NMT := false
+INCLUDE_TRACE := false
+INCLUDE_CDS := false
 
 CXXFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
 CFLAGS += -DMINIMAL_JVM -DCOMPILER1 -DVMTYPE=\"Minimal\"
--- a/make/solaris/makefiles/adlc.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/solaris/makefiles/adlc.make	Fri Oct 11 17:21:14 2013 +0200
@@ -42,13 +42,11 @@
 
 ifeq ("${Platform_arch_model}", "${Platform_arch}")
   SOURCES.AD = \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
+  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) 
 else
   SOURCES.AD = \
   $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch_model).ad) \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) \
-  $(call altsrc-replace,$(HS_COMMON_SRC)/os_cpu/$(OS)_$(ARCH)/vm/$(OS)_$(Platform_arch_model).ad)
+  $(call altsrc-replace,$(HS_COMMON_SRC)/cpu/$(ARCH)/vm/$(Platform_arch).ad) 
 endif
 
 EXEC	= $(OUTDIR)/adlc
--- a/make/solaris/makefiles/dtrace.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/solaris/makefiles/dtrace.make	Fri Oct 11 17:21:14 2013 +0200
@@ -283,9 +283,9 @@
 	$(QUIETLY) $(DTRACE_PROG) $(DTRACE_OPTS) -C -I. -G -xlazyload -o $@ -s $(DTRACE).d \
      $(DTraced_Files) ||\
   STATUS=$$?;\
-	if [ x"$$STATUS" = x"1" -a \
-       x`uname -r` = x"5.10" -a \
-       x`uname -p` = x"sparc" ]; then\
+  if [ x"$$STATUS" = x"1" ]; then \
+      if [ x`uname -r` = x"5.10" -a \
+           x`uname -p` = x"sparc" ]; then\
     echo "*****************************************************************";\
     echo "* If you are building server compiler, and the error message is ";\
     echo "* \"incorrect ELF machine type...\", you have run into solaris bug ";\
@@ -294,6 +294,20 @@
     echo "* environment variable HOTSPOT_DISABLE_DTRACE_PROBES to disable ";\
     echo "* dtrace probes for this build.";\
     echo "*****************************************************************";\
+      elif [ x`uname -r` = x"5.10" ]; then\
+    echo "*****************************************************************";\
+    echo "* If you are seeing 'syntax error near \"umpiconninfo_t\"' on Solaris";\
+    echo "* 10, try doing 'cd /usr/lib/dtrace && gzip mpi.d' as root, ";\
+    echo "* or set the environment variable HOTSPOT_DISABLE_DTRACE_PROBES";\
+    echo "* to disable dtrace probes for this build.";\
+    echo "*****************************************************************";\
+      else \
+    echo "*****************************************************************";\
+    echo "* If you cannot fix dtrace build issues, try to ";\
+    echo "* set the environment variable HOTSPOT_DISABLE_DTRACE_PROBES";\
+    echo "* to disable dtrace probes for this build.";\
+    echo "*****************************************************************";\
+      fi; \
   fi;\
   exit $$STATUS
   # Since some DTraced_Files are in LIBJVM.o and they are touched by this
--- a/make/windows/create.bat	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/windows/create.bat	Fri Oct 11 17:21:14 2013 +0200
@@ -1,6 +1,6 @@
 @echo off
 REM
-REM Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+REM Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 REM
 REM This code is free software; you can redistribute it and/or modify it
@@ -152,7 +152,7 @@
 
 REM This is now safe to do.
 :copyfiles
-for /D %%i in (graal, compiler1, compiler2, tiered, core) do (
+for /D %%i in (graal, compiler1, compiler2, tiered) do (
 if NOT EXIST %HotSpotBuildSpace%\%%i\generated mkdir %HotSpotBuildSpace%\%%i\generated
 copy %HotSpotWorkSpace%\make\windows\projectfiles\%%i\* %HotSpotBuildSpace%\%%i\generated > NUL
 )
@@ -160,7 +160,7 @@
 REM force regneration of ProjectFile
 if exist %ProjectFile% del %ProjectFile%
 
-for /D %%i in (graal, compiler1, compiler2, tiered, core) do (
+for /D %%i in (graal, compiler1, compiler2, tiered) do (
 echo -- %%i --
 echo # Generated file!                                                        >    %HotSpotBuildSpace%\%%i\local.make
 echo # Changing a variable below and then deleting %ProjectFile% will cause  >>    %HotSpotBuildSpace%\%%i\local.make
--- a/make/windows/create_obj_files.sh	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/windows/create_obj_files.sh	Fri Oct 11 17:21:14 2013 +0200
@@ -73,19 +73,17 @@
 
 BASE_PATHS="${BASE_PATHS} ${GENERATED}/jvmtifiles ${GENERATED}/tracefiles"
 
-if [ -d "${ALTSRC}/share/vm/jfr" ]; then
-  BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr"
+if [ -d "${ALTSRC}/share/vm/jfr/buffers" ]; then
   BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr/buffers"
 fi
 
 BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/share/vm/prims/wbtestmethods"
 
-CORE_PATHS="${BASE_PATHS}"
 # shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS.
 if [ -d "${ALTSRC}/share/vm/gc_implementation" ]; then
-  CORE_PATHS="${CORE_PATHS} `$FIND ${ALTSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`"
+  BASE_PATHS="${BASE_PATHS} `$FIND ${ALTSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`"
 fi
-CORE_PATHS="${CORE_PATHS} `$FIND ${COMMONSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`"
+BASE_PATHS="${BASE_PATHS} `$FIND ${COMMONSRC}/share/vm/gc_implementation ! -name gc_implementation -prune -type d \! -name shared`"
 
 if [ -d "${ALTSRC}/share/vm/c1" ]; then
   COMPILER1_PATHS="${ALTSRC}/share/vm/c1"
@@ -104,12 +102,11 @@
 
 # Include dirs per type.
 case "${TYPE}" in
-    "core")      Src_Dirs="${CORE_PATHS}" ;;
-    "compiler1") Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS}" ;;
-    "compiler2") Src_Dirs="${CORE_PATHS} ${COMPILER2_PATHS}" ;;
-    "tiered")    Src_Dirs="${CORE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;;
-    "zero")      Src_Dirs="${CORE_PATHS}" ;;
-    "shark")     Src_Dirs="${CORE_PATHS}" ;;
+    "compiler1") Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS}" ;;
+    "compiler2") Src_Dirs="${BASE_PATHS} ${COMPILER2_PATHS}" ;;
+    "tiered")    Src_Dirs="${BASE_PATHS} ${COMPILER1_PATHS} ${COMPILER2_PATHS}" ;;
+    "zero")      Src_Dirs="${BASE_PATHS}" ;;
+    "shark")     Src_Dirs="${BASE_PATHS}" ;;
 esac
 
 COMPILER2_SPECIFIC_FILES="opto libadt bcEscapeAnalyzer.cpp c2_* runtime_*"
@@ -122,7 +119,6 @@
 
 # Exclude per type.
 case "${TYPE}" in
-    "core")      Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
     "compiler1") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER2_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES} ciTypeFlow.cpp" ;;
     "compiler2") Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${COMPILER1_SPECIFIC_FILES} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;;
     "tiered")    Src_Files_EXCLUDE="${Src_Files_EXCLUDE} ${ZERO_SPECIFIC_FILES} ${SHARK_SPECIFIC_FILES}" ;;
@@ -149,9 +145,17 @@
    Src_Files="${Src_Files}`findsrc ${e}` "
 done 
 
-Obj_Files=
+Obj_Files=" "
 for e in ${Src_Files}; do
-	Obj_Files="${Obj_Files}${e%\.[!.]*}.obj "
+        o="${e%\.[!.]*}.obj"
+        set +e
+        chk=`expr "${Obj_Files}" : ".* $o"`
+        set -e
+        if [ "$chk" != 0 ]; then
+             echo "# INFO: skipping duplicate $o"
+             continue
+        fi
+	Obj_Files="${Obj_Files}$o "
 done
 
 echo Obj_Files=${Obj_Files}
--- a/make/windows/makefiles/adlc.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/windows/makefiles/adlc.make	Fri Oct 11 17:21:14 2013 +0200
@@ -55,13 +55,11 @@
 
 !if "$(Platform_arch_model)" == "$(Platform_arch)"
 SOURCES_AD=\
-  $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad \
-  $(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad
+  $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad 
 !else
 SOURCES_AD=\
   $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch_model).ad \
-  $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad \
-  $(WorkSpace)/src/os_cpu/windows_$(Platform_arch)/vm/windows_$(Platform_arch_model).ad
+  $(WorkSpace)/src/cpu/$(Platform_arch)/vm/$(Platform_arch).ad 
 !endif
 
 # NOTE! If you add any files here, you must also update GENERATED_NAMES_IN_DIR
--- a/make/windows/makefiles/projectcreator.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/windows/makefiles/projectcreator.make	Fri Oct 11 17:21:14 2013 +0200
@@ -44,10 +44,11 @@
 
 # This is only used internally
 ProjectCreatorIncludesPRIVATE=\
-        -relativeInclude src\closed\share\vm \
-        -relativeInclude src\closed\os\windows\vm \
-        -relativeInclude src\closed\os_cpu\windows_$(Platform_arch)\vm \
-        -relativeInclude src\closed\cpu\$(Platform_arch)\vm \
+        -relativeAltSrcInclude src\closed \
+        -altRelativeInclude share\vm \
+        -altRelativeInclude os\windows\vm \
+        -altRelativeInclude os_cpu\windows_$(Platform_arch)\vm \
+        -altRelativeInclude cpu\$(Platform_arch)\vm \
         -relativeInclude src\share\vm \
         -relativeInclude src\share\vm\precompiled \
         -relativeInclude src\share\vm\prims\wbtestmethods \
@@ -92,7 +93,7 @@
         -disablePch        getThread_windows_$(Platform_arch).cpp \
         -disablePch_compiler2     opcodes.cpp
 
-# Common options for the IDE builds for core, c1, and c2
+# Common options for the IDE builds for c1, and c2
 ProjectCreatorIDEOptions=\
         $(ProjectCreatorIDEOptions) \
         -sourceBase $(HOTSPOTWORKSPACE) \
@@ -165,19 +166,11 @@
  -ignoreFile_TARGET $(Platform_arch_model).ad
 
 ##################################################
-# Without compiler(core) specific options
-##################################################
-ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
-$(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=core) \
-$(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=core)
-
-##################################################
 # Client(C1) compiler specific options
 ##################################################
 ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
  -define_compiler1 COMPILER1 \
  -define_compiler1 GRAAL \
- -ignorePath_compiler1 core \
  -ignorePath_compiler1 graal/generated \
  $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1)
 
@@ -186,7 +179,6 @@
 ##################################################
 ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
  -define_graal GRAAL \
- -ignorePath_graal core \
  $(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=graal) \
  $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=graal)
 
@@ -198,7 +190,6 @@
  -define_compiler2 COMPILER2 \
  -define_compiler2 GRAAL \
  -define_compiler2 TIERED \
- -ignorePath_compiler2 core \
  -ignorePath_compiler2 graal/generated \
  -additionalFile_compiler2 $(Platform_arch_model).ad \
  -additionalFile_compiler2 ad_$(Platform_arch_model).cpp \
--- a/make/windows/makefiles/trace.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/windows/makefiles/trace.make	Fri Oct 11 17:21:14 2013 +0200
@@ -90,25 +90,25 @@
 !if "$(OPENJDK)" == "true"
 
 $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceSrcDir)/traceEventClasses.xsl $(XML_DEPS)
-	@echo Generating $@
+	@echo Generating OpenJDK $@
 	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
 
 !else
 
 $(TraceOutDir)/traceEventClasses.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventClasses.xsl $(XML_DEPS)
-	@echo Generating $@
+	@echo Generating AltSrc $@
 	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventClasses.xsl -OUT $(TraceOutDir)/traceEventClasses.hpp
 
 $(TraceOutDir)/traceProducer.cpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceProducer.xsl $(XML_DEPS)
-	@echo Generating $@
+	@echo Generating AltSrc $@
 	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceProducer.xsl -OUT $(TraceOutDir)/traceProducer.cpp
 
 $(TraceOutDir)/traceRequestables.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceRequestables.xsl $(XML_DEPS)
-	@echo Generating $@
+	@echo Generating AltSrc $@
 	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceRequestables.xsl -OUT $(TraceOutDir)/traceRequestables.hpp
 
 $(TraceOutDir)/traceEventControl.hpp: $(TraceSrcDir)/trace.xml $(TraceAltSrcDir)/traceEventControl.xsl $(XML_DEPS)
-	@echo Generating $@
+	@echo Generating AltSrc $@
 	@$(XSLT) -IN $(TraceSrcDir)/trace.xml -XSL $(TraceAltSrcDir)/traceEventControl.xsl -OUT $(TraceOutDir)/traceEventControl.hpp
 
 !endif
--- a/make/windows/makefiles/vm.make	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/windows/makefiles/vm.make	Fri Oct 11 17:21:14 2013 +0200
@@ -36,10 +36,6 @@
 CXX_FLAGS=$(CXX_FLAGS) /D "ASSERT"
 !endif
 
-!if "$(Variant)" == "core"
-# No need to define anything, CORE is defined as !COMPILER1 && !COMPILER2
-!endif
-
 !if "$(Variant)" == "compiler1"
 CXX_FLAGS=$(CXX_FLAGS) /D "COMPILER1"
 !endif
--- a/make/windows/projectfiles/common/Makefile	Fri Oct 11 17:14:35 2013 +0200
+++ b/make/windows/projectfiles/common/Makefile	Fri Oct 11 17:21:14 2013 +0200
@@ -112,6 +112,7 @@
 ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) $(ReleaseOptions)
 
 $(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
+	@if "$(MSC_VER)"=="1500" echo Make sure you have VS2008 SP1 or later, or you may see 'expanded command line too long'
 	@$(RUN_JAVA) -Djava.class.path="$(HOTSPOTBUILDSPACE)/classes" ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions)
 
 clean:
--- a/mx/commands.py	Fri Oct 11 17:14:35 2013 +0200
+++ b/mx/commands.py	Fri Oct 11 17:21:14 2013 +0200
@@ -365,9 +365,18 @@
 
     return jdk
 
+def _updateInstalledGraalOptionsFile(jdk):
+    graalOptions = join(_graal_home, 'graal.options')
+    jreLibDir = join(jdk, 'jre', 'lib')
+    if exists(graalOptions):
+        shutil.copy(graalOptions, join(jreLibDir, 'graal.options'))
+    else:
+        toDelete = join(jreLibDir, 'graal.options')
+        if exists(toDelete):
+            os.unlink(toDelete)
+
 def _installGraalJarInJdks(graalDist):
     graalJar = graalDist.path
-    graalOptions = join(_graal_home, 'graal.options')
     jdks = _jdksDir()
     if exists(jdks):
         for e in os.listdir(jdks):
@@ -379,9 +388,6 @@
                 os.close(fd)
                 shutil.move(tmp, join(jreLibDir, 'graal.jar'))
 
-                if exists(graalOptions):
-                    shutil.copy(graalOptions, join(jreLibDir, 'graal.options'))
-
 # run a command in the windows SDK Debug Shell
 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None):
     if respondTo is None:
@@ -692,6 +698,7 @@
 
     build = vmbuild if vmbuild is not None else _vmbuild if _vmSourcesAvailable else 'product'
     jdk = _jdk(build, vmToCheck=vm, installGraalJar=False)
+    _updateInstalledGraalOptionsFile(jdk)
     mx.expand_project_in_args(args)
     if _make_eclipse_launch:
         mx.make_eclipse_launch(args, 'graal-' + build, name=None, deps=mx.project('com.oracle.graal.hotspot').all_deps([], True))
@@ -944,12 +951,14 @@
 
     with VM('graal', 'product'):
         t = Task('BootstrapWithGCVerification:product')
-        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'])
+        out = mx.DuplicateSuppressingStream(['VerifyAfterGC:', 'VerifyBeforeGC:']).write
+        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out)
         tasks.append(t.stop())
 
     with VM('graal', 'product'):
         t = Task('BootstrapWithG1GCVerification:product')
-        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC', '-XX:+UseG1GC', '-XX:+UseNewCode', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'])
+        out = mx.DuplicateSuppressingStream(['VerifyAfterGC:', 'VerifyBeforeGC:']).write
+        vm(['-XX:+UnlockDiagnosticVMOptions', '-XX:-UseSerialGC', '-XX:+UseG1GC', '-XX:+UseNewCode', '-XX:+VerifyBeforeGC', '-XX:+VerifyAfterGC', '-version'], out=out)
         tasks.append(t.stop())
 
     with VM('graal', 'product'):
@@ -1318,6 +1327,14 @@
         mx.abort('jacocoreport takes only one argument : an output directory')
     mx.run_java(['-jar', jacocoreport.get_path(True), '-in', 'jacoco.exec', '-g', join(_graal_home, 'graal'), out])
 
+def sl(args):
+    """run an SL program
+
+    VM args should have a @ prefix."""
+    vmArgs = [a[1:] for a in args if a[0] == '@']
+    slArgs = [a for a in args if a[0] != '@']
+    vm(vmArgs + ['-cp', mx.classpath("com.oracle.truffle.sl"), "com.oracle.truffle.sl.SimpleLanguage"] + slArgs)
+
 def isGraalEnabled(vm):
     return vm != 'original' and not vm.endswith('nograal')
 
@@ -1361,7 +1378,8 @@
         'vmg': [vmg, '[-options] class [args...]'],
         'vmfg': [vmfg, '[-options] class [args...]'],
         'deoptalot' : [deoptalot, '[n]'],
-        'longtests' : [longtests, '']
+        'longtests' : [longtests, ''],
+        'sl' : [sl, '[SL args|@VM options]']
     }
 
     mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append'])
--- a/mx/projects	Fri Oct 11 17:14:35 2013 +0200
+++ b/mx/projects	Fri Oct 11 17:21:14 2013 +0200
@@ -186,7 +186,7 @@
 # graal.graph
 project@com.oracle.graal.graph@subDir=graal
 project@com.oracle.graal.graph@sourceDirs=src
-project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug
+project@com.oracle.graal.graph@dependencies=com.oracle.graal.debug,com.oracle.graal.api.code
 project@com.oracle.graal.graph@javaCompliance=1.7
 project@com.oracle.graal.graph@workingSets=Graal,Graph
 
@@ -297,7 +297,7 @@
 # graal.nodes
 project@com.oracle.graal.nodes@subDir=graal
 project@com.oracle.graal.nodes@sourceDirs=src
-project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements,com.oracle.graal.api.code
+project@com.oracle.graal.nodes@dependencies=com.oracle.graal.graph,com.oracle.graal.api.replacements
 project@com.oracle.graal.nodes@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.nodes@javaCompliance=1.7
 project@com.oracle.graal.nodes@workingSets=Graal,Graph
@@ -497,7 +497,7 @@
 # graal.hsail
 project@com.oracle.graal.hsail@subDir=graal
 project@com.oracle.graal.hsail@sourceDirs=src
-project@com.oracle.graal.hsail@dependencies=com.oracle.graal.api.code,com.oracle.graal.graph
+project@com.oracle.graal.hsail@dependencies=com.oracle.graal.graph
 project@com.oracle.graal.hsail@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.hsail@javaCompliance=1.7
 
--- a/mxtool/mx.py	Fri Oct 11 17:14:35 2013 +0200
+++ b/mxtool/mx.py	Fri Oct 11 17:21:14 2013 +0200
@@ -158,7 +158,7 @@
 _mainSuite = None
 _opts = None
 _java = None
-_check_global_structures = True # can be set False to allow suites with duplicate definitions to load without aborting
+_check_global_structures = True  # can be set False to allow suites with duplicate definitions to load without aborting
 
 
 """
@@ -1277,6 +1277,36 @@
     return name
 
 """
+Utility for filtering duplicate lines.
+"""
+class DuplicateSuppressingStream:
+    """
+    Creates an object that will suppress duplicate lines sent to 'out'.
+    The lines considered for suppression are those that contain one of the
+    strings in 'restrictTo' if it is not None.
+    """
+    def __init__(self, restrictTo=None, out=sys.stdout):
+        self.restrictTo = restrictTo
+        self.seen = set()
+        self.out = out
+
+    def isSuppressionCandidate(self, line):
+        if self.restrictTo:
+            for p in self.restrictTo:
+                if p in line:
+                    return True
+            return False
+        else:
+            return True
+
+    def write(self, line):
+        if self.isSuppressionCandidate(line):
+            if line in self.seen:
+                return
+            self.seen.add(line)
+        self.out.write(line)
+
+"""
 A JavaCompliance simplifies comparing Java compliance values extracted from a JDK version string.
 """
 class JavaCompliance:
@@ -2518,7 +2548,7 @@
         return
 
     if buildProcessorJars:
-        ## todo suite specific
+        # todo suite specific
         processorjars()
 
     projToDist = dict()
@@ -2810,7 +2840,7 @@
     if exists(md):
         return wsdir
     split = os.path.split(wsdir)
-    if split[0] == wsdir: # root directory
+    if split[0] == wsdir:  # root directory
         return None
     else:
         return _find_eclipse_wsroot(split[0])
--- a/src/cpu/sparc/vm/c2_globals_sparc.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/cpu/sparc/vm/c2_globals_sparc.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -44,7 +44,11 @@
 #else
 define_pd_global(bool, ProfileInterpreter,           true);
 #endif // CC_INTERP
+#ifdef GRAAL
 define_pd_global(bool, TieredCompilation,            false);
+#else
+define_pd_global(bool, TieredCompilation,            trueInTiered);
+#endif
 define_pd_global(intx, CompileThreshold,             10000);
 define_pd_global(intx, BackEdgeThreshold,            140000);
 
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1900,6 +1900,27 @@
   if (ProfileInterpreter) {
     __ set_method_data_pointer_for_bcp();
   }
+
+#if INCLUDE_JVMTI
+  if (EnableInvokeDynamic) {
+    Label L_done;
+
+    __ ldub(Address(Lbcp, 0), G1_scratch);  // Load current bytecode
+    __ cmp_and_br_short(G1_scratch, Bytecodes::_invokestatic, Assembler::notEqual, Assembler::pn, L_done);
+
+    // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
+    // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
+
+    __ call_VM(G1_scratch, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), I0, Lmethod, Lbcp);
+
+    __ br_null(G1_scratch, false, Assembler::pn, L_done);
+    __ delayed()->nop();
+
+    __ st_ptr(G1_scratch, Lesp, wordSize);
+    __ bind(L_done);
+  }
+#endif // INCLUDE_JVMTI
+
   // Resume bytecode interpretation at the current bcp
   __ dispatch_next(vtos);
   // end of JVMTI PopFrame support
--- a/src/cpu/x86/vm/c2_globals_x86.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/cpu/x86/vm/c2_globals_x86.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -46,7 +46,11 @@
 #else
 define_pd_global(bool, ProfileInterpreter,           true);
 #endif // CC_INTERP
+#ifdef GRAAL
 define_pd_global(bool, TieredCompilation,            false);
+#else
+define_pd_global(bool, TieredCompilation,            trueInTiered);
+#endif
 define_pd_global(intx, CompileThreshold,             10000);
 define_pd_global(intx, BackEdgeThreshold,            100000);
 
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -50,6 +50,9 @@
     // the inlined vtable stub contains a "call register" instruction
     assert(method != NULL, "only valid for virtual calls");
     return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset());
+  } else if (inst->is_cond_jump()) {
+    address pc = (address) (inst);
+    return pc_offset + (jint) (Assembler::locate_next_instruction(pc) - pc);
   } else {
     fatal("unsupported type of instruction for call site");
     return 0;
@@ -145,21 +148,30 @@
 }
 
 inline void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
+  address pc = (address) inst;
   if (inst->is_call()) {
     // NOTE: for call without a mov, the offset must fit a 32-bit immediate
     //       see also CompilerToVM.getMaxCallTargetOffset()
-    NativeCall* call = nativeCall_at((address) (inst));
+    NativeCall* call = nativeCall_at(pc);
     call->set_destination((address) foreign_call_destination);
     _instructions->relocate(call->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
   } else if (inst->is_mov_literal64()) {
-    NativeMovConstReg* mov = nativeMovConstReg_at((address) (inst));
+    NativeMovConstReg* mov = nativeMovConstReg_at(pc);
     mov->set_data((intptr_t) foreign_call_destination);
     _instructions->relocate(mov->instruction_address(), runtime_call_Relocation::spec(), Assembler::imm_operand);
-  } else {
-    NativeJump* jump = nativeJump_at((address) (inst));
+  } else if (inst->is_jump()) {
+    NativeJump* jump = nativeJump_at(pc);
     jump->set_jump_destination((address) foreign_call_destination);
-    _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
+    _instructions->relocate(jump->instruction_address(), runtime_call_Relocation::spec(), Assembler::call32_operand);
+  } else if (inst->is_cond_jump()) {
+    address old_dest = nativeGeneralJump_at(pc)->jump_destination();
+    address disp = Assembler::locate_operand(pc, Assembler::call32_operand);
+    *(jint*) disp += ((address) foreign_call_destination) - old_dest;
+    _instructions->relocate(pc, runtime_call_Relocation::spec(), Assembler::call32_operand);
+  } else {
+    fatal("unsupported relocation for foreign call");
   }
+
   TRACE_graal_3("relocating (foreign call)  at %p", inst);
 }
 
--- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1920,6 +1920,29 @@
   __ get_thread(thread);
   __ movl(Address(thread, JavaThread::popframe_condition_offset()), JavaThread::popframe_inactive);
 
+#if INCLUDE_JVMTI
+  if (EnableInvokeDynamic) {
+    Label L_done;
+    const Register local0 = rdi;
+
+    __ cmpb(Address(rsi, 0), Bytecodes::_invokestatic);
+    __ jcc(Assembler::notEqual, L_done);
+
+    // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
+    // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
+
+    __ get_method(rdx);
+    __ movptr(rax, Address(local0, 0));
+    __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, rsi);
+
+    __ testptr(rax, rax);
+    __ jcc(Assembler::zero, L_done);
+
+    __ movptr(Address(rbx, 0), rax);
+    __ bind(L_done);
+  }
+#endif // INCLUDE_JVMTI
+
   __ dispatch_next(vtos);
   // end of PopFrame support
 
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -2011,6 +2011,29 @@
   __ movl(Address(r15_thread, JavaThread::popframe_condition_offset()),
           JavaThread::popframe_inactive);
 
+#if INCLUDE_JVMTI
+  if (EnableInvokeDynamic) {
+    Label L_done;
+    const Register local0 = r14;
+
+    __ cmpb(Address(r13, 0), Bytecodes::_invokestatic);
+    __ jcc(Assembler::notEqual, L_done);
+
+    // The member name argument must be restored if _invokestatic is re-executed after a PopFrame call.
+    // Detect such a case in the InterpreterRuntime function and return the member name argument, or NULL.
+
+    __ get_method(rdx);
+    __ movptr(rax, Address(local0, 0));
+    __ call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::member_name_arg_or_null), rax, rdx, r13);
+
+    __ testptr(rax, rax);
+    __ jcc(Assembler::zero, L_done);
+
+    __ movptr(Address(rbx, 0), rax);
+    __ bind(L_done);
+  }
+#endif // INCLUDE_JVMTI
+
   __ dispatch_next(vtos);
   // end of PopFrame support
 
--- a/src/cpu/zero/vm/entryFrame_zero.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/cpu/zero/vm/entryFrame_zero.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -58,8 +58,8 @@
                            JavaCallWrapper* call_wrapper,
                            TRAPS);
  public:
-  JavaCallWrapper *call_wrapper() const {
-    return (JavaCallWrapper *) value_of_word(call_wrapper_off);
+  JavaCallWrapper **call_wrapper() const {
+    return (JavaCallWrapper **) addr_of_word(call_wrapper_off);
   }
 
  public:
--- a/src/cpu/zero/vm/frame_zero.inline.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/cpu/zero/vm/frame_zero.inline.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -141,7 +141,7 @@
   return fp();
 }
 
-inline JavaCallWrapper* frame::entry_frame_call_wrapper() const {
+inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const {
   return zero_entryframe()->call_wrapper();
 }
 
--- a/src/cpu/zero/vm/stubGenerator_zero.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/cpu/zero/vm/stubGenerator_zero.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -176,6 +176,19 @@
       StubRoutines::_oop_arraycopy;
   }
 
+  static int SafeFetch32(int *adr, int errValue) {
+    int value = errValue;
+    value = *adr;
+    return value;
+  }
+
+  static intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
+    intptr_t value = errValue;
+    value = *adr;
+    return value;
+  }
+
+
   void generate_initial() {
     // Generates all stubs and initializes the entry points
 
@@ -225,6 +238,15 @@
 
     // arraycopy stubs used by compilers
     generate_arraycopy_stubs();
+
+    // Safefetch stubs.
+    StubRoutines::_safefetch32_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetch32);
+    StubRoutines::_safefetch32_fault_pc = NULL;
+    StubRoutines::_safefetch32_continuation_pc = NULL;
+
+    StubRoutines::_safefetchN_entry = CAST_FROM_FN_PTR(address, StubGenerator::SafeFetchN);
+    StubRoutines::_safefetchN_fault_pc = NULL;
+    StubRoutines::_safefetchN_continuation_pc = NULL;
   }
 
  public:
--- a/src/gpu/ptx/vm/gpu_ptx.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/gpu/ptx/vm/gpu_ptx.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -50,6 +50,28 @@
 gpu::Ptx::cuda_cu_memcpy_dtoh_func_t gpu::Ptx::_cuda_cu_memcpy_dtoh;
 gpu::Ptx::cuda_cu_memfree_func_t gpu::Ptx::_cuda_cu_memfree;
 
+
+/*
+ * see http://en.wikipedia.org/wiki/CUDA#Supported_GPUs
+ */
+int ncores(int major, int minor) {
+    int device_type = (major << 4) + minor;
+
+    switch (device_type) {
+        case 0x10: return 8;
+        case 0x11: return 8;
+        case 0x12: return 8;
+        case 0x13: return 8;
+        case 0x20: return 32;
+        case 0x21: return 48;
+        case 0x30: return 192;
+        case 0x35: return 192;
+    default:
+        tty->print_cr("[CUDA] Warning: Unhandled device %x", device_type);
+        return 0;
+    }
+}
+
 bool gpu::Ptx::initialize_gpu() {
 
   /* Initialize CUDA driver API */
@@ -95,24 +117,7 @@
   }
 
   /* Get device attributes */
-  int minor, major, unified_addressing;
-  status = _cuda_cu_device_get_attribute(&minor, GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR, _cu_device);
-
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] Failed to get minor attribute of device: %d", _cu_device);
-    return false;
-  }
-
-  status = _cuda_cu_device_get_attribute(&major, GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR, _cu_device);
-
-  if (status != GRAAL_CUDA_SUCCESS) {
-    tty->print_cr("[CUDA] Failed to get major attribute of device: %d", _cu_device);
-    return false;
-  }
-
-  if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Compatibility version of device %d: %d.%d", _cu_device, major, minor);
-  }
+  int unified_addressing;
 
   status = _cuda_cu_device_get_attribute(&unified_addressing, GRAAL_CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING, _cu_device);
 
@@ -139,9 +144,99 @@
     tty->print_cr("[CUDA] Using %s", device_name);
   }
 
+
   return true;
 }
 
+unsigned int gpu::Ptx::total_cores() {
+
+    int minor, major, nmp;
+    int status = _cuda_cu_device_get_attribute(&minor,
+                                               GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR,
+                                               _cu_device);
+
+    if (status != GRAAL_CUDA_SUCCESS) {
+        tty->print_cr("[CUDA] Failed to get minor attribute of device: %d", _cu_device);
+        return 0;
+    }
+
+    status = _cuda_cu_device_get_attribute(&major,
+                                           GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR,
+                                           _cu_device);
+
+    if (status != GRAAL_CUDA_SUCCESS) {
+        tty->print_cr("[CUDA] Failed to get major attribute of device: %d", _cu_device);
+        return 0;
+    }
+
+    status = _cuda_cu_device_get_attribute(&nmp,
+                                           GRAAL_CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT,
+                                           _cu_device);
+
+    if (status != GRAAL_CUDA_SUCCESS) {
+        tty->print_cr("[CUDA] Failed to get numberof MPs on device: %d", _cu_device);
+        return 0;
+    }
+
+    int total = nmp * ncores(major, minor);
+
+    int max_threads_per_block, warp_size, async_engines, can_map_host_memory, concurrent_kernels;
+
+    status = _cuda_cu_device_get_attribute(&max_threads_per_block,
+                                           GRAAL_CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK,
+                                           _cu_device);
+
+    if (status != GRAAL_CUDA_SUCCESS) {
+        tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK: %d", _cu_device);
+        return 0;
+    }
+
+    status = _cuda_cu_device_get_attribute(&warp_size,
+                                           GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE,
+                                           _cu_device);
+
+    if (status != GRAAL_CUDA_SUCCESS) {
+        tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE: %d", _cu_device);
+        return 0;
+    }
+    
+    status = _cuda_cu_device_get_attribute(&async_engines,
+                                           GRAAL_CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT,
+                                           _cu_device);
+
+    if (status != GRAAL_CUDA_SUCCESS) {
+        tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE: %d", _cu_device);
+        return 0;
+    }
+
+    status = _cuda_cu_device_get_attribute(&can_map_host_memory,
+                                           GRAAL_CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY,
+                                           _cu_device);
+
+    if (status != GRAAL_CUDA_SUCCESS) {
+        tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY: %d", _cu_device);
+        return 0;
+    }
+
+    status = _cuda_cu_device_get_attribute(&concurrent_kernels,
+                                           GRAAL_CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS,
+                                           _cu_device);
+
+    if (status != GRAAL_CUDA_SUCCESS) {
+        tty->print_cr("[CUDA] Failed to get GRAAL_CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS: %d", _cu_device);
+        return 0;
+    }
+
+    if (TraceGPUInteraction) {
+        tty->print_cr("[CUDA] Compatibility version of device %d: %d.%d", _cu_device, major, minor);
+        tty->print_cr("[CUDA] Number of cores: %d async engines: %d can map host mem: %d concurrent kernels: %d",
+                      total, async_engines, can_map_host_memory, concurrent_kernels);
+        tty->print_cr("[CUDA] Max threads per block: %d warp size: %d", max_threads_per_block, warp_size);
+    }
+    return (total);
+    
+}
+
 void *gpu::Ptx::generate_kernel(unsigned char *code, int code_len, const char *name) {
 
   struct CUmod_st * cu_module;
@@ -228,15 +323,20 @@
 }
 
 bool gpu::Ptx::execute_kernel(address kernel, PTXKernelArguments &ptxka, JavaValue &ret) {
+    return gpu::Ptx::execute_warp(1, 1, 1, kernel, ptxka, ret);
+}
+
+bool gpu::Ptx::execute_warp(int dimX, int dimY, int dimZ,
+                            address kernel, PTXKernelArguments &ptxka, JavaValue &ret) {
   // grid dimensionality
   unsigned int gridX = 1;
   unsigned int gridY = 1;
   unsigned int gridZ = 1;
 
   // thread dimensionality
-  unsigned int blockX = 1;
-  unsigned int blockY = 1;
-  unsigned int blockZ = 1;
+  unsigned int blockX = dimX;
+  unsigned int blockY = dimY;
+  unsigned int blockZ = dimZ;
 
   struct CUfunc_st* cu_function = (struct CUfunc_st*) kernel;
 
@@ -264,7 +364,7 @@
   }
 
   if (TraceGPUInteraction) {
-    tty->print_cr("[CUDA] Success: Kernel Launch");
+    tty->print_cr("[CUDA] Success: Kernel Launch: X: %d Y: %d Z: %d", blockX, blockY, blockZ);
   }
 
   status = _cuda_cu_ctx_synchronize();
@@ -282,7 +382,18 @@
   // Get the result. TODO: Move this code to get_return_oop()
   BasicType return_type = ptxka.get_ret_type();
   switch (return_type) {
-     case T_INT :
+     case T_INT:
+       {
+         int return_val;
+         status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_INT_BYTE_SIZE);
+         if (status != GRAAL_CUDA_SUCCESS) {
+           tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status);
+           return false;
+         }
+         ret.set_jint(return_val);
+       }
+       break;
+     case T_BOOLEAN:
        {
          int return_val;
          status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_INT_BYTE_SIZE);
@@ -293,7 +404,29 @@
          ret.set_jint(return_val);
        }
        break;
-     case T_LONG :
+     case T_FLOAT:
+       {
+         float return_val;
+         status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_FLOAT_BYTE_SIZE);
+         if (status != GRAAL_CUDA_SUCCESS) {
+           tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status);
+           return false;
+         }
+         ret.set_jfloat(return_val);
+       }
+       break;
+     case T_DOUBLE:
+       {
+         double return_val;
+         status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_DOUBLE_BYTE_SIZE);
+         if (status != GRAAL_CUDA_SUCCESS) {
+           tty->print_cr("[CUDA] *** Error (%d) Failed to copy value to device argument", status);
+           return false;
+         }
+         ret.set_jdouble(return_val);
+       }
+       break;
+     case T_LONG:
        {
          long return_val;
          status = gpu::Ptx::_cuda_cu_memcpy_dtoh(&return_val, ptxka._return_value_ptr, T_LONG_BYTE_SIZE);
@@ -304,10 +437,14 @@
          ret.set_jlong(return_val);
        }
        break;
+     case T_VOID:
+       break;
      default:
-       tty->print_cr("[CUDA] TODO *** Unhandled return type");
+       tty->print_cr("[CUDA] TODO *** Unhandled return type: %d", return_type);
   }
 
+  // handle post-invocation object and array arguemtn
+  ptxka.reiterate();
 
   // Free device memory allocated for result
   status = gpu::Ptx::_cuda_cu_memfree(ptxka._return_value_ptr);
--- a/src/gpu/ptx/vm/gpu_ptx.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/gpu/ptx/vm/gpu_ptx.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -31,9 +31,15 @@
  */
 #define GRAAL_CUDA_SUCCESS                                   0
 /**< Device shares a unified address space with the host */
+#define GRAAL_CU_DEVICE_ATTRIBUTE_MAX_THREADS_PER_BLOCK     1
 #define GRAAL_CU_DEVICE_ATTRIBUTE_UNIFIED_ADDRESSING        41
 #define GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MAJOR  75
 #define GRAAL_CU_DEVICE_ATTRIBUTE_COMPUTE_CAPABILITY_MINOR  76
+#define GRAAL_CU_DEVICE_ATTRIBUTE_MULTIPROCESSOR_COUNT      16
+#define GRAAL_CU_DEVICE_ATTRIBUTE_WARP_SIZE                 10
+#define GRAAL_CU_DEVICE_ATTRIBUTE_CAN_MAP_HOST_MEMORY       19
+#define GRAAL_CU_DEVICE_ATTRIBUTE_CONCURRENT_KERNELS        31
+#define GRAAL_CU_DEVICE_ATTRIBUTE_ASYNC_ENGINE_COUNT        40
 #define GRAAL_CU_JIT_MAX_REGISTERS                           0
 #define GRAAL_CU_JIT_THREADS_PER_BLOCK                       1
 #define GRAAL_CU_JIT_INFO_LOG_BUFFER                         3
@@ -73,7 +79,9 @@
  protected:
   static bool probe_linkage();
   static bool initialize_gpu();
+  static unsigned int total_cores();
   static void * generate_kernel(unsigned char *code, int code_len, const char *name);
+  static bool execute_warp(int dimX, int dimY, int dimZ, address kernel, PTXKernelArguments & ka, JavaValue &ret);
   static bool execute_kernel(address kernel, PTXKernelArguments & ka, JavaValue &ret);
 public:
 #if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64)
--- a/src/gpu/ptx/vm/ptxKernelArguments.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/gpu/ptx/vm/ptxKernelArguments.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -32,42 +32,115 @@
 // Get next java argument
 oop PTXKernelArguments::next_arg(BasicType expectedType) {
   assert(_index < _args->length(), "out of bounds");
-  oop arg=((objArrayOop) (_args))->obj_at(_index++);
-  assert(expectedType == T_OBJECT || java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
+
+  oop arg = ((objArrayOop) (_args))->obj_at(_index++);
+  assert(expectedType == T_OBJECT ||
+         java_lang_boxing_object::is_instance(arg, expectedType), "arg type mismatch");
+
   return arg;
 }
 
-void PTXKernelArguments::do_int()    {
-  // If the parameter is a return value,
-  if (is_return_type()) {
-    // Allocate device memory for T_INT return value pointer on device. Size in bytes
-    int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_INT_BYTE_SIZE);
-    if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
-      _success = false;
-      return;
+void PTXKernelArguments::do_int() {
+    if (is_after_invocation()) {
+        return;
     }
-    // Push _return_value_ptr to _kernelBuffer
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr;
-    _bufferOffset += sizeof(_return_value_ptr);
-  }
-  else {
-    // Get the next java argument and its value which should be a T_INT
-    oop arg = next_arg(T_INT);
-    // Copy the java argument value to kernelArgBuffer
-    jvalue intval;
-    if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) {
-      tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT");
-      _success = false;
-      return;
+    // If the parameter is a return value,
+    if (is_return_type()) {
+        // Allocate device memory for T_INT return value pointer on device. Size in bytes
+        int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_INT_BYTE_SIZE);
+        if (status != GRAAL_CUDA_SUCCESS) {
+            tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
+            _success = false;
+            return;
+        }
+        // Push _return_value_ptr to _kernelBuffer
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr;
+        _bufferOffset += sizeof(_return_value_ptr);
+    } else {
+        // Get the next java argument and its value which should be a T_INT
+        oop arg = next_arg(T_INT);
+        // Copy the java argument value to kernelArgBuffer
+        jvalue intval;
+        if (java_lang_boxing_object::get_value(arg, &intval) != T_INT) {
+            tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT");
+            _success = false;
+            return;
+        }
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i;
+        _bufferOffset += sizeof(intval.i);
     }
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = intval.i;
-    _bufferOffset += sizeof(intval.i);
-  }
-  return;
+    return;
 }
 
-void PTXKernelArguments::do_long()    {
+void PTXKernelArguments::do_float() {
+    if (is_after_invocation()) {
+        return;
+    }
+    // If the parameter is a return value,
+    if (is_return_type()) {
+        // Allocate device memory for T_INT return value pointer on device. Size in bytes
+        int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_FLOAT_BYTE_SIZE);
+        if (status != GRAAL_CUDA_SUCCESS) {
+            tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
+            _success = false;
+            return;
+        }
+        // Push _return_value_ptr to _kernelBuffer
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr;
+        _bufferOffset += sizeof(_return_value_ptr);
+    } else {
+        // Get the next java argument and its value which should be a T_INT
+        oop arg = next_arg(T_FLOAT);
+        // Copy the java argument value to kernelArgBuffer
+        jvalue floatval;
+        if (java_lang_boxing_object::get_value(arg, &floatval) != T_FLOAT) {
+            tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT");
+            _success = false;
+            return;
+        }
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = floatval.f;
+        _bufferOffset += sizeof(floatval.f);
+    }
+    return;
+}
+
+void PTXKernelArguments::do_double() {
+    if (is_after_invocation()) {
+        return;
+    }
+    // If the parameter is a return value,
+    jvalue doubleval;
+    if (is_return_type()) {
+        // Allocate device memory for T_INT return value pointer on device. Size in bytes
+        int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_DOUBLE_BYTE_SIZE);
+        if (status != GRAAL_CUDA_SUCCESS) {
+            tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
+            _success = false;
+            return;
+        }
+        // Push _return_value_ptr to _kernelBuffer
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr;
+        // _bufferOffset += sizeof(_return_value_ptr);
+        _bufferOffset += sizeof(doubleval.d);
+    } else {
+        // Get the next java argument and its value which should be a T_INT
+        oop arg = next_arg(T_FLOAT);
+        // Copy the java argument value to kernelArgBuffer
+        if (java_lang_boxing_object::get_value(arg, &doubleval) != T_DOUBLE) {
+            tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_INT");
+            _success = false;
+            return;
+        }
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = doubleval.d;
+        _bufferOffset += sizeof(doubleval.d);
+    }
+    return;
+}
+
+void PTXKernelArguments::do_long() {
+  if (is_after_invocation()) {
+    return;
+  }
   // If the parameter is a return value,
   if (is_return_type()) {
     // Allocate device memory for T_LONG return value pointer on device. Size in bytes
@@ -80,8 +153,7 @@
     // Push _return_value_ptr to _kernelBuffer
     *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr;
     _bufferOffset += sizeof(_return_value_ptr);
-  }
-  else {
+  } else {
     // Get the next java argument and its value which should be a T_LONG
     oop arg = next_arg(T_LONG);
     // Copy the java argument value to kernelArgBuffer
@@ -97,34 +169,113 @@
   return;
 }
 
-void PTXKernelArguments::do_byte()    {
-  // If the parameter is a return value,
-  if (is_return_type()) {
-    // Allocate device memory for T_BYTE return value pointer on device. Size in bytes
-    int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BYTE_SIZE);
+void PTXKernelArguments::do_byte() {
+    if (is_after_invocation()) {
+        return;
+    }
+    // If the parameter is a return value,
+    if (is_return_type()) {
+        // Allocate device memory for T_BYTE return value pointer on device. Size in bytes
+        int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BYTE_SIZE);
+        if (status != GRAAL_CUDA_SUCCESS) {
+            tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
+            _success = false;
+            return;
+        }
+        // Push _return_value_ptr to _kernelBuffer
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr;
+        _bufferOffset += sizeof(_return_value_ptr);
+    } else {
+        // Get the next java argument and its value which should be a T_BYTE
+        oop arg = next_arg(T_BYTE);
+        // Copy the java argument value to kernelArgBuffer
+        jvalue val;
+        if (java_lang_boxing_object::get_value(arg, &val) != T_BYTE) {
+            tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE");
+            _success = false;
+            return;
+        }
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.b;
+        _bufferOffset += sizeof(val.b);
+    }
+    return;
+}
+
+void PTXKernelArguments::do_bool() {
+    if (is_after_invocation()) {
+        return;
+    }
+    // If the parameter is a return value,
+    if (is_return_type()) {
+        // Allocate device memory for T_BYTE return value pointer on device. Size in bytes
+        int status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, T_BOOLEAN_SIZE);
+        if (status != GRAAL_CUDA_SUCCESS) {
+            tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
+            _success = false;
+            return;
+        }
+        // Push _return_value_ptr to _kernelBuffer
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr;
+        _bufferOffset += sizeof(_return_value_ptr);
+    } else {
+        // Get the next java argument and its value which should be a T_BYTE
+        oop arg = next_arg(T_BYTE);
+        // Copy the java argument value to kernelArgBuffer
+        jvalue val;
+        if (java_lang_boxing_object::get_value(arg, &val) != T_BOOLEAN) {
+            tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE");
+            _success = false;
+            return;
+        }
+        *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.z;
+        _bufferOffset += sizeof(val.z);
+    }
+    return;
+}
+
+void PTXKernelArguments::do_array(int begin, int end) {
+    gpu::Ptx::CUdeviceptr _array_ptr;
+    int status;
+
+    // Get the next java argument and its value which should be a T_ARRAY
+    oop arg = next_arg(T_OBJECT);
+    int array_size = arg->size() * HeapWordSize;
+
+    if (is_after_invocation()) {
+        _array_ptr = *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]);
+        status = gpu::Ptx::_cuda_cu_memcpy_dtoh(arg, _array_ptr, array_size);
+        if (status != GRAAL_CUDA_SUCCESS) {
+            tty->print_cr("[CUDA] *** Error (%d) Failed to copy array argument to host", status);
+            _success = false;
+            return;
+        } else {
+            // tty->print_cr("device: %x host: %x size: %d", _array_ptr, arg, array_size);
+        }
+        return;
+    }
+    // Allocate device memory for T_ARRAY return value pointer on device. Size in bytes
+    status = gpu::Ptx::_cuda_cu_memalloc(&_return_value_ptr, array_size);
     if (status != GRAAL_CUDA_SUCCESS) {
-      tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
-      _success = false;
-      return;
+        tty->print_cr("[CUDA] *** Error (%d) Failed to allocate memory for return value pointer on device", status);
+        _success = false;
+        return;
+    }
+    status = gpu::Ptx::_cuda_cu_memcpy_htod(_return_value_ptr, arg, array_size);
+    if (status != GRAAL_CUDA_SUCCESS) {
+        tty->print_cr("[CUDA] *** Error (%d) Failed to copy array to device argument", status);
+        _success = false;
+        return;
+    } else {
+        // tty->print_cr("host: %x device: %x size: %d", arg, _return_value_ptr, array_size);
     }
     // Push _return_value_ptr to _kernelBuffer
     *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = _return_value_ptr;
     _bufferOffset += sizeof(_return_value_ptr);
-  }
-  else {
-    // Get the next java argument and its value which should be a T_BYTE
-    oop arg = next_arg(T_BYTE);
-    // Copy the java argument value to kernelArgBuffer
-    jvalue val;
-    if (java_lang_boxing_object::get_value(arg, &val) != T_BYTE) {
-      tty->print_cr("[CUDA] *** Error: Unexpected argument type; expecting T_BYTE");
-      _success = false;
-      return;
-    }
-    *((gpu::Ptx::CUdeviceptr*) &_kernelArgBuffer[_bufferOffset]) = val.b;
-    _bufferOffset += sizeof(val.b);
-  }
-  return;
+    return;
+}
+
+void PTXKernelArguments::do_void() {
+    return;
 }
 
 // TODO implement other do_*
--- a/src/gpu/ptx/vm/ptxKernelArguments.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/gpu/ptx/vm/ptxKernelArguments.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -28,9 +28,13 @@
 #include "runtime/gpu.hpp"
 #include "runtime/signature.hpp"
 
-#define T_BYTE_SIZE       1
-#define T_INT_BYTE_SIZE   4
-#define T_LONG_BYTE_SIZE  8
+#define T_BYTE_SIZE        1
+#define T_BOOLEAN_SIZE     4
+#define T_INT_BYTE_SIZE    4
+#define T_FLOAT_BYTE_SIZE  4
+#define T_DOUBLE_BYTE_SIZE 8
+#define T_LONG_BYTE_SIZE   8
+#define T_ARRAY_BYTE_SIZE  8
 
 class PTXKernelArguments : public SignatureIterator {
 public:
@@ -46,6 +50,8 @@
   int _index;
   // Flag to indicate successful creation of kernel argument buffer
   bool _success;
+
+    bool _afterInvoocation;
   // Get next java argument
   oop next_arg(BasicType expectedType);
 
@@ -74,6 +80,17 @@
     return _bufferOffset;
   }
 
+    void reiterate() {
+        _afterInvoocation = true;
+        _bufferOffset = 0;
+        _index = 0;
+        iterate();
+    }
+
+    inline bool is_after_invocation() {
+        return _afterInvoocation;
+    }
+
   // Get the return oop value
   oop get_return_oop();
 
@@ -84,46 +101,32 @@
 
 
   void do_byte();
+  void do_bool();
   void do_int();
+  void do_float();
+  void do_double();
   void do_long();
+  void do_array(int begin, int end);
+  void do_void();
 
-  inline void do_bool()   {
-    /* TODO : To be implemented */
-    guarantee(false, "NYI");
-  }
   inline void do_char()   {
     /* TODO : To be implemented */
-    guarantee(false, "NYI");
+    guarantee(false, "do_char:NYI");
   }
   inline void do_short()  {
     /* TODO : To be implemented */
-    guarantee(false, "NYI");
-  }
-  inline void do_float()  {
-    /* TODO : To be implemented */
-    guarantee(false, "NYI");
+    guarantee(false, "do_short:NYI");
   }
-  inline void do_double() {
-    /* TODO : To be implemented */
-    guarantee(false, "NYI");
-  }
-
   inline void do_object() {
     /* TODO : To be implemented */
-    guarantee(false, "NYI");
+    guarantee(false, "do_object:NYI");
   }
+    
   inline void do_object(int begin, int end) {
     /* TODO : To be implemented */
-    guarantee(false, "NYI");
+    guarantee(false, "do_object(II):NYI");
   }
-  inline void do_array(int begin, int end)  {
-    /* TODO : To be implemented */
-    guarantee(false, "NYI");
-  }
-  inline void do_void() {
-    /* TODO : To be implemented */
-    guarantee(false, "NYI");
-  }
+
 };
 
 #endif  // KERNEL_ARGUMENTS_HPP
--- a/src/os/windows/vm/os_windows.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/os/windows/vm/os_windows.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1642,6 +1642,8 @@
 
 void os::win32::print_windows_version(outputStream* st) {
   OSVERSIONINFOEX osvi;
+  SYSTEM_INFO si;
+
   ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
 
@@ -1651,6 +1653,18 @@
   }
 
   int os_vers = osvi.dwMajorVersion * 1000 + osvi.dwMinorVersion;
+
+  ZeroMemory(&si, sizeof(SYSTEM_INFO));
+  if (os_vers >= 5002) {
+    // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
+    // find out whether we are running on 64 bit processor or not.
+    if (os::Kernel32Dll::GetNativeSystemInfoAvailable()) {
+      os::Kernel32Dll::GetNativeSystemInfo(&si);
+    } else {
+      GetSystemInfo(&si);
+    }
+  }
+
   if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
     switch (os_vers) {
     case 3051: st->print(" Windows NT 3.51"); break;
@@ -1658,57 +1672,48 @@
     case 5000: st->print(" Windows 2000"); break;
     case 5001: st->print(" Windows XP"); break;
     case 5002:
-    case 6000:
-    case 6001:
-    case 6002: {
-      // Retrieve SYSTEM_INFO from GetNativeSystemInfo call so that we could
-      // find out whether we are running on 64 bit processor or not.
-      SYSTEM_INFO si;
-      ZeroMemory(&si, sizeof(SYSTEM_INFO));
-        if (!os::Kernel32Dll::GetNativeSystemInfoAvailable()){
-          GetSystemInfo(&si);
+      if (osvi.wProductType == VER_NT_WORKSTATION &&
+          si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
+        st->print(" Windows XP x64 Edition");
       } else {
-        os::Kernel32Dll::GetNativeSystemInfo(&si);
+        st->print(" Windows Server 2003 family");
       }
-      if (os_vers == 5002) {
-        if (osvi.wProductType == VER_NT_WORKSTATION &&
-            si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
-          st->print(" Windows XP x64 Edition");
-        else
-            st->print(" Windows Server 2003 family");
-      } else if (os_vers == 6000) {
-        if (osvi.wProductType == VER_NT_WORKSTATION)
-            st->print(" Windows Vista");
-        else
-            st->print(" Windows Server 2008");
-        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
-            st->print(" , 64 bit");
-      } else if (os_vers == 6001) {
-        if (osvi.wProductType == VER_NT_WORKSTATION) {
-            st->print(" Windows 7");
-        } else {
-            // Unrecognized windows, print out its major and minor versions
-            st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
-        }
-        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
-            st->print(" , 64 bit");
-      } else if (os_vers == 6002) {
-        if (osvi.wProductType == VER_NT_WORKSTATION) {
-            st->print(" Windows 8");
-        } else {
-            st->print(" Windows Server 2012");
-        }
-        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
-            st->print(" , 64 bit");
-      } else { // future os
-        // Unrecognized windows, print out its major and minor versions
-        st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
-        if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
-            st->print(" , 64 bit");
+      break;
+
+    case 6000:
+      if (osvi.wProductType == VER_NT_WORKSTATION) {
+        st->print(" Windows Vista");
+      } else {
+        st->print(" Windows Server 2008");
       }
       break;
-    }
-    default: // future windows, print out its major and minor versions
+
+    case 6001:
+      if (osvi.wProductType == VER_NT_WORKSTATION) {
+        st->print(" Windows 7");
+      } else {
+        st->print(" Windows Server 2008 R2");
+      }
+      break;
+
+    case 6002:
+      if (osvi.wProductType == VER_NT_WORKSTATION) {
+        st->print(" Windows 8");
+      } else {
+        st->print(" Windows Server 2012");
+      }
+      break;
+
+    case 6003:
+      if (osvi.wProductType == VER_NT_WORKSTATION) {
+        st->print(" Windows 8.1");
+      } else {
+        st->print(" Windows Server 2012 R2");
+      }
+      break;
+
+    default: // future os
+      // Unrecognized windows, print out its major and minor versions
       st->print(" Windows NT %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
     }
   } else {
@@ -1720,6 +1725,11 @@
       st->print(" Windows %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
     }
   }
+
+  if (os_vers >= 6000 && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
+    st->print(" , 64 bit");
+  }
+
   st->print(" Build %d", osvi.dwBuildNumber);
   st->print(" %s", osvi.szCSDVersion);           // service pack
   st->cr();
--- a/src/os_cpu/bsd_x86/vm/bsd_x86_32.ad	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-//
-// Copyright (c) 1999, 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.
-//
-//
-
-// X86 Bsd Architecture Description File
-
--- a/src/os_cpu/bsd_x86/vm/bsd_x86_64.ad	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-//
-// Copyright (c) 2003, 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.
-//
-//
-
-// AMD64 Bsd Architecture Description File
-
-//----------OS-DEPENDENT ENCODING BLOCK----------------------------------------
-// This block specifies the encoding classes used by the compiler to
-// output byte streams.  Encoding classes generate functions which are
-// called by Machine Instruction Nodes in order to generate the bit
-// encoding of the instruction.  Operands specify their base encoding
-// interface with the interface keyword.  There are currently
-// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
-// COND_INTER.  REG_INTER causes an operand to generate a function
-// which returns its register number when queried.  CONST_INTER causes
-// an operand to generate a function which returns the value of the
-// constant when queried.  MEMORY_INTER causes an operand to generate
-// four functions which return the Base Register, the Index Register,
-// the Scale Value, and the Offset Value of the operand when queried.
-// COND_INTER causes an operand to generate six functions which return
-// the encoding code (ie - encoding bits for the instruction)
-// associated with each basic boolean condition for a conditional
-// instruction.  Instructions specify two basic values for encoding.
-// They use the ins_encode keyword to specify their encoding class
-// (which must be one of the class names specified in the encoding
-// block), and they use the opcode keyword to specify, in order, their
-// primary, secondary, and tertiary opcode.  Only the opcode sections
-// which a particular instruction needs for encoding need to be
-// specified.
-encode %{
-  // Build emit functions for each basic byte or larger field in the intel
-  // encoding scheme (opcode, rm, sib, immediate), and call them from C++
-  // code in the enc_class source block.  Emit functions will live in the
-  // main source block for now.  In future, we can generalize this by
-  // adding a syntax that specifies the sizes of fields in an order,
-  // so that the adlc can build the emit functions automagically
-
-%}
-
-
-// Platform dependent source
-
-source %{
-
-%}
--- a/src/os_cpu/linux_x86/vm/linux_x86_32.ad	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-//
-// Copyright (c) 1999, 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.
-//
-//
-
-// X86 Linux Architecture Description File
-
--- a/src/os_cpu/linux_x86/vm/linux_x86_64.ad	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-//
-// Copyright (c) 2003, 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.
-//
-//
-
-// AMD64 Linux Architecture Description File
-
-//----------OS-DEPENDENT ENCODING BLOCK----------------------------------------
-// This block specifies the encoding classes used by the compiler to
-// output byte streams.  Encoding classes generate functions which are
-// called by Machine Instruction Nodes in order to generate the bit
-// encoding of the instruction.  Operands specify their base encoding
-// interface with the interface keyword.  There are currently
-// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
-// COND_INTER.  REG_INTER causes an operand to generate a function
-// which returns its register number when queried.  CONST_INTER causes
-// an operand to generate a function which returns the value of the
-// constant when queried.  MEMORY_INTER causes an operand to generate
-// four functions which return the Base Register, the Index Register,
-// the Scale Value, and the Offset Value of the operand when queried.
-// COND_INTER causes an operand to generate six functions which return
-// the encoding code (ie - encoding bits for the instruction)
-// associated with each basic boolean condition for a conditional
-// instruction.  Instructions specify two basic values for encoding.
-// They use the ins_encode keyword to specify their encoding class
-// (which must be one of the class names specified in the encoding
-// block), and they use the opcode keyword to specify, in order, their
-// primary, secondary, and tertiary opcode.  Only the opcode sections
-// which a particular instruction needs for encoding need to be
-// specified.
-encode %{
-  // Build emit functions for each basic byte or larger field in the intel
-  // encoding scheme (opcode, rm, sib, immediate), and call them from C++
-  // code in the enc_class source block.  Emit functions will live in the
-  // main source block for now.  In future, we can generalize this by
-  // adding a syntax that specifies the sizes of fields in an order,
-  // so that the adlc can build the emit functions automagically
-
-%}
-
-
-// Platform dependent source
-
-source %{
-
-%}
--- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -410,16 +410,6 @@
   int SpinPause() {
   }
 
-  int SafeFetch32(int *adr, int errValue) {
-    int value = errValue;
-    value = *adr;
-    return value;
-  }
-  intptr_t SafeFetchN(intptr_t *adr, intptr_t errValue) {
-    intptr_t value = errValue;
-    value = *adr;
-    return value;
-  }
 
   void _Copy_conjoint_jshorts_atomic(jshort* from, jshort* to, size_t count) {
     if (from > to) {
--- a/src/os_cpu/solaris_sparc/vm/solaris_sparc.ad	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-//
-// Copyright (c) 1999, 2007, 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.
-//
-
-//
-//
-
-// SPARC Solaris Architecture Description File
--- a/src/os_cpu/solaris_x86/vm/solaris_x86_32.ad	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-//
-// Copyright (c) 1999, 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.
-//
-//
-
-// X86 Solaris Architecture Description File
-
--- a/src/os_cpu/solaris_x86/vm/solaris_x86_64.ad	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-//
-// Copyright (c) 2004, 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.
-//
-//
-
-// AMD64 Solaris Architecture Description File
-
-//----------OS-DEPENDENT ENCODING BLOCK----------------------------------------
-// This block specifies the encoding classes used by the compiler to
-// output byte streams.  Encoding classes generate functions which are
-// called by Machine Instruction Nodes in order to generate the bit
-// encoding of the instruction.  Operands specify their base encoding
-// interface with the interface keyword.  There are currently
-// supported four interfaces, REG_INTER, CONST_INTER, MEMORY_INTER, &
-// COND_INTER.  REG_INTER causes an operand to generate a function
-// which returns its register number when queried.  CONST_INTER causes
-// an operand to generate a function which returns the value of the
-// constant when queried.  MEMORY_INTER causes an operand to generate
-// four functions which return the Base Register, the Index Register,
-// the Scale Value, and the Offset Value of the operand when queried.
-// COND_INTER causes an operand to generate six functions which return
-// the encoding code (ie - encoding bits for the instruction)
-// associated with each basic boolean condition for a conditional
-// instruction.  Instructions specify two basic values for encoding.
-// They use the ins_encode keyword to specify their encoding class
-// (which must be one of the class names specified in the encoding
-// block), and they use the opcode keyword to specify, in order, their
-// primary, secondary, and tertiary opcode.  Only the opcode sections
-// which a particular instruction needs for encoding need to be
-// specified.
-encode %{
-  // Build emit functions for each basic byte or larger field in the intel
-  // encoding scheme (opcode, rm, sib, immediate), and call them from C++
-  // code in the enc_class source block.  Emit functions will live in the
-  // main source block for now.  In future, we can generalize this by
-  // adding a syntax that specifies the sizes of fields in an order,
-  // so that the adlc can build the emit functions automagically
-%}
-
-
-// Platform dependent source
-
-source %{
-%}
--- a/src/os_cpu/windows_x86/vm/windows_x86_32.ad	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-//
-// Copyright (c) 1999, 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.
-//
-//
-
-// X86 Win32 Architecture Description File
-
--- a/src/os_cpu/windows_x86/vm/windows_x86_64.ad	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-//
-// Copyright (c) 2003, 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.
-//
-//
-
-// AMD64 Win32 Architecture Description File
-
-//----------OS-DEPENDENT ENCODING BLOCK-----------------------------------------------------
-// This block specifies the encoding classes used by the compiler to output
-// byte streams.  Encoding classes generate functions which are called by
-// Machine Instruction Nodes in order to generate the bit encoding of the
-// instruction.  Operands specify their base encoding interface with the
-// interface keyword.  There are currently supported four interfaces,
-// REG_INTER, CONST_INTER, MEMORY_INTER, & COND_INTER.  REG_INTER causes an
-// operand to generate a function which returns its register number when
-// queried.   CONST_INTER causes an operand to generate a function which
-// returns the value of the constant when queried.  MEMORY_INTER causes an
-// operand to generate four functions which return the Base Register, the
-// Index Register, the Scale Value, and the Offset Value of the operand when
-// queried.  COND_INTER causes an operand to generate six functions which
-// return the encoding code (ie - encoding bits for the instruction)
-// associated with each basic boolean condition for a conditional instruction.
-// Instructions specify two basic values for encoding.  They use the
-// ins_encode keyword to specify their encoding class (which must be one of
-// the class names specified in the encoding block), and they use the
-// opcode keyword to specify, in order, their primary, secondary, and
-// tertiary opcode.  Only the opcode sections which a particular instruction
-// needs for encoding need to be specified.
-encode %{
-  // Build emit functions for each basic byte or larger field in the intel
-  // encoding scheme (opcode, rm, sib, immediate), and call them from C++
-  // code in the enc_class source block.  Emit functions will live in the
-  // main source block for now.  In future, we can generalize this by
-  // adding a syntax that specifies the sizes of fields in an order,
-  // so that the adlc can build the emit functions automagically
-
-%}
-
-
-// Platform dependent source
-
-source %{
-
-%}
--- a/src/share/tools/ProjectCreator/BuildConfig.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/tools/ProjectCreator/BuildConfig.java	Fri Oct 11 17:21:14 2013 +0200
@@ -160,6 +160,69 @@
         return rv;
     }
 
+    // Returns true if the specified path refers to a relative alternate
+    // source file. RelativeAltSrcInclude is usually "src\closed".
+    public static boolean matchesRelativeAltSrcInclude(String path) {
+        String relativeAltSrcInclude =
+            getFieldString(null, "RelativeAltSrcInclude");
+        Vector<String> v = getFieldVector(null, "AltRelativeInclude");
+        for (String pathPart : v) {
+            if (path.contains(relativeAltSrcInclude + Util.sep + pathPart))  {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Returns the relative alternate source file for the specified path.
+    // Null is returned if the specified path does not have a matching
+    // alternate source file.
+    public static String getMatchingRelativeAltSrcFile(String path) {
+        Vector<String> v = getFieldVector(null, "RelativeAltSrcFileList");
+        if (v == null) {
+            return null;
+        }
+        for (String pathPart : v) {
+            if (path.endsWith(pathPart)) {
+                String relativeAltSrcInclude =
+                    getFieldString(null, "RelativeAltSrcInclude");
+                return relativeAltSrcInclude + Util.sep + pathPart;
+            }
+        }
+        return null;
+    }
+
+    // Returns true if the specified path has a matching alternate
+    // source file.
+    public static boolean matchesRelativeAltSrcFile(String path) {
+        return getMatchingRelativeAltSrcFile(path) != null;
+    }
+
+    // Track the specified alternate source file. The source file is
+    // tracked without the leading .*<sep><RelativeAltSrcFileList><sep>
+    // part to make matching regular source files easier.
+    public static void trackRelativeAltSrcFile(String path) {
+        String pattern = getFieldString(null, "RelativeAltSrcInclude") +
+            Util.sep;
+        int altSrcInd = path.indexOf(pattern);
+        if (altSrcInd == -1) {
+            // not an AltSrc path
+            return;
+        }
+
+        altSrcInd += pattern.length();
+        if (altSrcInd >= path.length()) {
+            // not a valid AltSrc path
+            return;
+        }
+
+        String altSrcFile = path.substring(altSrcInd);
+        Vector v = getFieldVector(null, "RelativeAltSrcFileList");
+        if (v == null || !v.contains(altSrcFile)) {
+            addFieldVector(null, "RelativeAltSrcFileList", altSrcFile);
+        }
+    }
+
     void addTo(Hashtable ht, String key, String value) {
         ht.put(expandFormat(key), expandFormat(value));
     }
@@ -306,8 +369,19 @@
 
     private Vector getSourceIncludes() {
         Vector<String> rv = new Vector<String>();
+        String sourceBase = getFieldString(null, "SourceBase");
+
+        // add relative alternate source include values:
+        String relativeAltSrcInclude =
+            getFieldString(null, "RelativeAltSrcInclude");
+        Vector<String> asri = new Vector<String>();
+        collectRelevantVectors(asri, "AltRelativeInclude");
+        for (String f : asri) {
+            rv.add(sourceBase + Util.sep + relativeAltSrcInclude +
+                   Util.sep + f);
+        }
+
         Vector<String> ri = new Vector<String>();
-        String sourceBase = getFieldString(null, "SourceBase");
         collectRelevantVectors(ri, "RelativeInclude");
         for (String f : ri) {
             rv.add(sourceBase + Util.sep + f);
@@ -607,35 +681,6 @@
     }
 }
 
-class CoreDebugConfig extends GenericDebugNonKernelConfig {
-    String getOptFlag() {
-        return getCI().getNoOptFlag();
-    }
-
-    CoreDebugConfig() {
-        initNames("core", "debug", "jvm.dll");
-        init(getIncludes(), getDefines());
-    }
-}
-
-class CoreFastDebugConfig extends GenericDebugNonKernelConfig {
-    String getOptFlag() {
-        return getCI().getOptFlag();
-    }
-
-    CoreFastDebugConfig() {
-        initNames("core", "fastdebug", "jvm.dll");
-        init(getIncludes(), getDefines());
-    }
-}
-
-class CoreProductConfig extends ProductConfig {
-    CoreProductConfig() {
-        initNames("core", "product", "jvm.dll");
-        init(getIncludes(), getDefines());
-    }
-}
-
 
 abstract class CompilerInterface {
     abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
--- a/src/share/tools/ProjectCreator/FileTreeCreator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/tools/ProjectCreator/FileTreeCreator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -12,11 +12,15 @@
    final int startDirLength;
    Stack<DirAttributes> attributes = new Stack<DirAttributes>();
    Vector<BuildConfig> allConfigs;
-   WinGammaPlatformVC10 wg;
+   WinGammaPlatform wg;
+   WinGammaPlatformVC10 wg10;
 
-   public FileTreeCreator(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatformVC10 wg) {
+   public FileTreeCreator(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatform wg) {
       super();
       this.wg = wg;
+      if (wg instanceof WinGammaPlatformVC10) {
+          wg10 = (WinGammaPlatformVC10)wg;
+      }
       this.allConfigs = allConfigs;
       this.startDir = startDir;
       startDirLength = startDir.toAbsolutePath().toString().length();
--- a/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,3 +1,27 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
 import static java.nio.file.FileVisitResult.CONTINUE;
 
 import java.io.IOException;
@@ -21,6 +45,8 @@
          boolean usePch = false;
          boolean disablePch = false;
          boolean useIgnore = false;
+         boolean isAltSrc = false;  // only needed as a debugging crumb
+         boolean isReplacedByAltSrc = false;
          String fileName = file.getFileName().toString();
 
          // TODO hideFile
@@ -30,6 +56,26 @@
             usePch = true;
          }
 
+         String fileLoc = vcProjLocation.relativize(file).toString();
+
+         // isAltSrc and isReplacedByAltSrc applies to all configs for a file
+         if (BuildConfig.matchesRelativeAltSrcInclude(
+               file.toAbsolutePath().toString())) {
+            // current file is an alternate source file so track it
+            isAltSrc = true;
+            BuildConfig.trackRelativeAltSrcFile(
+                file.toAbsolutePath().toString());
+         } else if (BuildConfig.matchesRelativeAltSrcFile(
+                    file.toAbsolutePath().toString())) {
+            // current file is a regular file that matches an alternate
+            // source file so yack about replacing the regular file
+            isReplacedByAltSrc = true;
+            System.out.println("INFO: alternate source file '" +
+                               BuildConfig.getMatchingRelativeAltSrcFile(
+                                   file.toAbsolutePath().toString()) +
+                               "' replaces '" + fileLoc + "'");
+         }
+
          for (BuildConfig cfg : allConfigs) {
             if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) {
                useIgnore = true;
@@ -58,10 +104,9 @@
             }
          }
 
-         String tagName = wg.getFileTagFromSuffix(fileName);
-         String fileLoc = vcProjLocation.relativize(file).toString();
+         String tagName = wg10.getFileTagFromSuffix(fileName);
 
-         if (!useIgnore && !disablePch && !usePch) {
+         if (!useIgnore && !disablePch && !usePch && !isReplacedByAltSrc) {
             wg.tag(tagName, new String[] { "Include", fileLoc});
          } else {
             wg.startTag(
@@ -79,12 +124,17 @@
                if (disablePch) {
                   wg.tag("PrecompiledHeader", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
                }
+               if (isReplacedByAltSrc) {
+                  wg.tagData("ExcludedFromBuild", "true", "Condition",
+                             "'$(Configuration)|$(Platform)'=='" +
+                             cfg.get("Name") + "'");
+               }
             }
             wg.endTag();
          }
 
          String filter = startDir.relativize(file.getParent().toAbsolutePath()).toString();
-         wg.addFilterDependency(fileLoc, filter);
+         wg10.addFilterDependency(fileLoc, filter);
 
          return CONTINUE;
       }
@@ -113,7 +163,7 @@
          if (!hide) {
             String name = startDir.relativize(path.toAbsolutePath()).toString();
             if (!"".equals(name)) {
-               wg.addFilter(name);
+               wg10.addFilter(name);
             }
 
             attributes.push(newAttr);
@@ -138,6 +188,4 @@
       public void writeFileTree() throws IOException {
          Files.walkFileTree(this.startDir, this);
       }
-
-
-   }
\ No newline at end of file
+}
--- a/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java	Fri Oct 11 17:21:14 2013 +0200
@@ -12,7 +12,7 @@
 public class FileTreeCreatorVC7 extends FileTreeCreator {
 
       public FileTreeCreatorVC7(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatform wg) {
-         super(startDir, allConfigs, null);
+         super(startDir, allConfigs, wg);
       }
 
       @Override
--- a/src/share/tools/ProjectCreator/ProjectCreator.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/tools/ProjectCreator/ProjectCreator.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -39,10 +39,15 @@
             + "jvm.dll; no trailing slash>");
       System.err.println("  If any of the above are specified, "
             + "they must all be.");
+      System.err.println("  Note: if '-altRelativeInclude' option below is "
+            + "used, then the '-relativeAltSrcInclude' option must be used "
+            + "to specify the alternate source dir, e.g., 'src\\closed'");
       System.err.println("  Additional, optional arguments, which can be "
             + "specified multiple times:");
       System.err.println("    -absoluteInclude <string containing absolute "
             + "path to include directory>");
+      System.err.println("    -altRelativeInclude <string containing "
+            + "alternate include directory relative to -envVar>");
       System.err.println("    -relativeInclude <string containing include "
             + "directory relative to -envVar>");
       System.err.println("    -define <preprocessor flag to be #defined "
--- a/src/share/tools/ProjectCreator/WinGammaPlatform.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/tools/ProjectCreator/WinGammaPlatform.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -140,10 +140,17 @@
                            "already exist>");
         System.err.println("  If any of the above are specified, "+
                            "they must all be.");
+        System.err.println("  Note: if '-altRelativeInclude' option below " +
+                           "is used, then the '-relativeAltSrcInclude' " +
+                           "option must be used to specify the alternate " +
+                           "source dir, e.g., 'src\\closed'");
         System.err.println("  Additional, optional arguments, which can be " +
                            "specified multiple times:");
         System.err.println("    -absoluteInclude <string containing absolute " +
                            "path to include directory>");
+        System.err.println("    -altRelativeInclude <string containing " +
+                           "alternate include directory relative to " +
+                           "-sourceBase>");
         System.err.println("    -relativeInclude <string containing include " +
                            "directory relative to -sourceBase>");
         System.err.println("    -define <preprocessor flag to be #defined " +
@@ -343,6 +350,12 @@
                               HsArgHandler.VECTOR
                               ),
 
+                new HsArgRule("-altRelativeInclude",
+                              "AltRelativeInclude",
+                              null,
+                              HsArgHandler.VECTOR
+                              ),
+
                 new HsArgRule("-relativeInclude",
                               "RelativeInclude",
                               null,
@@ -355,6 +368,12 @@
                               HsArgHandler.VECTOR
                               ),
 
+                new HsArgRule("-relativeAltSrcInclude",
+                              "RelativeAltSrcInclude",
+                              null,
+                              HsArgHandler.STRING
+                              ),
+
                 new HsArgRule("-relativeSrcInclude",
                               "RelativeSrcInclude",
                               null,
@@ -564,10 +583,6 @@
         allConfigs.add(new TieredFastDebugConfig());
         allConfigs.add(new TieredProductConfig());
 
-        allConfigs.add(new CoreDebugConfig());
-        allConfigs.add(new CoreFastDebugConfig());
-        allConfigs.add(new CoreProductConfig());
-
         return allConfigs;
     }
 
--- a/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,3 +1,27 @@
+/*
+ * Copyright (c) 2011, 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.
+ *
+ */
+
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
@@ -24,7 +48,7 @@
     public void writeProjectFile(String projectFileName, String projectName,
             Vector<BuildConfig> allConfigs) throws IOException {
         System.out.println();
-        System.out.print("    Writing .vcxproj file: " + projectFileName);
+        System.out.println("    Writing .vcxproj file: " + projectFileName);
 
         String projDir = Util.normalize(new File(projectFileName).getParent());
 
@@ -114,7 +138,7 @@
 
         endTag();
         printWriter.close();
-        System.out.println("    Done.");
+        System.out.println("    Done writing .vcxproj file.");
 
         writeFilterFile(projectFileName, projectName, allConfigs, projDir);
         writeUserFile(projectFileName, allConfigs);
--- a/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java	Fri Oct 11 17:21:14 2013 +0200
@@ -139,19 +139,22 @@
 
       tagV("Tool", cfg.getV("LinkerFlags"));
 
-      tag("Tool",
-            new String[] {
-            "Name",
-            "VCPostBuildEventTool",
-            "Description",
-            BuildConfig
-            .getFieldString(null, "PostbuildDescription"),
-            // Caution: String.replace(String,String) is available
-            // from JDK5 onwards only
-            "CommandLine",
-            cfg.expandFormat(BuildConfig.getFieldString(null,
-                  "PostbuildCommand").replace("\t",
-                        "&#x0D;&#x0A;")) });
+      String postBuildCmd = BuildConfig.getFieldString(null,
+            "PostbuildCommand");
+      if (postBuildCmd != null) {
+         tag("Tool",
+               new String[] {
+               "Name",
+               "VCPostBuildEventTool",
+               "Description",
+               BuildConfig
+               .getFieldString(null, "PostbuildDescription"),
+               // Caution: String.replace(String,String) is available
+               // from JDK5 onwards only
+               "CommandLine",
+                   cfg.expandFormat(postBuildCmd.replace("\t",
+                           "&#x0D;&#x0A;")) });
+      }
 
       tag("Tool", new String[] { "Name", "VCPreBuildEventTool" });
 
--- a/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/c1/c1_LIRGenerator.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -2295,7 +2295,7 @@
       if (gen_type_check) {
         // We have determined that offset == referent_offset && src != null.
         // if (src->_klass->_reference_type == REF_NONE) -> continue
-        __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), UseCompressedKlassPointers ? T_OBJECT : T_ADDRESS), src_klass);
+        __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), src_klass);
         LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(InstanceKlass::reference_type_offset()), T_BYTE);
         LIR_Opr reference_type = new_register(T_INT);
         __ move(reference_type_addr, reference_type);
--- a/src/share/vm/ci/ciReplay.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/ci/ciReplay.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -299,7 +299,7 @@
     Symbol* method_signature = parse_symbol(CHECK_NULL);
     Method* m = k->find_method(method_name, method_signature);
     if (m == NULL) {
-      report_error("can't find method");
+      report_error("Can't find method");
     }
     return m;
   }
@@ -398,8 +398,8 @@
 
   // compile <klass> <name> <signature> <entry_bci> <comp_level>
   void process_compile(TRAPS) {
-    // methodHandle method;
     Method* method = parse_method(CHECK);
+    if (had_error()) return;
     int entry_bci = parse_int("entry_bci");
     const char* comp_level_label = "comp_level";
     int comp_level = parse_int(comp_level_label);
@@ -440,6 +440,7 @@
   //
   void process_ciMethod(TRAPS) {
     Method* method = parse_method(CHECK);
+    if (had_error()) return;
     ciMethodRecord* rec = new_ciMethod(method);
     rec->invocation_counter = parse_int("invocation_counter");
     rec->backedge_counter = parse_int("backedge_counter");
@@ -451,6 +452,7 @@
   // ciMethodData <klass> <name> <signature> <state> <current mileage> orig <length> # # ... data <length> # # ... oops <length>
   void process_ciMethodData(TRAPS) {
     Method* method = parse_method(CHECK);
+    if (had_error()) return;
     /* jsut copied from Method, to build interpret data*/
     if (InstanceRefKlass::owns_pending_list_lock((JavaThread*)THREAD)) {
       return;
--- a/src/share/vm/classfile/classLoader.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/classfile/classLoader.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -878,7 +878,7 @@
 
 instanceKlassHandle ClassLoader::load_classfile(Symbol* h_name, TRAPS) {
   ResourceMark rm(THREAD);
-  EventMark m("loading class " INTPTR_FORMAT, (address)h_name);
+  EventMark m("loading class %s", h_name->as_C_string());
   ThreadProfilerMark tpm(ThreadProfilerMark::classLoaderRegion);
 
   stringStream st;
--- a/src/share/vm/classfile/javaClasses.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/classfile/javaClasses.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -2563,6 +2563,26 @@
   *offset = value;
 }
 
+// Support for java_lang_invoke_DirectMethodHandle
+
+int java_lang_invoke_DirectMethodHandle::_member_offset;
+
+oop java_lang_invoke_DirectMethodHandle::member(oop dmh) {
+  oop member_name = NULL;
+  bool is_dmh = dmh->is_oop() && java_lang_invoke_DirectMethodHandle::is_instance(dmh);
+  assert(is_dmh, "a DirectMethodHandle oop is expected");
+  if (is_dmh) {
+    member_name = dmh->obj_field(member_offset_in_bytes());
+  }
+  return member_name;
+}
+
+void java_lang_invoke_DirectMethodHandle::compute_offsets() {
+  Klass* klass_oop = SystemDictionary::DirectMethodHandle_klass();
+  if (klass_oop != NULL && EnableInvokeDynamic) {
+    compute_offset(_member_offset, klass_oop, vmSymbols::member_name(), vmSymbols::java_lang_invoke_MemberName_signature());
+  }
+}
 
 // Support for java_lang_invoke_MethodHandle
 
@@ -3214,6 +3234,7 @@
   java_lang_ThreadGroup::compute_offsets();
   if (EnableInvokeDynamic) {
     java_lang_invoke_MethodHandle::compute_offsets();
+    java_lang_invoke_DirectMethodHandle::compute_offsets();
     java_lang_invoke_MemberName::compute_offsets();
     java_lang_invoke_LambdaForm::compute_offsets();
     java_lang_invoke_MethodType::compute_offsets();
--- a/src/share/vm/classfile/javaClasses.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/classfile/javaClasses.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -986,6 +986,32 @@
   static int form_offset_in_bytes()             { return _form_offset; }
 };
 
+// Interface to java.lang.invoke.DirectMethodHandle objects
+
+class java_lang_invoke_DirectMethodHandle: AllStatic {
+  friend class JavaClasses;
+
+ private:
+  static int _member_offset;               // the MemberName of this DMH
+
+  static void compute_offsets();
+
+ public:
+  // Accessors
+  static oop  member(oop mh);
+
+  // Testers
+  static bool is_subclass(Klass* klass) {
+    return klass->is_subclass_of(SystemDictionary::DirectMethodHandle_klass());
+  }
+  static bool is_instance(oop obj) {
+    return obj != NULL && is_subclass(obj->klass());
+  }
+
+  // Accessors for code generation:
+  static int member_offset_in_bytes()           { return _member_offset; }
+};
+
 // Interface to java.lang.invoke.LambdaForm objects
 // (These are a private interface for managing adapter code generation.)
 
--- a/src/share/vm/classfile/systemDictionary.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/classfile/systemDictionary.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -151,6 +151,7 @@
   do_klass(reflect_CallerSensitive_klass,               sun_reflect_CallerSensitive,               Opt                 ) \
                                                                                                                          \
   /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */                                            \
+  do_klass(DirectMethodHandle_klass,                    java_lang_invoke_DirectMethodHandle,       Opt                 ) \
   do_klass(MethodHandle_klass,                          java_lang_invoke_MethodHandle,             Pre_JSR292          ) \
   do_klass(MemberName_klass,                            java_lang_invoke_MemberName,               Pre_JSR292          ) \
   do_klass(MethodHandleNatives_klass,                   java_lang_invoke_MethodHandleNatives,      Pre_JSR292          ) \
@@ -202,6 +203,7 @@
   do_klass(HotSpotResolvedObjectType_klass,       com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType,      Opt) \
   do_klass(HotSpotMonitorValue_klass,             com_oracle_graal_hotspot_meta_HotSpotMonitorValue,            Opt) \
   do_klass(LocalImpl_klass,                       com_oracle_graal_hotspot_debug_LocalImpl,                     Opt) \
+  do_klass(CompilerThread_klass,                  com_oracle_graal_hotspot_CompilerThread,                      Opt) \
   /* graal.api.code */                                                                                               \
   do_klass(Assumptions_klass,                     com_oracle_graal_api_code_Assumptions,                        Opt) \
   do_klass(Assumptions_ConcreteMethod_klass,      com_oracle_graal_api_code_Assumptions_ConcreteMethod,         Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/classfile/vmSymbols.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -255,6 +255,7 @@
   /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */                                   \
   template(java_lang_invoke_CallSite,                 "java/lang/invoke/CallSite")                \
   template(java_lang_invoke_ConstantCallSite,         "java/lang/invoke/ConstantCallSite")        \
+  template(java_lang_invoke_DirectMethodHandle,       "java/lang/invoke/DirectMethodHandle")      \
   template(java_lang_invoke_MutableCallSite,          "java/lang/invoke/MutableCallSite")         \
   template(java_lang_invoke_VolatileCallSite,         "java/lang/invoke/VolatileCallSite")        \
   template(java_lang_invoke_MethodHandle,             "java/lang/invoke/MethodHandle")            \
@@ -311,6 +312,7 @@
   template(com_oracle_graal_hotspot_meta_HotSpotResolvedObjectType,  "com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType")       \
   template(com_oracle_graal_hotspot_meta_HotSpotMonitorValue,        "com/oracle/graal/hotspot/meta/HotSpotMonitorValue")             \
   template(com_oracle_graal_hotspot_debug_LocalImpl,                 "com/oracle/graal/hotspot/debug/LocalImpl")                      \
+  template(com_oracle_graal_hotspot_CompilerThread,                  "com/oracle/graal/hotspot/CompilerThread")                       \
   template(com_oracle_graal_hotspot_ptx_PTXHotSpotGraalRuntime,      "com/oracle/graal/hotspot/ptx/PTXHotSpotGraalRuntime")\
   AMD64_ONLY(template(com_oracle_graal_hotspot_amd64_AMD64HotSpotGraalRuntime,"com/oracle/graal/hotspot/amd64/AMD64HotSpotGraalRuntime"))\
   SPARC_ONLY(template(com_oracle_graal_hotspot_sparc_SPARCHotSpotGraalRuntime,"com/oracle/graal/hotspot/sparc/SPARCHotSpotGraalRuntime"))\
@@ -463,6 +465,7 @@
   template(thread_id_name,                            "tid")                                      \
   template(newInstance0_name,                         "newInstance0")                             \
   template(limit_name,                                "limit")                                    \
+  template(member_name,                               "member")                                   \
   template(forName_name,                              "forName")                                  \
   template(forName0_name,                             "forName0")                                 \
   template(isJavaIdentifierStart_name,                "isJavaIdentifierStart")                    \
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -122,6 +122,22 @@
   }
 };
 
+class Par_MarkRefsIntoClosure: public CMSOopsInGenClosure {
+ private:
+  const MemRegion _span;
+  CMSBitMap*      _bitMap;
+ protected:
+  DO_OOP_WORK_DEFN
+ public:
+  Par_MarkRefsIntoClosure(MemRegion span, CMSBitMap* bitMap);
+  virtual void do_oop(oop* p);
+  virtual void do_oop(narrowOop* p);
+
+  Prefetch::style prefetch_style() {
+    return Prefetch::do_read;
+  }
+};
+
 // A variant of the above used in certain kinds of CMS
 // marking verification.
 class MarkRefsIntoVerifyClosure: public CMSOopsInGenClosure {
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -50,6 +50,7 @@
 #include "memory/genMarkSweep.hpp"
 #include "memory/genOopClosures.inline.hpp"
 #include "memory/iterator.hpp"
+#include "memory/padded.hpp"
 #include "memory/referencePolicy.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/tenuredGeneration.hpp"
@@ -569,6 +570,7 @@
   _restart_addr(NULL),
   _overflow_list(NULL),
   _stats(cmsGen),
+  _eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true)),
   _eden_chunk_array(NULL),     // may be set in ctor body
   _eden_chunk_capacity(0),     // -- ditto --
   _eden_chunk_index(0),        // -- ditto --
@@ -732,7 +734,7 @@
   assert(_eden_chunk_array != NULL || _eden_chunk_capacity == 0, "Error");
 
   // Support for parallelizing survivor space rescan
-  if (CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) {
+  if ((CMSParallelRemarkEnabled && CMSParallelSurvivorRemarkEnabled) || CMSParallelInitialMarkEnabled) {
     const size_t max_plab_samples =
       ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
 
@@ -2137,6 +2139,39 @@
 }
 
 
+void CMSCollector::print_eden_and_survivor_chunk_arrays() {
+  DefNewGeneration* dng = _young_gen->as_DefNewGeneration();
+  EdenSpace* eden_space = dng->eden();
+  ContiguousSpace* from_space = dng->from();
+  ContiguousSpace* to_space   = dng->to();
+  // Eden
+  if (_eden_chunk_array != NULL) {
+    gclog_or_tty->print_cr("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
+                           eden_space->bottom(), eden_space->top(),
+                           eden_space->end(), eden_space->capacity());
+    gclog_or_tty->print_cr("_eden_chunk_index=" SIZE_FORMAT ", "
+                           "_eden_chunk_capacity=" SIZE_FORMAT,
+                           _eden_chunk_index, _eden_chunk_capacity);
+    for (size_t i = 0; i < _eden_chunk_index; i++) {
+      gclog_or_tty->print_cr("_eden_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
+                             i, _eden_chunk_array[i]);
+    }
+  }
+  // Survivor
+  if (_survivor_chunk_array != NULL) {
+    gclog_or_tty->print_cr("survivor " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")",
+                           from_space->bottom(), from_space->top(),
+                           from_space->end(), from_space->capacity());
+    gclog_or_tty->print_cr("_survivor_chunk_index=" SIZE_FORMAT ", "
+                           "_survivor_chunk_capacity=" SIZE_FORMAT,
+                           _survivor_chunk_index, _survivor_chunk_capacity);
+    for (size_t i = 0; i < _survivor_chunk_index; i++) {
+      gclog_or_tty->print_cr("_survivor_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT,
+                             i, _survivor_chunk_array[i]);
+    }
+  }
+}
+
 void CMSCollector::getFreelistLocks() const {
   // Get locks for all free lists in all generations that this
   // collector is responsible for
@@ -3549,6 +3584,31 @@
 
 // CMS work
 
+// The common parts of CMSParInitialMarkTask and CMSParRemarkTask.
+class CMSParMarkTask : public AbstractGangTask {
+ protected:
+  CMSCollector*     _collector;
+  int               _n_workers;
+  CMSParMarkTask(const char* name, CMSCollector* collector, int n_workers) :
+      AbstractGangTask(name),
+      _collector(collector),
+      _n_workers(n_workers) {}
+  // Work method in support of parallel rescan ... of young gen spaces
+  void do_young_space_rescan(uint worker_id, OopsInGenClosure* cl,
+                             ContiguousSpace* space,
+                             HeapWord** chunk_array, size_t chunk_top);
+  void work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl);
+};
+
+// Parallel initial mark task
+class CMSParInitialMarkTask: public CMSParMarkTask {
+ public:
+  CMSParInitialMarkTask(CMSCollector* collector, int n_workers) :
+      CMSParMarkTask("Scan roots and young gen for initial mark in parallel",
+                     collector, n_workers) {}
+  void work(uint worker_id);
+};
+
 // Checkpoint the roots into this generation from outside
 // this generation. [Note this initial checkpoint need only
 // be approximate -- we'll do a catch up phase subsequently.]
@@ -3646,19 +3706,42 @@
   // the klasses. The claimed marks need to be cleared before marking starts.
   ClassLoaderDataGraph::clear_claimed_marks();
 
-  CMKlassClosure klass_closure(&notOlder);
+  if (CMSPrintEdenSurvivorChunks) {
+    print_eden_and_survivor_chunk_arrays();
+  }
+
   {
     COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
-    gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
-    gch->gen_process_strong_roots(_cmsGen->level(),
-                                  true,   // younger gens are roots
-                                  true,   // activate StrongRootsScope
-                                  false,  // not scavenging
-                                  SharedHeap::ScanningOption(roots_scanning_options()),
-                                  &notOlder,
-                                  true,   // walk all of code cache if (so & SO_CodeCache)
-                                  NULL,
-                                  &klass_closure);
+    if (CMSParallelInitialMarkEnabled && CollectedHeap::use_parallel_gc_threads()) {
+      // The parallel version.
+      FlexibleWorkGang* workers = gch->workers();
+      assert(workers != NULL, "Need parallel worker threads.");
+      int n_workers = workers->active_workers();
+      CMSParInitialMarkTask tsk(this, n_workers);
+      gch->set_par_threads(n_workers);
+      initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
+      if (n_workers > 1) {
+        GenCollectedHeap::StrongRootsScope srs(gch);
+        workers->run_task(&tsk);
+      } else {
+        GenCollectedHeap::StrongRootsScope srs(gch);
+        tsk.work(0);
+      }
+      gch->set_par_threads(0);
+    } else {
+      // The serial version.
+      CMKlassClosure klass_closure(&notOlder);
+      gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
+      gch->gen_process_strong_roots(_cmsGen->level(),
+                                    true,   // younger gens are roots
+                                    true,   // activate StrongRootsScope
+                                    false,  // not scavenging
+                                    SharedHeap::ScanningOption(roots_scanning_options()),
+                                    &notOlder,
+                                    true,   // walk all of code cache if (so & SO_CodeCache)
+                                    NULL,
+                                    &klass_closure);
+    }
   }
 
   // Clear mod-union table; it will be dirtied in the prologue of
@@ -4417,7 +4500,9 @@
   verify_overflow_empty();
   _abort_preclean = false;
   if (CMSPrecleaningEnabled) {
-    _eden_chunk_index = 0;
+    if (!CMSEdenChunksRecordAlways) {
+      _eden_chunk_index = 0;
+    }
     size_t used = get_eden_used();
     size_t capacity = get_eden_capacity();
     // Don't start sampling unless we will get sufficiently
@@ -4526,7 +4611,9 @@
   if (!_start_sampling) {
     return;
   }
-  if (_eden_chunk_array) {
+  // When CMSEdenChunksRecordAlways is true, the eden chunk array
+  // is populated by the young generation.
+  if (_eden_chunk_array != NULL && !CMSEdenChunksRecordAlways) {
     if (_eden_chunk_index < _eden_chunk_capacity) {
       _eden_chunk_array[_eden_chunk_index] = *_top_addr;   // take sample
       assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
@@ -5010,6 +5097,10 @@
     // Update the saved marks which may affect the root scans.
     gch->save_marks();
 
+    if (CMSPrintEdenSurvivorChunks) {
+      print_eden_and_survivor_chunk_arrays();
+    }
+
     {
       COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;)
 
@@ -5116,10 +5207,53 @@
   }
 }
 
+void CMSParInitialMarkTask::work(uint worker_id) {
+  elapsedTimer _timer;
+  ResourceMark rm;
+  HandleMark   hm;
+
+  // ---------- scan from roots --------------
+  _timer.start();
+  GenCollectedHeap* gch = GenCollectedHeap::heap();
+  Par_MarkRefsIntoClosure par_mri_cl(_collector->_span, &(_collector->_markBitMap));
+  CMKlassClosure klass_closure(&par_mri_cl);
+
+  // ---------- young gen roots --------------
+  {
+    work_on_young_gen_roots(worker_id, &par_mri_cl);
+    _timer.stop();
+    if (PrintCMSStatistics != 0) {
+      gclog_or_tty->print_cr(
+        "Finished young gen initial mark scan work in %dth thread: %3.3f sec",
+        worker_id, _timer.seconds());
+    }
+  }
+
+  // ---------- remaining roots --------------
+  _timer.reset();
+  _timer.start();
+  gch->gen_process_strong_roots(_collector->_cmsGen->level(),
+                                false,     // yg was scanned above
+                                false,     // this is parallel code
+                                false,     // not scavenging
+                                SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
+                                &par_mri_cl,
+                                true,   // walk all of code cache if (so & SO_CodeCache)
+                                NULL,
+                                &klass_closure);
+  assert(_collector->should_unload_classes()
+         || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_CodeCache),
+         "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops");
+  _timer.stop();
+  if (PrintCMSStatistics != 0) {
+    gclog_or_tty->print_cr(
+      "Finished remaining root initial mark scan work in %dth thread: %3.3f sec",
+      worker_id, _timer.seconds());
+  }
+}
+
 // Parallel remark task
-class CMSParRemarkTask: public AbstractGangTask {
-  CMSCollector* _collector;
-  int           _n_workers;
+class CMSParRemarkTask: public CMSParMarkTask {
   CompactibleFreeListSpace* _cms_space;
 
   // The per-thread work queues, available here for stealing.
@@ -5133,10 +5267,9 @@
                    CompactibleFreeListSpace* cms_space,
                    int n_workers, FlexibleWorkGang* workers,
                    OopTaskQueueSet* task_queues):
-    AbstractGangTask("Rescan roots and grey objects in parallel"),
-    _collector(collector),
+    CMSParMarkTask("Rescan roots and grey objects in parallel",
+                   collector, n_workers),
     _cms_space(cms_space),
-    _n_workers(n_workers),
     _task_queues(task_queues),
     _term(n_workers, task_queues) { }
 
@@ -5150,11 +5283,6 @@
   void work(uint worker_id);
 
  private:
-  // Work method in support of parallel rescan ... of young gen spaces
-  void do_young_space_rescan(int i, Par_MarkRefsIntoAndScanClosure* cl,
-                             ContiguousSpace* space,
-                             HeapWord** chunk_array, size_t chunk_top);
-
   // ... of  dirty cards in old space
   void do_dirty_card_rescan_tasks(CompactibleFreeListSpace* sp, int i,
                                   Par_MarkRefsIntoAndScanClosure* cl);
@@ -5186,6 +5314,25 @@
   }
 };
 
+void CMSParMarkTask::work_on_young_gen_roots(uint worker_id, OopsInGenClosure* cl) {
+  DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
+  EdenSpace* eden_space = dng->eden();
+  ContiguousSpace* from_space = dng->from();
+  ContiguousSpace* to_space   = dng->to();
+
+  HeapWord** eca = _collector->_eden_chunk_array;
+  size_t     ect = _collector->_eden_chunk_index;
+  HeapWord** sca = _collector->_survivor_chunk_array;
+  size_t     sct = _collector->_survivor_chunk_index;
+
+  assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
+  assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
+
+  do_young_space_rescan(worker_id, cl, to_space, NULL, 0);
+  do_young_space_rescan(worker_id, cl, from_space, sca, sct);
+  do_young_space_rescan(worker_id, cl, eden_space, eca, ect);
+}
+
 // work_queue(i) is passed to the closure
 // Par_MarkRefsIntoAndScanClosure.  The "i" parameter
 // also is passed to do_dirty_card_rescan_tasks() and to
@@ -5210,23 +5357,7 @@
   // work first.
   // ---------- young gen roots --------------
   {
-    DefNewGeneration* dng = _collector->_young_gen->as_DefNewGeneration();
-    EdenSpace* eden_space = dng->eden();
-    ContiguousSpace* from_space = dng->from();
-    ContiguousSpace* to_space   = dng->to();
-
-    HeapWord** eca = _collector->_eden_chunk_array;
-    size_t     ect = _collector->_eden_chunk_index;
-    HeapWord** sca = _collector->_survivor_chunk_array;
-    size_t     sct = _collector->_survivor_chunk_index;
-
-    assert(ect <= _collector->_eden_chunk_capacity, "out of bounds");
-    assert(sct <= _collector->_survivor_chunk_capacity, "out of bounds");
-
-    do_young_space_rescan(worker_id, &par_mrias_cl, to_space, NULL, 0);
-    do_young_space_rescan(worker_id, &par_mrias_cl, from_space, sca, sct);
-    do_young_space_rescan(worker_id, &par_mrias_cl, eden_space, eca, ect);
-
+    work_on_young_gen_roots(worker_id, &par_mrias_cl);
     _timer.stop();
     if (PrintCMSStatistics != 0) {
       gclog_or_tty->print_cr(
@@ -5334,8 +5465,8 @@
 
 // Note that parameter "i" is not used.
 void
-CMSParRemarkTask::do_young_space_rescan(int i,
-  Par_MarkRefsIntoAndScanClosure* cl, ContiguousSpace* space,
+CMSParMarkTask::do_young_space_rescan(uint worker_id,
+  OopsInGenClosure* cl, ContiguousSpace* space,
   HeapWord** chunk_array, size_t chunk_top) {
   // Until all tasks completed:
   // . claim an unclaimed task
@@ -5530,6 +5661,32 @@
          "Else our work is not yet done");
 }
 
+// Record object boundaries in _eden_chunk_array by sampling the eden
+// top in the slow-path eden object allocation code path and record
+// the boundaries, if CMSEdenChunksRecordAlways is true. If
+// CMSEdenChunksRecordAlways is false, we use the other asynchronous
+// sampling in sample_eden() that activates during the part of the
+// preclean phase.
+void CMSCollector::sample_eden_chunk() {
+  if (CMSEdenChunksRecordAlways && _eden_chunk_array != NULL) {
+    if (_eden_chunk_lock->try_lock()) {
+      // Record a sample. This is the critical section. The contents
+      // of the _eden_chunk_array have to be non-decreasing in the
+      // address order.
+      _eden_chunk_array[_eden_chunk_index] = *_top_addr;
+      assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr,
+             "Unexpected state of Eden");
+      if (_eden_chunk_index == 0 ||
+          ((_eden_chunk_array[_eden_chunk_index] > _eden_chunk_array[_eden_chunk_index-1]) &&
+           (pointer_delta(_eden_chunk_array[_eden_chunk_index],
+                          _eden_chunk_array[_eden_chunk_index-1]) >= CMSSamplingGrain))) {
+        _eden_chunk_index++;  // commit sample
+      }
+      _eden_chunk_lock->unlock();
+    }
+  }
+}
+
 // Return a thread-local PLAB recording array, as appropriate.
 void* CMSCollector::get_data_recorder(int thr_num) {
   if (_survivor_plab_array != NULL &&
@@ -5553,12 +5710,13 @@
 
 // Merge the per-thread plab arrays into the global survivor chunk
 // array which will provide the partitioning of the survivor space
-// for CMS rescan.
+// for CMS initial scan and rescan.
 void CMSCollector::merge_survivor_plab_arrays(ContiguousSpace* surv,
                                               int no_of_gc_threads) {
   assert(_survivor_plab_array  != NULL, "Error");
   assert(_survivor_chunk_array != NULL, "Error");
-  assert(_collectorState == FinalMarking, "Error");
+  assert(_collectorState == FinalMarking ||
+         (CMSParallelInitialMarkEnabled && _collectorState == InitialMarking), "Error");
   for (int j = 0; j < no_of_gc_threads; j++) {
     _cursor[j] = 0;
   }
@@ -5621,7 +5779,7 @@
 }
 
 // Set up the space's par_seq_tasks structure for work claiming
-// for parallel rescan of young gen.
+// for parallel initial scan and rescan of young gen.
 // See ParRescanTask where this is currently used.
 void
 CMSCollector::
@@ -6748,6 +6906,28 @@
 void MarkRefsIntoClosure::do_oop(oop* p)       { MarkRefsIntoClosure::do_oop_work(p); }
 void MarkRefsIntoClosure::do_oop(narrowOop* p) { MarkRefsIntoClosure::do_oop_work(p); }
 
+Par_MarkRefsIntoClosure::Par_MarkRefsIntoClosure(
+  MemRegion span, CMSBitMap* bitMap):
+    _span(span),
+    _bitMap(bitMap)
+{
+    assert(_ref_processor == NULL, "deliberately left NULL");
+    assert(_bitMap->covers(_span), "_bitMap/_span mismatch");
+}
+
+void Par_MarkRefsIntoClosure::do_oop(oop obj) {
+  // if p points into _span, then mark corresponding bit in _markBitMap
+  assert(obj->is_oop(), "expected an oop");
+  HeapWord* addr = (HeapWord*)obj;
+  if (_span.contains(addr)) {
+    // this should be made more efficient
+    _bitMap->par_mark(addr);
+  }
+}
+
+void Par_MarkRefsIntoClosure::do_oop(oop* p)       { Par_MarkRefsIntoClosure::do_oop_work(p); }
+void Par_MarkRefsIntoClosure::do_oop(narrowOop* p) { Par_MarkRefsIntoClosure::do_oop_work(p); }
+
 // A variant of the above, used for CMS marking verification.
 MarkRefsIntoVerifyClosure::MarkRefsIntoVerifyClosure(
   MemRegion span, CMSBitMap* verification_bm, CMSBitMap* cms_bm):
@@ -9305,7 +9485,6 @@
     return;
   }
 }
-
 // Transfer some number of overflown objects to usual marking
 // stack. Return true if some objects were transferred.
 bool MarkRefsIntoAndScanClosure::take_from_overflow_list() {
@@ -9377,4 +9556,3 @@
       ShouldNotReachHere();
   }
 }
-
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -515,6 +515,8 @@
   friend class ConcurrentMarkSweepThread;
   friend class ConcurrentMarkSweepGeneration;
   friend class CompactibleFreeListSpace;
+  friend class CMSParMarkTask;
+  friend class CMSParInitialMarkTask;
   friend class CMSParRemarkTask;
   friend class CMSConcMarkingTask;
   friend class CMSRefProcTaskProxy;
@@ -749,6 +751,7 @@
   Generation* _young_gen;  // the younger gen
   HeapWord** _top_addr;    // ... Top of Eden
   HeapWord** _end_addr;    // ... End of Eden
+  Mutex*     _eden_chunk_lock;
   HeapWord** _eden_chunk_array; // ... Eden partitioning array
   size_t     _eden_chunk_index; // ... top (exclusive) of array
   size_t     _eden_chunk_capacity;  // ... max entries in array
@@ -950,6 +953,7 @@
 
   // Support for parallel remark of survivor space
   void* get_data_recorder(int thr_num);
+  void sample_eden_chunk();
 
   CMSBitMap* markBitMap()  { return &_markBitMap; }
   void directAllocated(HeapWord* start, size_t size);
@@ -1027,6 +1031,8 @@
 
   // Initialization errors
   bool completed_initialization() { return _completed_initialization; }
+
+  void print_eden_and_survivor_chunk_arrays();
 };
 
 class CMSExpansionCause : public AllStatic  {
@@ -1317,6 +1323,10 @@
     //Delegate to collector
     return collector()->get_data_recorder(thr_num);
   }
+  void sample_eden_chunk() {
+    //Delegate to collector
+    return collector()->sample_eden_chunk();
+  }
 
   // Printing
   const char* name() const;
--- a/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/g1/g1_globals.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -96,11 +96,6 @@
           "the buffer will be enqueued for processing. A value of 0 "       \
           "specifies that mutator threads should not do such filtering.")   \
                                                                             \
-  develop(intx, G1ExtraRegionSurvRate, 33,                                  \
-          "If the young survival rate is S, and there's room left in "      \
-          "to-space, we will allow regions whose survival rate is up to "   \
-          "S + (1 - S)*X, where X is this parameter (as a fraction.)")      \
-                                                                            \
   develop(bool, G1SATBPrintStubs, false,                                    \
           "If true, print generated stubs for the SATB barrier")            \
                                                                             \
@@ -110,9 +105,6 @@
   develop(bool, G1RSBarrierRegionFilter, true,                              \
           "If true, generate region filtering code in RS barrier")          \
                                                                             \
-  develop(bool, G1RSBarrierNullFilter, true,                                \
-          "If true, generate null-pointer filtering code in RS barrier")    \
-                                                                            \
   develop(bool, G1DeferredRSUpdate, true,                                   \
           "If true, use deferred RS updates")                               \
                                                                             \
@@ -120,9 +112,6 @@
           "If true, verify that no dirty cards remain after RS log "        \
           "processing.")                                                    \
                                                                             \
-  develop(bool, G1RSCountHisto, false,                                      \
-          "If true, print a histogram of RS occupancies after each pause")  \
-                                                                            \
   diagnostic(bool, G1PrintRegionLivenessInfo, false,                        \
             "Prints the liveness information for all regions in the heap "  \
             "at the end of a marking cycle.")                               \
@@ -169,9 +158,6 @@
   product(uintx, G1ConcRSHotCardLimit, 4,                                   \
           "The threshold that defines (>=) a hot card.")                    \
                                                                             \
-  develop(bool, G1PrintOopAppls, false,                                     \
-          "When true, print applications of closures to external locs.")    \
-                                                                            \
   develop(intx, G1RSetRegionEntriesBase, 256,                               \
           "Max number of regions in a fine-grain table per MB.")            \
                                                                             \
--- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -314,6 +314,11 @@
     region_size = MAX_REGION_SIZE;
   }
 
+  if (region_size != G1HeapRegionSize) {
+    // Update the flag to make sure that PrintFlagsFinal logs the correct value
+    FLAG_SET_ERGO(uintx, G1HeapRegionSize, region_size);
+  }
+
   // And recalculate the log.
   region_size_log = log2_long((jlong) region_size);
 
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -927,11 +927,9 @@
                                    workers->active_workers(),
                                    Threads::number_of_non_daemon_threads());
   workers->set_active_workers(active_workers);
-  _next_gen = gch->next_gen(this);
-  assert(_next_gen != NULL,
-    "This must be the youngest gen, and not the only gen");
   assert(gch->n_gens() == 2,
          "Par collection currently only works with single older gen.");
+  _next_gen = gch->next_gen(this);
   // Do we have to avoid promotion_undo?
   if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) {
     set_avoid_promotion_undo(true);
--- a/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -29,6 +29,7 @@
 #include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
 #include "memory/defNewGeneration.hpp"
+#include "memory/padded.hpp"
 #include "utilities/taskqueue.hpp"
 
 class ChunkArray;
--- a/src/share/vm/gc_implementation/parNew/parOopClosures.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/parNew/parOopClosures.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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
@@ -26,6 +26,7 @@
 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PAROOPCLOSURES_HPP
 
 #include "memory/genOopClosures.hpp"
+#include "memory/padded.hpp"
 
 // Closures for ParNewGeneration
 
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -29,14 +29,16 @@
 #include "gc_implementation/parallelScavenge/psScavenge.inline.hpp"
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/mutableSpace.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/memRegion.hpp"
+#include "memory/padded.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/oop.psgc.inline.hpp"
 
-PSPromotionManager**         PSPromotionManager::_manager_array = NULL;
-OopStarTaskQueueSet*         PSPromotionManager::_stack_array_depth = NULL;
-PSOldGen*                    PSPromotionManager::_old_gen = NULL;
-MutableSpace*                PSPromotionManager::_young_space = NULL;
+PaddedEnd<PSPromotionManager>* PSPromotionManager::_manager_array = NULL;
+OopStarTaskQueueSet*           PSPromotionManager::_stack_array_depth = NULL;
+PSOldGen*                      PSPromotionManager::_old_gen = NULL;
+MutableSpace*                  PSPromotionManager::_young_space = NULL;
 
 void PSPromotionManager::initialize() {
   ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap();
@@ -45,8 +47,10 @@
   _old_gen = heap->old_gen();
   _young_space = heap->young_gen()->to_space();
 
+  // To prevent false sharing, we pad the PSPromotionManagers
+  // and make sure that the first instance starts at a cache line.
   assert(_manager_array == NULL, "Attempt to initialize twice");
-  _manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1, mtGC);
+  _manager_array = PaddedArray<PSPromotionManager, mtGC>::create_unfreeable(ParallelGCThreads + 1);
   guarantee(_manager_array != NULL, "Could not initialize promotion manager");
 
   _stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads);
@@ -54,26 +58,21 @@
 
   // Create and register the PSPromotionManager(s) for the worker threads.
   for(uint i=0; i<ParallelGCThreads; i++) {
-    _manager_array[i] = new PSPromotionManager();
-    guarantee(_manager_array[i] != NULL, "Could not create PSPromotionManager");
-    stack_array_depth()->register_queue(i, _manager_array[i]->claimed_stack_depth());
+    stack_array_depth()->register_queue(i, _manager_array[i].claimed_stack_depth());
   }
-
   // The VMThread gets its own PSPromotionManager, which is not available
   // for work stealing.
-  _manager_array[ParallelGCThreads] = new PSPromotionManager();
-  guarantee(_manager_array[ParallelGCThreads] != NULL, "Could not create PSPromotionManager");
 }
 
 PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(int index) {
   assert(index >= 0 && index < (int)ParallelGCThreads, "index out of range");
   assert(_manager_array != NULL, "Sanity");
-  return _manager_array[index];
+  return &_manager_array[index];
 }
 
 PSPromotionManager* PSPromotionManager::vm_thread_promotion_manager() {
   assert(_manager_array != NULL, "Sanity");
-  return _manager_array[ParallelGCThreads];
+  return &_manager_array[ParallelGCThreads];
 }
 
 void PSPromotionManager::pre_scavenge() {
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -29,6 +29,8 @@
 #include "gc_implementation/shared/gcTrace.hpp"
 #include "gc_implementation/shared/copyFailedInfo.hpp"
 #include "memory/allocation.hpp"
+#include "memory/padded.hpp"
+#include "utilities/globalDefinitions.hpp"
 #include "utilities/taskqueue.hpp"
 
 //
@@ -51,14 +53,14 @@
 class PSOldGen;
 class ParCompactionManager;
 
-class PSPromotionManager : public CHeapObj<mtGC> {
+class PSPromotionManager VALUE_OBJ_CLASS_SPEC {
   friend class PSScavenge;
   friend class PSRefProcTaskExecutor;
  private:
-  static PSPromotionManager**         _manager_array;
-  static OopStarTaskQueueSet*         _stack_array_depth;
-  static PSOldGen*                    _old_gen;
-  static MutableSpace*                _young_space;
+  static PaddedEnd<PSPromotionManager>* _manager_array;
+  static OopStarTaskQueueSet*           _stack_array_depth;
+  static PSOldGen*                      _old_gen;
+  static MutableSpace*                  _young_space;
 
 #if TASKQUEUE_STATS
   size_t                              _masked_pushes;
--- a/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -32,7 +32,7 @@
 inline PSPromotionManager* PSPromotionManager::manager_array(int index) {
   assert(_manager_array != NULL, "access of NULL manager_array");
   assert(index >= 0 && index <= (int)ParallelGCThreads, "out of range manager_array access");
-  return _manager_array[index];
+  return &_manager_array[index];
 }
 
 template <class T>
--- a/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -32,6 +32,7 @@
 #if INCLUDE_SERVICES
 
 void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp) {
+#if INCLUDE_TRACE
   assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId),
          "Only call this method if the event is enabled");
 
@@ -42,6 +43,7 @@
   event.set_totalSize(entry->words() * BytesPerWord);
   event.set_endtime(timestamp);
   event.commit();
+#endif // INCLUDE_TRACE
 }
 
 bool ObjectCountEventSender::should_send_event() {
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -727,7 +727,7 @@
 
   oop debug_info = CompilationResult_Call::debugInfo(site);
 
-  assert((hotspot_method ? 1 : 0) + (foreign_call ? 1 : 0) == 1, "Call site needs exactly one type");
+  assert(!!hotspot_method ^ !!foreign_call, "Call site needs exactly one type");
 
   NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset);
   jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method);
--- a/src/share/vm/graal/graalCompilerToGPU.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToGPU.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -96,7 +96,72 @@
   } else {
     oop o = java_lang_boxing_object::create(ptxka.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
     if (TraceGPUInteraction) {
-      tty->print_cr("GPU execution returned %d", result.get_jint());
+      switch (ptxka.get_ret_type()) {
+        case T_INT:
+          tty->print_cr("GPU execution returned %d", result.get_jint());
+          break;
+        case T_FLOAT:
+          tty->print_cr("GPU execution returned %f", result.get_jfloat());
+          break;
+        case T_DOUBLE:
+          tty->print_cr("GPU execution returned %f", result.get_jdouble());
+          break;
+        default:
+          tty->print_cr("GPU returned unhandled");
+          break;
+        }
+    }
+    return JNIHandles::make_local(o);
+  }
+
+C2V_END
+
+C2V_VMENTRY(jobject, executeParallelMethodVarargs, (JNIEnv *env,
+                                                          jobject,
+                                                          jint dimX, jint dimY, jint dimZ,
+                                                          jobject args, jobject hotspotInstalledCode))
+  ResourceMark rm;
+  HandleMark hm;
+
+  if (gpu::is_available() == false || gpu::has_gpu_linkage() == false && gpu::is_initialized()) {
+    tty->print_cr("executeParallelMethodVarargs - not available / no linkage / not initialized");
+    return NULL;
+  }
+  jlong nmethodValue = HotSpotInstalledCode::codeBlob(hotspotInstalledCode);
+  nmethod* nm = (nmethod*) (address) nmethodValue;
+  methodHandle mh = nm->method();
+  Symbol* signature = mh->signature();
+
+  // start value is the kernel
+  jlong startValue = HotSpotInstalledCode::codeStart(hotspotInstalledCode);
+
+  PTXKernelArguments ptxka(signature, (arrayOop) JNIHandles::resolve(args), mh->is_static());
+  JavaValue result(ptxka.get_ret_type());
+if (!gpu::execute_warp(dimX, dimY, dimZ, (address)startValue, ptxka, result)) {
+    return NULL;
+  }
+
+  if (ptxka.get_ret_type() == T_VOID) {
+    return NULL;
+  } else if (ptxka.get_ret_type() == T_OBJECT || ptxka.get_ret_type() == T_ARRAY) {
+    return JNIHandles::make_local((oop) result.get_jobject());
+  } else {
+    oop o = java_lang_boxing_object::create(ptxka.get_ret_type(), (jvalue *) result.get_value_addr(), CHECK_NULL);
+    if (TraceGPUInteraction) {
+      switch (ptxka.get_ret_type()) {
+        case T_INT:
+          tty->print_cr("GPU execution returned %d", result.get_jint());
+          break;
+        case T_FLOAT:
+          tty->print_cr("GPU execution returned %f", result.get_jfloat());
+          break;
+        case T_DOUBLE:
+          tty->print_cr("GPU execution returned %g", result.get_jdouble());
+          break;
+        default:
+          tty->print_cr("GPU returned unhandled");
+          break;
+      }
     }
     return JNIHandles::make_local(o);
   }
@@ -116,6 +181,14 @@
   return gpu::is_initialized();
 C2V_END
 
+C2V_VMENTRY(jint, availableProcessors, (JNIEnv *env, jobject))
+  if (gpu::is_available() == false || gpu::has_gpu_linkage() == false) {
+    tty->print_cr("deviceInit - not available / no linkage");
+    return false;
+  }
+  return gpu::available_processors();
+C2V_END
+
 C2V_VMENTRY(jboolean, deviceDetach, (JNIEnv *env, jobject))
 return true;
 C2V_END
@@ -157,10 +230,12 @@
 #define GPUSPACE_METHOD       "J"
 
 JNINativeMethod CompilerToGPU_methods[] = {
-  {CC"generateKernel",                CC"([B" STRING ")"GPUSPACE_METHOD,        FN_PTR(generateKernel)},
-  {CC"deviceInit",                    CC"()Z",                                  FN_PTR(deviceInit)},
-  {CC"deviceDetach",                  CC"()Z",                                  FN_PTR(deviceDetach)},
-  {CC"executeExternalMethodVarargs",  CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT,  FN_PTR(executeExternalMethodVarargs)},
+  {CC"generateKernel",                CC"([B" STRING ")"GPUSPACE_METHOD,          FN_PTR(generateKernel)},
+  {CC"deviceInit",                    CC"()Z",                                    FN_PTR(deviceInit)},
+  {CC"deviceDetach",                  CC"()Z",                                    FN_PTR(deviceDetach)},
+  {CC"availableProcessors",           CC"()I",                                    FN_PTR(availableProcessors)},
+  {CC"executeExternalMethodVarargs",  CC"(["OBJECT HS_INSTALLED_CODE")"OBJECT,    FN_PTR(executeExternalMethodVarargs)},
+  {CC"executeParallelMethodVarargs",  CC"(III["OBJECT HS_INSTALLED_CODE")"OBJECT, FN_PTR(executeParallelMethodVarargs)},
 };
 
 int CompilerToGPU_methods_count() {
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -875,6 +875,9 @@
 
   set_int("arrayClassElementOffset", in_bytes(ObjArrayKlass::element_klass_offset()));
 
+  set_int("graalCountersThreadOffset", in_bytes(JavaThread::graal_counters_offset()));
+  set_int("graalCountersSize", (jint) GRAAL_COUNTERS_SIZE);
+
 #undef set_boolean
 #undef set_int
 #undef set_long
@@ -1145,6 +1148,12 @@
   return klass;
 C2V_END
 
+C2V_VMENTRY(jlongArray, collectCounters, (JNIEnv *env, jobject))
+  typeArrayOop arrayOop = oopFactory::new_longArray(GRAAL_COUNTERS_SIZE, CHECK_NULL);
+  JavaThread::collect_counters(arrayOop);
+  return (jlongArray) JNIHandles::make_local(arrayOop);
+C2V_END
+
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
 
@@ -1224,6 +1233,7 @@
   {CC"invalidateInstalledCode",       CC"("HS_INSTALLED_CODE")V",                                       FN_PTR(invalidateInstalledCode)},
   {CC"readUnsafeUncompressedPointer", CC"("OBJECT"J)"OBJECT,                                            FN_PTR(readUnsafeUncompressedPointer)},
   {CC"readUnsafeKlassPointer",        CC"("OBJECT")J",                                                  FN_PTR(readUnsafeKlassPointer)},
+  {CC"collectCounters",               CC"()[J",                                                         FN_PTR(collectCounters)},
 };
 
 int CompilerToVM_methods_count() {
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1224,3 +1224,26 @@
                        size_of_arguments * Interpreter::stackElementSize);
 IRT_END
 #endif
+
+#if INCLUDE_JVMTI
+// This is a support of the JVMTI PopFrame interface.
+// Make sure it is an invokestatic of a polymorphic intrinsic that has a member_name argument
+// and return it as a vm_result so that it can be reloaded in the list of invokestatic parameters.
+// The dmh argument is a reference to a DirectMethoHandle that has a member name field.
+IRT_ENTRY(void, InterpreterRuntime::member_name_arg_or_null(JavaThread* thread, address dmh,
+                                                            Method* method, address bcp))
+  Bytecodes::Code code = Bytecodes::code_at(method, bcp);
+  if (code != Bytecodes::_invokestatic) {
+    return;
+  }
+  ConstantPool* cpool = method->constants();
+  int cp_index = Bytes::get_native_u2(bcp + 1) + ConstantPool::CPCACHE_INDEX_TAG;
+  Symbol* cname = cpool->klass_name_at(cpool->klass_ref_index_at(cp_index));
+  Symbol* mname = cpool->name_ref_at(cp_index);
+
+  if (MethodHandles::has_member_arg(cname, mname)) {
+    oop member_name = java_lang_invoke_DirectMethodHandle::member((oop)dmh);
+    thread->set_vm_result(member_name);
+  }
+IRT_END
+#endif // INCLUDE_JVMTI
--- a/src/share/vm/interpreter/interpreterRuntime.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/interpreter/interpreterRuntime.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -96,6 +96,9 @@
   static void    create_exception(JavaThread* thread, char* name, char* message);
   static void    create_klass_exception(JavaThread* thread, char* name, oopDesc* obj);
   static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception);
+#if INCLUDE_JVMTI
+  static void    member_name_arg_or_null(JavaThread* thread, address dmh, Method* m, address bcp);
+#endif
   static void    throw_pending_exception(JavaThread* thread);
 
   // Statics & fields
--- a/src/share/vm/memory/cardTableRS.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/cardTableRS.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -310,46 +310,31 @@
   _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, cl, this);
 }
 
-void CardTableRS::clear_into_younger(Generation* gen) {
-  GenCollectedHeap* gch = GenCollectedHeap::heap();
-  // Generations younger than gen have been evacuated. We can clear
-  // card table entries for gen (we know that it has no pointers
-  // to younger gens) and for those below. The card tables for
-  // the youngest gen need never be cleared.
+void CardTableRS::clear_into_younger(Generation* old_gen) {
+  assert(old_gen->level() == 1, "Should only be called for the old generation");
+  // The card tables for the youngest gen need never be cleared.
   // There's a bit of subtlety in the clear() and invalidate()
   // methods that we exploit here and in invalidate_or_clear()
   // below to avoid missing cards at the fringes. If clear() or
   // invalidate() are changed in the future, this code should
   // be revisited. 20040107.ysr
-  Generation* g = gen;
-  for(Generation* prev_gen = gch->prev_gen(g);
-      prev_gen != NULL;
-      g = prev_gen, prev_gen = gch->prev_gen(g)) {
-    MemRegion to_be_cleared_mr = g->prev_used_region();
-    clear(to_be_cleared_mr);
-  }
+  clear(old_gen->prev_used_region());
 }
 
-void CardTableRS::invalidate_or_clear(Generation* gen, bool younger) {
-  GenCollectedHeap* gch = GenCollectedHeap::heap();
-  // For each generation gen (and younger)
-  // invalidate the cards for the currently occupied part
-  // of that generation and clear the cards for the
+void CardTableRS::invalidate_or_clear(Generation* old_gen) {
+  assert(old_gen->level() == 1, "Should only be called for the old generation");
+  // Invalidate the cards for the currently occupied part of
+  // the old generation and clear the cards for the
   // unoccupied part of the generation (if any, making use
   // of that generation's prev_used_region to determine that
   // region). No need to do anything for the youngest
   // generation. Also see note#20040107.ysr above.
-  Generation* g = gen;
-  for(Generation* prev_gen = gch->prev_gen(g); prev_gen != NULL;
-      g = prev_gen, prev_gen = gch->prev_gen(g))  {
-    MemRegion used_mr = g->used_region();
-    MemRegion to_be_cleared_mr = g->prev_used_region().minus(used_mr);
-    if (!to_be_cleared_mr.is_empty()) {
-      clear(to_be_cleared_mr);
-    }
-    invalidate(used_mr);
-    if (!younger) break;
+  MemRegion used_mr = old_gen->used_region();
+  MemRegion to_be_cleared_mr = old_gen->prev_used_region().minus(used_mr);
+  if (!to_be_cleared_mr.is_empty()) {
+    clear(to_be_cleared_mr);
   }
+  invalidate(used_mr);
 }
 
 
--- a/src/share/vm/memory/cardTableRS.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/cardTableRS.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -142,12 +142,12 @@
   void verify_aligned_region_empty(MemRegion mr);
 
   void clear(MemRegion mr) { _ct_bs->clear(mr); }
-  void clear_into_younger(Generation* gen);
+  void clear_into_younger(Generation* old_gen);
 
   void invalidate(MemRegion mr, bool whole_heap = false) {
     _ct_bs->invalidate(mr, whole_heap);
   }
-  void invalidate_or_clear(Generation* gen, bool younger);
+  void invalidate_or_clear(Generation* old_gen);
 
   static uintx ct_max_alignment_constraint() {
     return CardTableModRefBS::ct_max_alignment_constraint();
--- a/src/share/vm/memory/defNewGeneration.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/defNewGeneration.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -567,8 +567,6 @@
   gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start());
 
   _next_gen = gch->next_gen(this);
-  assert(_next_gen != NULL,
-    "This must be the youngest gen, and not the only gen");
 
   // If the next generation is too full to accommodate promotion
   // from this generation, pass on collection; let the next generation
@@ -901,8 +899,6 @@
   if (_next_gen == NULL) {
     GenCollectedHeap* gch = GenCollectedHeap::heap();
     _next_gen = gch->next_gen(this);
-    assert(_next_gen != NULL,
-           "This must be the youngest gen, and not the only gen");
   }
   return _next_gen->promotion_attempt_is_safe(used());
 }
@@ -1033,6 +1029,9 @@
   // have to use it here, as well.
   HeapWord* result = eden()->par_allocate(word_size);
   if (result != NULL) {
+    if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
+      _next_gen->sample_eden_chunk();
+    }
     return result;
   }
   do {
@@ -1063,13 +1062,19 @@
   // circular dependency at compile time.
   if (result == NULL) {
     result = allocate_from_space(word_size);
+  } else if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
+    _next_gen->sample_eden_chunk();
   }
   return result;
 }
 
 HeapWord* DefNewGeneration::par_allocate(size_t word_size,
                                          bool is_tlab) {
-  return eden()->par_allocate(word_size);
+  HeapWord* res = eden()->par_allocate(word_size);
+  if (CMSEdenChunksRecordAlways && _next_gen != NULL) {
+    _next_gen->sample_eden_chunk();
+  }
+  return res;
 }
 
 void DefNewGeneration::gc_prologue(bool full) {
--- a/src/share/vm/memory/genCollectedHeap.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/genCollectedHeap.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1070,13 +1070,13 @@
 
 
 void GenCollectedHeap::prepare_for_compaction() {
-  Generation* scanning_gen = _gens[_n_gens-1];
+  guarantee(_n_gens = 2, "Wrong number of generations");
+  Generation* old_gen = _gens[1];
   // Start by compacting into same gen.
-  CompactPoint cp(scanning_gen, NULL, NULL);
-  while (scanning_gen != NULL) {
-    scanning_gen->prepare_for_compaction(&cp);
-    scanning_gen = prev_gen(scanning_gen);
-  }
+  CompactPoint cp(old_gen, NULL, NULL);
+  old_gen->prepare_for_compaction(&cp);
+  Generation* young_gen = _gens[0];
+  young_gen->prepare_for_compaction(&cp);
 }
 
 GCStats* GenCollectedHeap::gc_stats(int level) const {
@@ -1245,27 +1245,14 @@
   generation_iterate(&ep_cl, false);
 }
 
-oop GenCollectedHeap::handle_failed_promotion(Generation* gen,
+oop GenCollectedHeap::handle_failed_promotion(Generation* old_gen,
                                               oop obj,
                                               size_t obj_size) {
+  guarantee(old_gen->level() == 1, "We only get here with an old generation");
   assert(obj_size == (size_t)obj->size(), "bad obj_size passed in");
   HeapWord* result = NULL;
 
-  // First give each higher generation a chance to allocate the promoted object.
-  Generation* allocator = next_gen(gen);
-  if (allocator != NULL) {
-    do {
-      result = allocator->allocate(obj_size, false);
-    } while (result == NULL && (allocator = next_gen(allocator)) != NULL);
-  }
-
-  if (result == NULL) {
-    // Then give gen and higher generations a chance to expand and allocate the
-    // object.
-    do {
-      result = gen->expand_and_allocate(obj_size, false);
-    } while (result == NULL && (gen = next_gen(gen)) != NULL);
-  }
+  result = old_gen->expand_and_allocate(obj_size, false);
 
   if (result != NULL) {
     Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size);
--- a/src/share/vm/memory/genCollectedHeap.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/genCollectedHeap.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -368,25 +368,23 @@
   // collection.
   virtual bool is_maximal_no_gc() const;
 
-  // Return the generation before "gen", or else NULL.
+  // Return the generation before "gen".
   Generation* prev_gen(Generation* gen) const {
     int l = gen->level();
-    if (l == 0) return NULL;
-    else return _gens[l-1];
+    guarantee(l > 0, "Out of bounds");
+    return _gens[l-1];
   }
 
-  // Return the generation after "gen", or else NULL.
+  // Return the generation after "gen".
   Generation* next_gen(Generation* gen) const {
     int l = gen->level() + 1;
-    if (l == _n_gens) return NULL;
-    else return _gens[l];
+    guarantee(l < _n_gens, "Out of bounds");
+    return _gens[l];
   }
 
   Generation* get_gen(int i) const {
-    if (i >= 0 && i < _n_gens)
-      return _gens[i];
-    else
-      return NULL;
+    guarantee(i >= 0 && i < _n_gens, "Out of bounds");
+    return _gens[i];
   }
 
   int n_gens() const {
@@ -485,9 +483,9 @@
 
   // Promotion of obj into gen failed.  Try to promote obj to higher
   // gens in ascending order; return the new location of obj if successful.
-  // Otherwise, try expand-and-allocate for obj in each generation starting at
-  // gen; return the new location of obj if successful.  Otherwise, return NULL.
-  oop handle_failed_promotion(Generation* gen,
+  // Otherwise, try expand-and-allocate for obj in both the young and old
+  // generation; return the new location of obj if successful.  Otherwise, return NULL.
+  oop handle_failed_promotion(Generation* old_gen,
                               oop obj,
                               size_t obj_size);
 
--- a/src/share/vm/memory/genMarkSweep.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/genMarkSweep.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -52,8 +52,8 @@
 #include "utilities/copy.hpp"
 #include "utilities/events.hpp"
 
-void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp,
-  bool clear_all_softrefs) {
+void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool clear_all_softrefs) {
+  guarantee(level == 1, "We always collect both old and young.");
   assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
 
   GenCollectedHeap* gch = GenCollectedHeap::heap();
@@ -84,11 +84,6 @@
   // Capture heap size before collection for printing.
   size_t gch_prev_used = gch->used();
 
-  // Some of the card table updates below assume that the perm gen is
-  // also being collected.
-  assert(level == gch->n_gens() - 1,
-         "All generations are being collected, ergo perm gen too.");
-
   // Capture used regions for each generation that will be
   // subject to collection, so that card table adjustments can
   // be made intelligently (see clear / invalidate further below).
@@ -126,17 +121,15 @@
     all_empty = all_empty && gch->get_gen(i)->used() == 0;
   }
   GenRemSet* rs = gch->rem_set();
+  Generation* old_gen = gch->get_gen(level);
   // Clear/invalidate below make use of the "prev_used_regions" saved earlier.
   if (all_empty) {
     // We've evacuated all generations below us.
-    Generation* g = gch->get_gen(level);
-    rs->clear_into_younger(g);
+    rs->clear_into_younger(old_gen);
   } else {
     // Invalidate the cards corresponding to the currently used
-    // region and clear those corresponding to the evacuated region
-    // of all generations just collected (i.e. level and younger).
-    rs->invalidate_or_clear(gch->get_gen(level),
-                            true /* younger */);
+    // region and clear those corresponding to the evacuated region.
+    rs->invalidate_or_clear(old_gen);
   }
 
   Threads::gc_epilogue();
--- a/src/share/vm/memory/genRemSet.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/genRemSet.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -135,7 +135,7 @@
   // younger than gen from generations gen and older.
   // The parameter clear_perm indicates if the perm_gen's
   // remembered set should also be processed/cleared.
-  virtual void clear_into_younger(Generation* gen) = 0;
+  virtual void clear_into_younger(Generation* old_gen) = 0;
 
   // Informs the RS that refs in the given "mr" may have changed
   // arbitrarily, and therefore may contain old-to-young pointers.
@@ -146,11 +146,8 @@
 
   // Informs the RS that refs in this generation
   // may have changed arbitrarily, and therefore may contain
-  // old-to-young pointers in arbitrary locations. The parameter
-  // younger indicates if the same should be done for younger generations
-  // as well. The parameter perm indicates if the same should be done for
-  // perm gen as well.
-  virtual void invalidate_or_clear(Generation* gen, bool younger) = 0;
+  // old-to-young pointers in arbitrary locations.
+  virtual void invalidate_or_clear(Generation* old_gen) = 0;
 };
 
 #endif // SHARE_VM_MEMORY_GENREMSET_HPP
--- a/src/share/vm/memory/generation.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/generation.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -455,6 +455,7 @@
   // expected to be GC worker thread-local, with the worker index
   // indicated by "thr_num".
   virtual void* get_data_recorder(int thr_num) { return NULL; }
+  virtual void sample_eden_chunk() {}
 
   // Some generations may require some cleanup actions before allowing
   // a verification.
--- a/src/share/vm/memory/metaspace.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/metaspace.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -2254,10 +2254,11 @@
 
 void SpaceManager::deallocate(MetaWord* p, size_t word_size) {
   assert_lock_strong(_lock);
+  size_t raw_word_size = get_raw_word_size(word_size);
   size_t min_size = TreeChunk<Metablock, FreeList>::min_size();
-  assert(word_size >= min_size,
+  assert(raw_word_size >= min_size,
     err_msg("Should not deallocate dark matter " SIZE_FORMAT, word_size));
-  block_freelists()->return_block(p, word_size);
+  block_freelists()->return_block(p, raw_word_size);
 }
 
 // Adds a chunk to the list of chunks in use.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/memory/padded.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_PADDED_HPP
+#define SHARE_VM_MEMORY_PADDED_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// Bytes needed to pad type to avoid cache-line sharing; alignment should be the
+// expected cache line size (a power of two).  The first addend avoids sharing
+// when the start address is not a multiple of alignment; the second maintains
+// alignment of starting addresses that happen to be a multiple.
+#define PADDING_SIZE(type, alignment)                           \
+  ((alignment) + align_size_up_(sizeof(type), alignment))
+
+// Templates to create a subclass padded to avoid cache line sharing.  These are
+// effective only when applied to derived-most (leaf) classes.
+
+// When no args are passed to the base ctor.
+template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
+class Padded : public T {
+ private:
+  char _pad_buf_[PADDING_SIZE(T, alignment)];
+};
+
+// When either 0 or 1 args may be passed to the base ctor.
+template <class T, typename Arg1T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
+class Padded01 : public T {
+ public:
+  Padded01(): T() { }
+  Padded01(Arg1T arg1): T(arg1) { }
+ private:
+  char _pad_buf_[PADDING_SIZE(T, alignment)];
+};
+
+// Super class of PaddedEnd when pad_size != 0.
+template <class T, size_t pad_size>
+class PaddedEndImpl : public T {
+ private:
+  char _pad_buf[pad_size];
+};
+
+// Super class of PaddedEnd when pad_size == 0.
+template <class T>
+class PaddedEndImpl<T, /*pad_size*/ 0> : public T {
+  // No padding.
+};
+
+#define PADDED_END_SIZE(type, alignment) (align_size_up_(sizeof(type), alignment) - sizeof(type))
+
+// More memory conservative implementation of Padded. The subclass adds the
+// minimal amount of padding needed to make the size of the objects be aligned.
+// This will help reducing false sharing,
+// if the start address is a multiple of alignment.
+template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
+class PaddedEnd : public PaddedEndImpl<T, PADDED_END_SIZE(T, alignment)> {
+  // C++ don't allow zero-length arrays. The padding is put in a
+  // super class that is specialized for the pad_size == 0 case.
+};
+
+// Helper class to create an array of PaddedEnd<T> objects. All elements will
+// start at a multiple of alignment and the size will be aligned to alignment.
+template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
+class PaddedArray {
+ public:
+  // Creates an aligned padded array.
+  // The memory can't be deleted since the raw memory chunk is not returned.
+  static PaddedEnd<T>* create_unfreeable(uint length);
+};
+
+#endif // SHARE_VM_MEMORY_PADDED_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/vm/memory/padded.inline.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ *
+ */
+
+#include "memory/allocation.inline.hpp"
+#include "memory/padded.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// Creates an aligned padded array.
+// The memory can't be deleted since the raw memory chunk is not returned.
+template <class T, MEMFLAGS flags, size_t alignment>
+PaddedEnd<T>* PaddedArray<T, flags, alignment>::create_unfreeable(uint length) {
+  // Check that the PaddedEnd class works as intended.
+  STATIC_ASSERT(is_size_aligned_(sizeof(PaddedEnd<T>), alignment));
+
+  // Allocate a chunk of memory large enough to allow for some alignment.
+  void* chunk = AllocateHeap(length * sizeof(PaddedEnd<T, alignment>) + alignment, flags);
+
+  // Make the initial alignment.
+  PaddedEnd<T>* aligned_padded_array = (PaddedEnd<T>*)align_pointer_up(chunk, alignment);
+
+  // Call the default constructor for each element.
+  for (uint i = 0; i < length; i++) {
+    ::new (&aligned_padded_array[i]) T();
+  }
+
+  return aligned_padded_array;
+}
--- a/src/share/vm/memory/sharedHeap.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/sharedHeap.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -65,7 +65,8 @@
   }
   _sh = this;  // ch is static, should be set only once.
   if ((UseParNewGC ||
-      (UseConcMarkSweepGC && CMSParallelRemarkEnabled) ||
+      (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled ||
+                              CMSParallelRemarkEnabled)) ||
        UseG1GC) &&
       ParallelGCThreads > 0) {
     _workers = new FlexibleWorkGang("Parallel GC Threads", ParallelGCThreads,
--- a/src/share/vm/memory/universe.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/universe.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -105,10 +105,9 @@
 Array<Klass*>* Universe::_the_array_interfaces_array = NULL;
 oop Universe::_the_null_string                        = NULL;
 oop Universe::_the_min_jint_string                   = NULL;
-LatestMethodOopCache* Universe::_finalizer_register_cache = NULL;
-LatestMethodOopCache* Universe::_loader_addClass_cache    = NULL;
-LatestMethodOopCache* Universe::_pd_implies_cache         = NULL;
-ActiveMethodOopsCache* Universe::_reflect_invoke_cache    = NULL;
+LatestMethodCache* Universe::_finalizer_register_cache = NULL;
+LatestMethodCache* Universe::_loader_addClass_cache    = NULL;
+LatestMethodCache* Universe::_pd_implies_cache         = NULL;
 oop Universe::_out_of_memory_error_java_heap          = NULL;
 oop Universe::_out_of_memory_error_metaspace          = NULL;
 oop Universe::_out_of_memory_error_class_metaspace    = NULL;
@@ -225,7 +224,6 @@
   f->do_ptr((void**)&_the_empty_klass_array);
   _finalizer_register_cache->serialize(f);
   _loader_addClass_cache->serialize(f);
-  _reflect_invoke_cache->serialize(f);
   _pd_implies_cache->serialize(f);
 }
 
@@ -649,10 +647,9 @@
 
   // We have a heap so create the Method* caches before
   // Metaspace::initialize_shared_spaces() tries to populate them.
-  Universe::_finalizer_register_cache = new LatestMethodOopCache();
-  Universe::_loader_addClass_cache    = new LatestMethodOopCache();
-  Universe::_pd_implies_cache         = new LatestMethodOopCache();
-  Universe::_reflect_invoke_cache     = new ActiveMethodOopsCache();
+  Universe::_finalizer_register_cache = new LatestMethodCache();
+  Universe::_loader_addClass_cache    = new LatestMethodCache();
+  Universe::_pd_implies_cache         = new LatestMethodCache();
 
   if (UseSharedSpaces) {
     // Read the data structures supporting the shared spaces (shared
@@ -1088,35 +1085,21 @@
                                   vmSymbols::register_method_name(),
                                   vmSymbols::register_method_signature());
   if (m == NULL || !m->is_static()) {
-    THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(),
-      "java.lang.ref.Finalizer.register", false);
+    tty->print_cr("Unable to link/verify Finalizer.register method");
+    return false; // initialization failed (cannot throw exception yet)
   }
   Universe::_finalizer_register_cache->init(
-    SystemDictionary::Finalizer_klass(), m, CHECK_false);
-
-  // Resolve on first use and initialize class.
-  // Note: No race-condition here, since a resolve will always return the same result
-
-  // Setup method for security checks
-  k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_reflect_Method(), true, CHECK_false);
-  k_h = instanceKlassHandle(THREAD, k);
-  k_h->link_class(CHECK_false);
-  m = k_h->find_method(vmSymbols::invoke_name(), vmSymbols::object_object_array_object_signature());
-  if (m == NULL || m->is_static()) {
-    THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(),
-      "java.lang.reflect.Method.invoke", false);
-  }
-  Universe::_reflect_invoke_cache->init(k_h(), m, CHECK_false);
+    SystemDictionary::Finalizer_klass(), m);
 
   // Setup method for registering loaded classes in class loader vector
   InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false);
   m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature());
   if (m == NULL || m->is_static()) {
-    THROW_MSG_(vmSymbols::java_lang_NoSuchMethodException(),
-      "java.lang.ClassLoader.addClass", false);
+    tty->print_cr("Unable to link/verify ClassLoader.addClass method");
+    return false; // initialization failed (cannot throw exception yet)
   }
   Universe::_loader_addClass_cache->init(
-    SystemDictionary::ClassLoader_klass(), m, CHECK_false);
+    SystemDictionary::ClassLoader_klass(), m);
 
   // Setup method for checking protection domain
   InstanceKlass::cast(SystemDictionary::ProtectionDomain_klass())->link_class(CHECK_false);
@@ -1132,7 +1115,7 @@
       return false; // initialization failed
     }
     Universe::_pd_implies_cache->init(
-      SystemDictionary::ProtectionDomain_klass(), m, CHECK_false);;
+      SystemDictionary::ProtectionDomain_klass(), m);;
   }
 
   // The folowing is initializing converter functions for serialization in
@@ -1455,7 +1438,7 @@
 }
 
 
-void CommonMethodOopCache::init(Klass* k, Method* m, TRAPS) {
+void LatestMethodCache::init(Klass* k, Method* m) {
   if (!UseSharedSpaces) {
     _klass = k;
   }
@@ -1471,88 +1454,7 @@
 }
 
 
-ActiveMethodOopsCache::~ActiveMethodOopsCache() {
-  if (_prev_methods != NULL) {
-    delete _prev_methods;
-    _prev_methods = NULL;
-  }
-}
-
-
-void ActiveMethodOopsCache::add_previous_version(Method* method) {
-  assert(Thread::current()->is_VM_thread(),
-    "only VMThread can add previous versions");
-
-  // Only append the previous method if it is executing on the stack.
-  if (method->on_stack()) {
-
-    if (_prev_methods == NULL) {
-      // This is the first previous version so make some space.
-      // Start with 2 elements under the assumption that the class
-      // won't be redefined much.
-      _prev_methods = new (ResourceObj::C_HEAP, mtClass) GrowableArray<Method*>(2, true);
-    }
-
-    // RC_TRACE macro has an embedded ResourceMark
-    RC_TRACE(0x00000100,
-      ("add: %s(%s): adding prev version ref for cached method @%d",
-        method->name()->as_C_string(), method->signature()->as_C_string(),
-        _prev_methods->length()));
-
-    _prev_methods->append(method);
-  }
-
-
-  // Since the caller is the VMThread and we are at a safepoint, this is a good
-  // time to clear out unused method references.
-
-  if (_prev_methods == NULL) return;
-
-  for (int i = _prev_methods->length() - 1; i >= 0; i--) {
-    Method* method = _prev_methods->at(i);
-    assert(method != NULL, "weak method ref was unexpectedly cleared");
-
-    if (!method->on_stack()) {
-      // This method isn't running anymore so remove it
-      _prev_methods->remove_at(i);
-      MetadataFactory::free_metadata(method->method_holder()->class_loader_data(), method);
-    } else {
-      // RC_TRACE macro has an embedded ResourceMark
-      RC_TRACE(0x00000400,
-        ("add: %s(%s): previous cached method @%d is alive",
-         method->name()->as_C_string(), method->signature()->as_C_string(), i));
-    }
-  }
-} // end add_previous_version()
-
-
-bool ActiveMethodOopsCache::is_same_method(const Method* method) const {
-  InstanceKlass* ik = InstanceKlass::cast(klass());
-  const Method* check_method = ik->method_with_idnum(method_idnum());
-  assert(check_method != NULL, "sanity check");
-  if (check_method == method) {
-    // done with the easy case
-    return true;
-  }
-
-  if (_prev_methods != NULL) {
-    // The cached method has been redefined at least once so search
-    // the previous versions for a match.
-    for (int i = 0; i < _prev_methods->length(); i++) {
-      check_method = _prev_methods->at(i);
-      if (check_method == method) {
-        // a previous version matches
-        return true;
-      }
-    }
-  }
-
-  // either no previous versions or no previous version matched
-  return false;
-}
-
-
-Method* LatestMethodOopCache::get_Method() {
+Method* LatestMethodCache::get_method() {
   if (klass() == NULL) return NULL;
   InstanceKlass* ik = InstanceKlass::cast(klass());
   Method* m = ik->method_with_idnum(method_idnum());
--- a/src/share/vm/memory/universe.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/memory/universe.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -41,10 +41,11 @@
 class DeferredObjAllocEvent;
 
 
-// Common parts of a Method* cache. This cache safely interacts with
-// the RedefineClasses API.
-//
-class CommonMethodOopCache : public CHeapObj<mtClass> {
+// A helper class for caching a Method* when the user of the cache
+// only cares about the latest version of the Method*.  This cache safely
+// interacts with the RedefineClasses API.
+
+class LatestMethodCache : public CHeapObj<mtClass> {
   // We save the Klass* and the idnum of Method* in order to get
   // the current cached Method*.
  private:
@@ -52,12 +53,14 @@
   int                   _method_idnum;
 
  public:
-  CommonMethodOopCache()   { _klass = NULL; _method_idnum = -1; }
-  ~CommonMethodOopCache()  { _klass = NULL; _method_idnum = -1; }
+  LatestMethodCache()   { _klass = NULL; _method_idnum = -1; }
+  ~LatestMethodCache()  { _klass = NULL; _method_idnum = -1; }
 
-  void     init(Klass* k, Method* m, TRAPS);
-  Klass* klass() const         { return _klass; }
-  int      method_idnum() const  { return _method_idnum; }
+  void   init(Klass* k, Method* m);
+  Klass* klass() const           { return _klass; }
+  int    method_idnum() const    { return _method_idnum; }
+
+  Method* get_method();
 
   // Enhanced Class Redefinition support
   void classes_do(void f(Klass*)) {
@@ -72,39 +75,6 @@
 };
 
 
-// A helper class for caching a Method* when the user of the cache
-// cares about all versions of the Method*.
-//
-class ActiveMethodOopsCache : public CommonMethodOopCache {
-  // This subclass adds weak references to older versions of the
-  // Method* and a query method for a Method*.
-
- private:
-  // If the cached Method* has not been redefined, then
-  // _prev_methods will be NULL. If all of the previous
-  // versions of the method have been collected, then
-  // _prev_methods can have a length of zero.
-  GrowableArray<Method*>* _prev_methods;
-
- public:
-  ActiveMethodOopsCache()   { _prev_methods = NULL; }
-  ~ActiveMethodOopsCache();
-
-  void add_previous_version(Method* method);
-  bool is_same_method(const Method* method) const;
-};
-
-
-// A helper class for caching a Method* when the user of the cache
-// only cares about the latest version of the Method*.
-//
-class LatestMethodOopCache : public CommonMethodOopCache {
-  // This subclass adds a getter method for the latest Method*.
-
- public:
-  Method* get_Method();
-};
-
 // For UseCompressedOops and UseCompressedKlassPointers.
 struct NarrowPtrStruct {
   // Base address for oop/klass-within-java-object materialization.
@@ -174,10 +144,10 @@
   static objArrayOop  _the_empty_class_klass_array;   // Canonicalized obj array of type java.lang.Class
   static oop          _the_null_string;               // A cache of "null" as a Java string
   static oop          _the_min_jint_string;          // A cache of "-2147483648" as a Java string
-  static LatestMethodOopCache* _finalizer_register_cache; // static method for registering finalizable objects
-  static LatestMethodOopCache* _loader_addClass_cache;    // method for registering loaded classes in class loader vector
-  static LatestMethodOopCache* _pd_implies_cache;         // method for checking protection domain attributes
-  static ActiveMethodOopsCache* _reflect_invoke_cache;    // method for security checks
+  static LatestMethodCache* _finalizer_register_cache; // static method for registering finalizable objects
+  static LatestMethodCache* _loader_addClass_cache;    // method for registering loaded classes in class loader vector
+  static LatestMethodCache* _pd_implies_cache;         // method for checking protection domain attributes
+
   // preallocated error objects (no backtrace)
   static oop          _out_of_memory_error_java_heap;
   static oop          _out_of_memory_error_metaspace;
@@ -334,11 +304,11 @@
   static Array<Klass*>* the_array_interfaces_array() { return _the_array_interfaces_array;   }
   static oop          the_null_string()               { return _the_null_string;               }
   static oop          the_min_jint_string()          { return _the_min_jint_string;          }
-  static Method*      finalizer_register_method()     { return _finalizer_register_cache->get_Method(); }
-  static Method*      loader_addClass_method()        { return _loader_addClass_cache->get_Method(); }
 
-  static Method*      protection_domain_implies_method() { return _pd_implies_cache->get_Method(); }
-  static ActiveMethodOopsCache* reflect_invoke_cache() { return _reflect_invoke_cache; }
+  static Method*      finalizer_register_method()     { return _finalizer_register_cache->get_method(); }
+  static Method*      loader_addClass_method()        { return _loader_addClass_cache->get_method(); }
+
+  static Method*      protection_domain_implies_method() { return _pd_implies_cache->get_method(); }
 
   static oop          null_ptr_exception_instance()   { return _null_ptr_exception_instance;   }
   static oop          arithmetic_exception_instance() { return _arithmetic_exception_instance; }
--- a/src/share/vm/oops/method.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/oops/method.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -989,7 +989,6 @@
 bool Method::is_ignored_by_security_stack_walk() const {
   const bool use_new_reflection = JDK_Version::is_gte_jdk14x_version() && UseNewReflection;
 
-  assert(intrinsic_id() != vmIntrinsics::_invoke || Universe::reflect_invoke_cache()->is_same_method((Method*)this), "sanity");
   if (intrinsic_id() == vmIntrinsics::_invoke) {
     // This is Method.invoke() -- ignore it
     return true;
--- a/src/share/vm/opto/block.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/block.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -221,7 +221,7 @@
 //------------------------------is_uncommon------------------------------------
 // True if block is low enough frequency or guarded by a test which
 // mostly does not go here.
-bool Block::is_uncommon( Block_Array &bbs ) const {
+bool Block::is_uncommon(PhaseCFG* cfg) const {
   // Initial blocks must never be moved, so are never uncommon.
   if (head()->is_Root() || head()->is_Start())  return false;
 
@@ -238,7 +238,7 @@
   uint uncommon_for_freq_preds = 0;
 
   for( uint i=1; i<num_preds(); i++ ) {
-    Block* guard = bbs[pred(i)->_idx];
+    Block* guard = cfg->get_block_for_node(pred(i));
     // Check to see if this block follows its guard 1 time out of 10000
     // or less.
     //
@@ -285,11 +285,11 @@
   }
 }
 
-void Block::dump_pred(const Block_Array *bbs, Block* orig, outputStream* st) const {
+void Block::dump_pred(const PhaseCFG* cfg, Block* orig, outputStream* st) const {
   if (is_connector()) {
     for (uint i=1; i<num_preds(); i++) {
-      Block *p = ((*bbs)[pred(i)->_idx]);
-      p->dump_pred(bbs, orig, st);
+      Block *p = cfg->get_block_for_node(pred(i));
+      p->dump_pred(cfg, orig, st);
     }
   } else {
     dump_bidx(orig, st);
@@ -297,7 +297,7 @@
   }
 }
 
-void Block::dump_head( const Block_Array *bbs, outputStream* st ) const {
+void Block::dump_head(const PhaseCFG* cfg, outputStream* st) const {
   // Print the basic block
   dump_bidx(this, st);
   st->print(": #\t");
@@ -311,26 +311,28 @@
   if( head()->is_block_start() ) {
     for (uint i=1; i<num_preds(); i++) {
       Node *s = pred(i);
-      if (bbs) {
-        Block *p = (*bbs)[s->_idx];
-        p->dump_pred(bbs, p, st);
+      if (cfg != NULL) {
+        Block *p = cfg->get_block_for_node(s);
+        p->dump_pred(cfg, p, st);
       } else {
         while (!s->is_block_start())
           s = s->in(0);
         st->print("N%d ", s->_idx );
       }
     }
-  } else
+  } else {
     st->print("BLOCK HEAD IS JUNK  ");
+  }
 
   // Print loop, if any
   const Block *bhead = this;    // Head of self-loop
   Node *bh = bhead->head();
-  if( bbs && bh->is_Loop() && !head()->is_Root() ) {
+
+  if ((cfg != NULL) && bh->is_Loop() && !head()->is_Root()) {
     LoopNode *loop = bh->as_Loop();
-    const Block *bx = (*bbs)[loop->in(LoopNode::LoopBackControl)->_idx];
+    const Block *bx = cfg->get_block_for_node(loop->in(LoopNode::LoopBackControl));
     while (bx->is_connector()) {
-      bx = (*bbs)[bx->pred(1)->_idx];
+      bx = cfg->get_block_for_node(bx->pred(1));
     }
     st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order);
     // Dump any loop-specific bits, especially for CountedLoops.
@@ -349,29 +351,32 @@
   st->print_cr("");
 }
 
-void Block::dump() const { dump(NULL); }
+void Block::dump() const {
+  dump(NULL);
+}
 
-void Block::dump( const Block_Array *bbs ) const {
-  dump_head(bbs);
-  uint cnt = _nodes.size();
-  for( uint i=0; i<cnt; i++ )
+void Block::dump(const PhaseCFG* cfg) const {
+  dump_head(cfg);
+  for (uint i=0; i< _nodes.size(); i++) {
     _nodes[i]->dump();
+  }
   tty->print("\n");
 }
 #endif
 
 //=============================================================================
 //------------------------------PhaseCFG---------------------------------------
-PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) :
-  Phase(CFG),
-  _bbs(a),
-  _root(r),
-  _node_latency(NULL)
+PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher)
+: Phase(CFG)
+, _block_arena(arena)
+, _node_to_block_mapping(arena)
+, _root(root)
+, _node_latency(NULL)
 #ifndef PRODUCT
-  , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining"))
+, _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining"))
 #endif
 #ifdef ASSERT
-  , _raw_oops(a)
+, _raw_oops(arena)
 #endif
 {
   ResourceMark rm;
@@ -380,13 +385,13 @@
   // Node on demand.
   Node *x = new (C) GotoNode(NULL);
   x->init_req(0, x);
-  _goto = m.match_tree(x);
+  _goto = matcher.match_tree(x);
   assert(_goto != NULL, "");
   _goto->set_req(0,_goto);
 
   // Build the CFG in Reverse Post Order
   _num_blocks = build_cfg();
-  _broot = _bbs[_root->_idx];
+  _broot = get_block_for_node(_root);
 }
 
 //------------------------------build_cfg--------------------------------------
@@ -440,9 +445,9 @@
       // 'p' now points to the start of this basic block
 
       // Put self in array of basic blocks
-      Block *bb = new (_bbs._arena) Block(_bbs._arena,p);
-      _bbs.map(p->_idx,bb);
-      _bbs.map(x->_idx,bb);
+      Block *bb = new (_block_arena) Block(_block_arena, p);
+      map_node_to_block(p, bb);
+      map_node_to_block(x, bb);
       if( x != p ) {                // Only for root is x == p
         bb->_nodes.push((Node*)x);
       }
@@ -473,16 +478,16 @@
       // Check if it the fist node pushed on stack at the beginning.
       if (idx == 0) break;          // end of the build
       // Find predecessor basic block
-      Block *pb = _bbs[x->_idx];
+      Block *pb = get_block_for_node(x);
       // Insert into nodes array, if not already there
-      if( !_bbs.lookup(proj->_idx) ) {
+      if (!has_block(proj)) {
         assert( x != proj, "" );
         // Map basic block of projection
-        _bbs.map(proj->_idx,pb);
+        map_node_to_block(proj, pb);
         pb->_nodes.push(proj);
       }
       // Insert self as a child of my predecessor block
-      pb->_succs.map(pb->_num_succs++, _bbs[np->_idx]);
+      pb->_succs.map(pb->_num_succs++, get_block_for_node(np));
       assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(),
               "too many control users, not a CFG?" );
     }
@@ -511,15 +516,15 @@
   RegionNode* region = new (C) RegionNode(2);
   region->init_req(1, proj);
   // setup corresponding basic block
-  Block* block = new (_bbs._arena) Block(_bbs._arena, region);
-  _bbs.map(region->_idx, block);
+  Block* block = new (_block_arena) Block(_block_arena, region);
+  map_node_to_block(region, block);
   C->regalloc()->set_bad(region->_idx);
   // add a goto node
   Node* gto = _goto->clone(); // get a new goto node
   gto->set_req(0, region);
   // add it to the basic block
   block->_nodes.push(gto);
-  _bbs.map(gto->_idx, block);
+  map_node_to_block(gto, block);
   C->regalloc()->set_bad(gto->_idx);
   // hook up successor block
   block->_succs.map(block->_num_succs++, out);
@@ -570,7 +575,7 @@
   gto->set_req(0, b->head());
   Node *bp = b->_nodes[end_idx];
   b->_nodes.map(end_idx,gto); // Slam over NeverBranch
-  _bbs.map(gto->_idx, b);
+  map_node_to_block(gto, b);
   C->regalloc()->set_bad(gto->_idx);
   b->_nodes.pop();              // Yank projections
   b->_nodes.pop();              // Yank projections
@@ -613,7 +618,7 @@
   // If the previous block conditionally falls into bx, return false,
   // because moving bx will create an extra jump.
   for(uint k = 1; k < bx->num_preds(); k++ ) {
-    Block* pred = _bbs[bx->pred(k)->_idx];
+    Block* pred = get_block_for_node(bx->pred(k));
     if (pred == _blocks[bx_index-1]) {
       if (pred->_num_succs != 1) {
         return false;
@@ -682,7 +687,7 @@
 
     // Look for uncommon blocks and move to end.
     if (!C->do_freq_based_layout()) {
-      if( b->is_uncommon(_bbs) ) {
+      if (b->is_uncommon(this)) {
         move_to_end(b, i);
         last--;                   // No longer check for being uncommon!
         if( no_flip_branch(b) ) { // Fall-thru case must follow?
@@ -870,28 +875,31 @@
   } while( !p->is_block_start() );
 
   // Recursively visit
-  for( uint i=1; i<p->req(); i++ )
-    _dump_cfg(p->in(i),visited);
+  for (uint i = 1; i < p->req(); i++) {
+    _dump_cfg(p->in(i), visited);
+  }
 
   // Dump the block
-  _bbs[p->_idx]->dump(&_bbs);
+  get_block_for_node(p)->dump(this);
 }
 
 void PhaseCFG::dump( ) const {
   tty->print("\n--- CFG --- %d BBs\n",_num_blocks);
-  if( _blocks.size() ) {        // Did we do basic-block layout?
-    for( uint i=0; i<_num_blocks; i++ )
-      _blocks[i]->dump(&_bbs);
+  if (_blocks.size()) {        // Did we do basic-block layout?
+    for (uint i = 0; i < _num_blocks; i++) {
+      _blocks[i]->dump(this);
+    }
   } else {                      // Else do it with a DFS
-    VectorSet visited(_bbs._arena);
+    VectorSet visited(_block_arena);
     _dump_cfg(_root,visited);
   }
 }
 
 void PhaseCFG::dump_headers() {
   for( uint i = 0; i < _num_blocks; i++ ) {
-    if( _blocks[i] == NULL ) continue;
-    _blocks[i]->dump_head(&_bbs);
+    if (_blocks[i]) {
+      _blocks[i]->dump_head(this);
+    }
   }
 }
 
@@ -904,7 +912,7 @@
     uint j;
     for (j = 0; j < cnt; j++)  {
       Node *n = b->_nodes[j];
-      assert( _bbs[n->_idx] == b, "" );
+      assert(get_block_for_node(n) == b, "");
       if (j >= 1 && n->is_Mach() &&
           n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
         assert(j == 1 || b->_nodes[j-1]->is_Phi(),
@@ -913,13 +921,12 @@
       for (uint k = 0; k < n->req(); k++) {
         Node *def = n->in(k);
         if (def && def != n) {
-          assert(_bbs[def->_idx] || def->is_Con(),
-                 "must have block; constants for debug info ok");
+          assert(get_block_for_node(def) || def->is_Con(), "must have block; constants for debug info ok");
           // Verify that instructions in the block is in correct order.
           // Uses must follow their definition if they are at the same block.
           // Mostly done to check that MachSpillCopy nodes are placed correctly
           // when CreateEx node is moved in build_ifg_physical().
-          if (_bbs[def->_idx] == b &&
+          if (get_block_for_node(def) == b &&
               !(b->head()->is_Loop() && n->is_Phi()) &&
               // See (+++) comment in reg_split.cpp
               !(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) {
--- a/src/share/vm/opto/block.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/block.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -48,13 +48,12 @@
   friend class VMStructs;
   uint _size;                   // allocated size, as opposed to formal limit
   debug_only(uint _limit;)      // limit to formal domain
+  Arena *_arena;                // Arena to allocate in
 protected:
   Block **_blocks;
   void grow( uint i );          // Grow array node to fit
 
 public:
-  Arena *_arena;                // Arena to allocate in
-
   Block_Array(Arena *a) : _arena(a), _size(OptoBlockListSize) {
     debug_only(_limit=0);
     _blocks = NEW_ARENA_ARRAY( a, Block *, OptoBlockListSize );
@@ -77,7 +76,7 @@
 public:
   uint _cnt;
   Block_List() : Block_Array(Thread::current()->resource_area()), _cnt(0) {}
-  void push( Block *b ) { map(_cnt++,b); }
+  void push( Block *b ) {  map(_cnt++,b); }
   Block *pop() { return _blocks[--_cnt]; }
   Block *rpop() { Block *b = _blocks[0]; _blocks[0]=_blocks[--_cnt]; return b;}
   void remove( uint i );
@@ -284,15 +283,15 @@
   // helper function that adds caller save registers to MachProjNode
   void add_call_kills(MachProjNode *proj, RegMask& regs, const char* save_policy, bool exclude_soe);
   // Schedule a call next in the block
-  uint sched_call(Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call);
+  uint sched_call(Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call);
 
   // Perform basic-block local scheduling
   Node *select(PhaseCFG *cfg, Node_List &worklist, GrowableArray<int> &ready_cnt, VectorSet &next_call, uint sched_slot);
-  void set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs );
-  void needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs);
+  void set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg);
+  void needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg);
   bool schedule_local(PhaseCFG *cfg, Matcher &m, GrowableArray<int> &ready_cnt, VectorSet &next_call);
   // Cleanup if any code lands between a Call and his Catch
-  void call_catch_cleanup(Block_Array &bbs, Compile *C);
+  void call_catch_cleanup(PhaseCFG* cfg, Compile *C);
   // Detect implicit-null-check opportunities.  Basically, find NULL checks
   // with suitable memory ops nearby.  Use the memory op to do the NULL check.
   // I can generate a memory op if there is not one nearby.
@@ -331,15 +330,15 @@
 
   // Use frequency calculations and code shape to predict if the block
   // is uncommon.
-  bool is_uncommon( Block_Array &bbs ) const;
+  bool is_uncommon(PhaseCFG* cfg) const;
 
 #ifndef PRODUCT
   // Debugging print of basic block
   void dump_bidx(const Block* orig, outputStream* st = tty) const;
-  void dump_pred(const Block_Array *bbs, Block* orig, outputStream* st = tty) const;
-  void dump_head( const Block_Array *bbs, outputStream* st = tty ) const;
+  void dump_pred(const PhaseCFG* cfg, Block* orig, outputStream* st = tty) const;
+  void dump_head(const PhaseCFG* cfg, outputStream* st = tty) const;
   void dump() const;
-  void dump( const Block_Array *bbs ) const;
+  void dump(const PhaseCFG* cfg) const;
 #endif
 };
 
@@ -349,6 +348,12 @@
 class PhaseCFG : public Phase {
   friend class VMStructs;
  private:
+  // Arena for the blocks to be stored in
+  Arena* _block_arena;
+
+  // Map nodes to owning basic block
+  Block_Array _node_to_block_mapping;
+
   // Build a proper looking cfg.  Return count of basic blocks
   uint build_cfg();
 
@@ -371,22 +376,42 @@
 
   Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
   void verify_anti_dependences(Block* LCA, Node* load) {
-    assert(LCA == _bbs[load->_idx], "should already be scheduled");
+    assert(LCA == get_block_for_node(load), "should already be scheduled");
     insert_anti_dependences(LCA, load, true);
   }
 
  public:
-  PhaseCFG( Arena *a, RootNode *r, Matcher &m );
+  PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher);
 
   uint _num_blocks;             // Count of basic blocks
   Block_List _blocks;           // List of basic blocks
   RootNode *_root;              // Root of whole program
-  Block_Array _bbs;             // Map Nodes to owning Basic Block
   Block *_broot;                // Basic block of root
   uint _rpo_ctr;
   CFGLoop* _root_loop;
   float _outer_loop_freq;       // Outmost loop frequency
 
+
+  // set which block this node should reside in
+  void map_node_to_block(const Node* node, Block* block) {
+    _node_to_block_mapping.map(node->_idx, block);
+  }
+
+  // removes the mapping from a node to a block
+  void unmap_node_from_block(const Node* node) {
+    _node_to_block_mapping.map(node->_idx, NULL);
+  }
+
+  // get the block in which this node resides
+  Block* get_block_for_node(const Node* node) const {
+    return _node_to_block_mapping[node->_idx];
+  }
+
+  // does this node reside in a block; return true
+  bool has_block(const Node* node) const {
+    return (_node_to_block_mapping.lookup(node->_idx) != NULL);
+  }
+
   // Per node latency estimation, valid only during GCM
   GrowableArray<uint> *_node_latency;
 
@@ -405,7 +430,7 @@
   void Estimate_Block_Frequency();
 
   // Global Code Motion.  See Click's PLDI95 paper.  Place Nodes in specific
-  // basic blocks; i.e. _bbs now maps _idx for all Nodes to some Block.
+  // basic blocks; i.e. _node_to_block_mapping now maps _idx for all Nodes to some Block.
   void GlobalCodeMotion( Matcher &m, uint unique, Node_List &proj_list );
 
   // Compute the (backwards) latency of a node from the uses
@@ -454,7 +479,7 @@
   // Insert a node into a block, and update the _bbs
   void insert( Block *b, uint idx, Node *n ) {
     b->_nodes.insert( idx, n );
-    _bbs.map( n->_idx, b );
+    map_node_to_block(n, b);
   }
 
 #ifndef PRODUCT
@@ -543,7 +568,7 @@
     _child(NULL),
     _exit_prob(1.0f) {}
   CFGLoop* parent() { return _parent; }
-  void push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk);
+  void push_pred(Block* blk, int i, Block_List& worklist, PhaseCFG* cfg);
   void add_member(CFGElement *s) { _members.push(s); }
   void add_nested_loop(CFGLoop* cl);
   Block* head() {
--- a/src/share/vm/opto/buildOopMap.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/buildOopMap.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -426,14 +426,16 @@
   }
   memset( live, 0, cfg->_num_blocks * (max_reg_ints<<LogBytesPerInt) );
   // Push preds onto worklist
-  for( uint i=1; i<root->req(); i++ )
-    worklist->push(cfg->_bbs[root->in(i)->_idx]);
+  for (uint i = 1; i < root->req(); i++) {
+    Block* block = cfg->get_block_for_node(root->in(i));
+    worklist->push(block);
+  }
 
   // ZKM.jar includes tiny infinite loops which are unreached from below.
   // If we missed any blocks, we'll retry here after pushing all missed
   // blocks on the worklist.  Normally this outer loop never trips more
   // than once.
-  while( 1 ) {
+  while (1) {
 
     while( worklist->size() ) { // Standard worklist algorithm
       Block *b = worklist->rpop();
@@ -537,8 +539,10 @@
         for( l=0; l<max_reg_ints; l++ )
           old_live[l] = tmp_live[l];
         // Push preds onto worklist
-        for( l=1; l<(int)b->num_preds(); l++ )
-          worklist->push(cfg->_bbs[b->pred(l)->_idx]);
+        for (l = 1; l < (int)b->num_preds(); l++) {
+          Block* block = cfg->get_block_for_node(b->pred(l));
+          worklist->push(block);
+        }
       }
     }
 
@@ -629,10 +633,9 @@
     // pred to this block.  Otherwise we have to grab a new OopFlow.
     OopFlow *flow = NULL;       // Flag for finding optimized flow
     Block *pred = (Block*)0xdeadbeef;
-    uint j;
     // Scan this block's preds to find a done predecessor
-    for( j=1; j<b->num_preds(); j++ ) {
-      Block *p = _cfg->_bbs[b->pred(j)->_idx];
+    for (uint j = 1; j < b->num_preds(); j++) {
+      Block* p = _cfg->get_block_for_node(b->pred(j));
       OopFlow *p_flow = flows[p->_pre_order];
       if( p_flow ) {            // Predecessor is done
         assert( p_flow->_b == p, "cross check" );
--- a/src/share/vm/opto/c2_globals.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/c2_globals.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -179,6 +179,9 @@
   product_pd(intx,  LoopUnrollLimit,                                        \
           "Unroll loop bodies with node count less than this")              \
                                                                             \
+  product(intx,  LoopMaxUnroll, 16,                                         \
+          "Maximum number of unrolls for main loop")                        \
+                                                                            \
   product(intx,  LoopUnrollMin, 4,                                          \
           "Minimum number of unroll loop bodies before checking progress"   \
           "of rounds of unroll,optimize,..")                                \
--- a/src/share/vm/opto/chaitin.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/chaitin.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -295,7 +295,7 @@
 
 
 bool PhaseChaitin::clone_projs_shared(Block *b, uint idx, Node *con, Node *copy, uint max_lrg_id) {
-  Block *bcon = _cfg._bbs[con->_idx];
+  Block* bcon = _cfg.get_block_for_node(con);
   uint cindex = bcon->find_node(con);
   Node *con_next = bcon->_nodes[cindex+1];
   if (con_next->in(0) != con || !con_next->is_MachProj()) {
@@ -306,7 +306,7 @@
   Node *kills = con_next->clone();
   kills->set_req(0, copy);
   b->_nodes.insert(idx, kills);
-  _cfg._bbs.map(kills->_idx, b);
+  _cfg.map_node_to_block(kills, b);
   new_lrg(kills, max_lrg_id);
   return true;
 }
@@ -962,8 +962,7 @@
         // AggressiveCoalesce.  This effectively pre-virtual-splits
         // around uncommon uses of common defs.
         const RegMask &rm = n->in_RegMask(k);
-        if( !after_aggressive &&
-          _cfg._bbs[n->in(k)->_idx]->_freq > 1000*b->_freq ) {
+        if (!after_aggressive && _cfg.get_block_for_node(n->in(k))->_freq > 1000 * b->_freq) {
           // Since we are BEFORE aggressive coalesce, leave the register
           // mask untrimmed by the call.  This encourages more coalescing.
           // Later, AFTER aggressive, this live range will have to spill
@@ -1709,16 +1708,15 @@
       // set control to _root and place it into Start block
       // (where top() node is placed).
       base->init_req(0, _cfg._root);
-      Block *startb = _cfg._bbs[C->top()->_idx];
+      Block *startb = _cfg.get_block_for_node(C->top());
       startb->_nodes.insert(startb->find_node(C->top()), base );
-      _cfg._bbs.map( base->_idx, startb );
+      _cfg.map_node_to_block(base, startb);
       assert(_lrg_map.live_range_id(base) == 0, "should not have LRG yet");
     }
     if (_lrg_map.live_range_id(base) == 0) {
       new_lrg(base, maxlrg++);
     }
-    assert(base->in(0) == _cfg._root &&
-           _cfg._bbs[base->_idx] == _cfg._bbs[C->top()->_idx], "base NULL should be shared");
+    assert(base->in(0) == _cfg._root && _cfg.get_block_for_node(base) == _cfg.get_block_for_node(C->top()), "base NULL should be shared");
     derived_base_map[derived->_idx] = base;
     return base;
   }
@@ -1754,12 +1752,12 @@
   base->as_Phi()->set_type(t);
 
   // Search the current block for an existing base-Phi
-  Block *b = _cfg._bbs[derived->_idx];
+  Block *b = _cfg.get_block_for_node(derived);
   for( i = 1; i <= b->end_idx(); i++ ) {// Search for matching Phi
     Node *phi = b->_nodes[i];
     if( !phi->is_Phi() ) {      // Found end of Phis with no match?
       b->_nodes.insert( i, base ); // Must insert created Phi here as base
-      _cfg._bbs.map( base->_idx, b );
+      _cfg.map_node_to_block(base, b);
       new_lrg(base,maxlrg++);
       break;
     }
@@ -1815,8 +1813,8 @@
       if( n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CmpI ) {
         Node *phi = n->in(1);
         if( phi->is_Phi() && phi->as_Phi()->region()->is_Loop() ) {
-          Block *phi_block = _cfg._bbs[phi->_idx];
-          if( _cfg._bbs[phi_block->pred(2)->_idx] == b ) {
+          Block *phi_block = _cfg.get_block_for_node(phi);
+          if (_cfg.get_block_for_node(phi_block->pred(2)) == b) {
             const RegMask *mask = C->matcher()->idealreg2spillmask[Op_RegI];
             Node *spill = new (C) MachSpillCopyNode( phi, *mask, *mask );
             insert_proj( phi_block, 1, spill, maxlrg++ );
@@ -1870,7 +1868,7 @@
             if ((_lrg_map.live_range_id(base) >= _lrg_map.max_lrg_id() || // (Brand new base (hence not live) or
                  !liveout.member(_lrg_map.live_range_id(base))) && // not live) AND
                  (_lrg_map.live_range_id(base) > 0) && // not a constant
-                 _cfg._bbs[base->_idx] != b) { // base not def'd in blk)
+                 _cfg.get_block_for_node(base) != b) { // base not def'd in blk)
               // Base pointer is not currently live.  Since I stretched
               // the base pointer to here and it crosses basic-block
               // boundaries, the global live info is now incorrect.
@@ -1993,8 +1991,8 @@
   tty->print("\n");
 }
 
-void PhaseChaitin::dump( const Block * b ) const {
-  b->dump_head( &_cfg._bbs );
+void PhaseChaitin::dump(const Block *b) const {
+  b->dump_head(&_cfg);
 
   // For all instructions
   for( uint j = 0; j < b->_nodes.size(); j++ )
@@ -2299,7 +2297,7 @@
       if (_lrg_map.find_const(n) == lidx) {
         if (!dump_once++) {
           tty->cr();
-          b->dump_head( &_cfg._bbs );
+          b->dump_head(&_cfg);
         }
         dump(n);
         continue;
@@ -2314,7 +2312,7 @@
           if (_lrg_map.find_const(m) == lidx) {
             if (!dump_once++) {
               tty->cr();
-              b->dump_head(&_cfg._bbs);
+              b->dump_head(&_cfg);
             }
             dump(n);
           }
--- a/src/share/vm/opto/coalesce.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/coalesce.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -52,7 +52,7 @@
     // Print a nice block header
     tty->print("B%d: ",b->_pre_order);
     for( j=1; j<b->num_preds(); j++ )
-      tty->print("B%d ", _phc._cfg._bbs[b->pred(j)->_idx]->_pre_order);
+      tty->print("B%d ", _phc._cfg.get_block_for_node(b->pred(j))->_pre_order);
     tty->print("-> ");
     for( j=0; j<b->_num_succs; j++ )
       tty->print("B%d ",b->_succs[j]->_pre_order);
@@ -208,7 +208,7 @@
     copy->set_req(idx,tmp);
     // Save source in temp early, before source is killed
     b->_nodes.insert(kill_src_idx,tmp);
-    _phc._cfg._bbs.map( tmp->_idx, b );
+    _phc._cfg.map_node_to_block(tmp, b);
     last_use_idx++;
   }
 
@@ -286,7 +286,7 @@
           Node *m = n->in(j);
           uint src_name = _phc._lrg_map.find(m);
           if (src_name != phi_name) {
-            Block *pred = _phc._cfg._bbs[b->pred(j)->_idx];
+            Block *pred = _phc._cfg.get_block_for_node(b->pred(j));
             Node *copy;
             assert(!m->is_Con() || m->is_Mach(), "all Con must be Mach");
             // Rematerialize constants instead of copying them
@@ -305,7 +305,7 @@
             }
             // Insert the copy in the use-def chain
             n->set_req(j, copy);
-            _phc._cfg._bbs.map( copy->_idx, pred );
+            _phc._cfg.map_node_to_block(copy, pred);
             // Extend ("register allocate") the names array for the copy.
             _phc._lrg_map.extend(copy->_idx, phi_name);
           } // End of if Phi names do not match
@@ -343,13 +343,13 @@
             n->set_req(idx, copy);
             // Extend ("register allocate") the names array for the copy.
             _phc._lrg_map.extend(copy->_idx, name);
-            _phc._cfg._bbs.map( copy->_idx, b );
+            _phc._cfg.map_node_to_block(copy, b);
           }
 
         } // End of is two-adr
 
         // Insert a copy at a debug use for a lrg which has high frequency
-        if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(_phc._cfg._bbs)) {
+        if (b->_freq < OPTO_DEBUG_SPLIT_FREQ || b->is_uncommon(&_phc._cfg)) {
           // Walk the debug inputs to the node and check for lrg freq
           JVMState* jvms = n->jvms();
           uint debug_start = jvms ? jvms->debug_start() : 999999;
@@ -391,7 +391,7 @@
               uint max_lrg_id = _phc._lrg_map.max_lrg_id();
               _phc.new_lrg(copy, max_lrg_id);
               _phc._lrg_map.set_max_lrg_id(max_lrg_id + 1);
-              _phc._cfg._bbs.map(copy->_idx, b);
+              _phc._cfg.map_node_to_block(copy, b);
               //tty->print_cr("Split a debug use in Aggressive Coalesce");
             }  // End of if high frequency use/def
           }  // End of for all debug inputs
@@ -437,7 +437,10 @@
     Block *bs = b->_succs[i];
     // Find index of 'b' in 'bs' predecessors
     uint j=1;
-    while( _phc._cfg._bbs[bs->pred(j)->_idx] != b ) j++;
+    while (_phc._cfg.get_block_for_node(bs->pred(j)) != b) {
+      j++;
+    }
+
     // Visit all the Phis in successor block
     for( uint k = 1; k<bs->_nodes.size(); k++ ) {
       Node *n = bs->_nodes[k];
@@ -510,9 +513,9 @@
   if( bindex < b->_fhrp_index ) b->_fhrp_index--;
 
   // Stretched lr1; add it to liveness of intermediate blocks
-  Block *b2 = _phc._cfg._bbs[src_copy->_idx];
+  Block *b2 = _phc._cfg.get_block_for_node(src_copy);
   while( b != b2 ) {
-    b = _phc._cfg._bbs[b->pred(1)->_idx];
+    b = _phc._cfg.get_block_for_node(b->pred(1));
     _phc._live->live(b)->insert(lr1);
   }
 }
@@ -532,7 +535,7 @@
     bindex2--;                  // Chain backwards 1 instruction
     while( bindex2 == 0 ) {     // At block start, find prior block
       assert( b2->num_preds() == 2, "cannot double coalesce across c-flow" );
-      b2 = _phc._cfg._bbs[b2->pred(1)->_idx];
+      b2 = _phc._cfg.get_block_for_node(b2->pred(1));
       bindex2 = b2->end_idx()-1;
     }
     // Get prior instruction
@@ -676,8 +679,8 @@
 
   if (UseFPUForSpilling && rm.is_AllStack() ) {
     // Don't coalesce when frequency difference is large
-    Block *dst_b = _phc._cfg._bbs[dst_copy->_idx];
-    Block *src_def_b = _phc._cfg._bbs[src_def->_idx];
+    Block *dst_b = _phc._cfg.get_block_for_node(dst_copy);
+    Block *src_def_b = _phc._cfg.get_block_for_node(src_def);
     if (src_def_b->_freq > 10*dst_b->_freq )
       return false;
   }
@@ -690,7 +693,7 @@
   // Another early bail-out test is when we are double-coalescing and the
   // 2 copies are separated by some control flow.
   if( dst_copy != src_copy ) {
-    Block *src_b = _phc._cfg._bbs[src_copy->_idx];
+    Block *src_b = _phc._cfg.get_block_for_node(src_copy);
     Block *b2 = b;
     while( b2 != src_b ) {
       if( b2->num_preds() > 2 ){// Found merge-point
@@ -701,7 +704,7 @@
         //record_bias( _phc._lrgs, lr1, lr2 );
         return false;           // To hard to find all interferences
       }
-      b2 = _phc._cfg._bbs[b2->pred(1)->_idx];
+      b2 = _phc._cfg.get_block_for_node(b2->pred(1));
     }
   }
 
@@ -786,8 +789,9 @@
 // Conservative (but pessimistic) copy coalescing of a single block
 void PhaseConservativeCoalesce::coalesce( Block *b ) {
   // Bail out on infrequent blocks
-  if( b->is_uncommon(_phc._cfg._bbs) )
+  if (b->is_uncommon(&_phc._cfg)) {
     return;
+  }
   // Check this block for copies.
   for( uint i = 1; i<b->end_idx(); i++ ) {
     // Check for actual copies on inputs.  Coalesce a copy into its
--- a/src/share/vm/opto/compile.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/compile.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -2262,7 +2262,7 @@
       tty->print("%3.3x   ", pcs[n->_idx]);
     else
       tty->print("      ");
-    b->dump_head( &_cfg->_bbs );
+    b->dump_head(_cfg);
     if (b->is_connector()) {
       tty->print_cr("        # Empty connector block");
     } else if (b->num_preds() == 2 && b->pred(1)->is_CatchProj() && b->pred(1)->as_CatchProj()->_con == CatchProjNode::fall_through_index) {
@@ -3525,7 +3525,7 @@
 }
 
 Compile::Constant Compile::ConstantTable::add(MachConstantNode* n, BasicType type, jvalue value) {
-  Block* b = Compile::current()->cfg()->_bbs[n->_idx];
+  Block* b = Compile::current()->cfg()->get_block_for_node(n);
   Constant con(type, value, b->_freq);
   add(con);
   return con;
--- a/src/share/vm/opto/domgraph.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/domgraph.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -105,8 +105,8 @@
 
     // Step 2:
     Node *whead = w->_block->head();
-    for( uint j=1; j < whead->req(); j++ ) {
-      Block *b = _bbs[whead->in(j)->_idx];
+    for (uint j = 1; j < whead->req(); j++) {
+      Block* b = get_block_for_node(whead->in(j));
       Tarjan *vx = &tarjan[b->_pre_order];
       Tarjan *u = vx->EVAL();
       if( u->_semi < w->_semi )
--- a/src/share/vm/opto/gcm.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/gcm.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -66,7 +66,7 @@
 // are in b also.
 void PhaseCFG::schedule_node_into_block( Node *n, Block *b ) {
   // Set basic block of n, Add n to b,
-  _bbs.map(n->_idx, b);
+  map_node_to_block(n, b);
   b->add_inst(n);
 
   // After Matching, nearly any old Node may have projections trailing it.
@@ -75,11 +75,12 @@
   for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
     Node*  use  = n->fast_out(i);
     if (use->is_Proj()) {
-      Block* buse = _bbs[use->_idx];
+      Block* buse = get_block_for_node(use);
       if (buse != b) {              // In wrong block?
-        if (buse != NULL)
+        if (buse != NULL) {
           buse->find_remove(use);   // Remove from wrong block
-        _bbs.map(use->_idx, b);     // Re-insert in this block
+        }
+        map_node_to_block(use, b);
         b->add_inst(use);
       }
     }
@@ -97,7 +98,7 @@
   if (p != NULL && p != n) {    // Control from a block projection?
     assert(!n->pinned() || n->is_MachConstantBase(), "only pinned MachConstantBase node is expected here");
     // Find trailing Region
-    Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
+    Block *pb = get_block_for_node(in0); // Block-projection already has basic block
     uint j = 0;
     if (pb->_num_succs != 1) {  // More then 1 successor?
       // Search for successor
@@ -127,14 +128,15 @@
   while ( spstack.is_nonempty() ) {
     Node *n = spstack.pop();
     if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited
-      if( n->pinned() && !_bbs.lookup(n->_idx) ) {  // Pinned?  Nail it down!
+      if( n->pinned() && !has_block(n)) {  // Pinned?  Nail it down!
         assert( n->in(0), "pinned Node must have Control" );
         // Before setting block replace block_proj control edge
         replace_block_proj_ctrl(n);
         Node *input = n->in(0);
-        while( !input->is_block_start() )
+        while (!input->is_block_start()) {
           input = input->in(0);
-        Block *b = _bbs[input->_idx];  // Basic block of controlling input
+        }
+        Block *b = get_block_for_node(input); // Basic block of controlling input
         schedule_node_into_block(n, b);
       }
       for( int i = n->req() - 1; i >= 0; --i ) {  // For all inputs
@@ -149,7 +151,7 @@
 // Assert that new input b2 is dominated by all previous inputs.
 // Check this by by seeing that it is dominated by b1, the deepest
 // input observed until b2.
-static void assert_dom(Block* b1, Block* b2, Node* n, Block_Array &bbs) {
+static void assert_dom(Block* b1, Block* b2, Node* n, const PhaseCFG* cfg) {
   if (b1 == NULL)  return;
   assert(b1->_dom_depth < b2->_dom_depth, "sanity");
   Block* tmp = b2;
@@ -162,7 +164,7 @@
     for (uint j=0; j<n->len(); j++) { // For all inputs
       Node* inn = n->in(j); // Get input
       if (inn == NULL)  continue;  // Ignore NULL, missing inputs
-      Block* inb = bbs[inn->_idx];
+      Block* inb = cfg->get_block_for_node(inn);
       tty->print("B%d idom=B%d depth=%2d ",inb->_pre_order,
                  inb->_idom ? inb->_idom->_pre_order : 0, inb->_dom_depth);
       inn->dump();
@@ -174,20 +176,20 @@
 }
 #endif
 
-static Block* find_deepest_input(Node* n, Block_Array &bbs) {
+static Block* find_deepest_input(Node* n, const PhaseCFG* cfg) {
   // Find the last input dominated by all other inputs.
   Block* deepb           = NULL;        // Deepest block so far
   int    deepb_dom_depth = 0;
   for (uint k = 0; k < n->len(); k++) { // For all inputs
     Node* inn = n->in(k);               // Get input
     if (inn == NULL)  continue;         // Ignore NULL, missing inputs
-    Block* inb = bbs[inn->_idx];
+    Block* inb = cfg->get_block_for_node(inn);
     assert(inb != NULL, "must already have scheduled this input");
     if (deepb_dom_depth < (int) inb->_dom_depth) {
       // The new inb must be dominated by the previous deepb.
       // The various inputs must be linearly ordered in the dom
       // tree, or else there will not be a unique deepest block.
-      DEBUG_ONLY(assert_dom(deepb, inb, n, bbs));
+      DEBUG_ONLY(assert_dom(deepb, inb, n, cfg));
       deepb = inb;                      // Save deepest block
       deepb_dom_depth = deepb->_dom_depth;
     }
@@ -243,7 +245,7 @@
         ++i;
         if (in == NULL) continue;    // Ignore NULL, missing inputs
         int is_visited = visited.test_set(in->_idx);
-        if (!_bbs.lookup(in->_idx)) { // Missing block selection?
+        if (!has_block(in)) { // Missing block selection?
           if (is_visited) {
             // assert( !visited.test(in->_idx), "did not schedule early" );
             return false;
@@ -265,9 +267,9 @@
         // any projections which depend on them.
         if (!n->pinned()) {
           // Set earliest legal block.
-          _bbs.map(n->_idx, find_deepest_input(n, _bbs));
+          map_node_to_block(n, find_deepest_input(n, this));
         } else {
-          assert(_bbs[n->_idx] == _bbs[n->in(0)->_idx], "Pinned Node should be at the same block as its control edge");
+          assert(get_block_for_node(n) == get_block_for_node(n->in(0)), "Pinned Node should be at the same block as its control edge");
         }
 
         if (nstack.is_empty()) {
@@ -313,8 +315,8 @@
 // The definition must dominate the use, so move the LCA upward in the
 // dominator tree to dominate the use.  If the use is a phi, adjust
 // the LCA only with the phi input paths which actually use this def.
-static Block* raise_LCA_above_use(Block* LCA, Node* use, Node* def, Block_Array &bbs) {
-  Block* buse = bbs[use->_idx];
+static Block* raise_LCA_above_use(Block* LCA, Node* use, Node* def, const PhaseCFG* cfg) {
+  Block* buse = cfg->get_block_for_node(use);
   if (buse == NULL)    return LCA;   // Unused killing Projs have no use block
   if (!use->is_Phi())  return buse->dom_lca(LCA);
   uint pmax = use->req();       // Number of Phi inputs
@@ -329,7 +331,7 @@
   // more than once.
   for (uint j=1; j<pmax; j++) { // For all inputs
     if (use->in(j) == def) {    // Found matching input?
-      Block* pred = bbs[buse->pred(j)->_idx];
+      Block* pred = cfg->get_block_for_node(buse->pred(j));
       LCA = pred->dom_lca(LCA);
     }
   }
@@ -342,8 +344,7 @@
 // which are marked with the given index.  Return the LCA (in the dom tree)
 // of all marked blocks.  If there are none marked, return the original
 // LCA.
-static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark,
-                                    Block* early, Block_Array &bbs) {
+static Block* raise_LCA_above_marks(Block* LCA, node_idx_t mark, Block* early, const PhaseCFG* cfg) {
   Block_List worklist;
   worklist.push(LCA);
   while (worklist.size() > 0) {
@@ -366,7 +367,7 @@
     } else {
       // Keep searching through this block's predecessors.
       for (uint j = 1, jmax = mid->num_preds(); j < jmax; j++) {
-        Block* mid_parent = bbs[ mid->pred(j)->_idx ];
+        Block* mid_parent = cfg->get_block_for_node(mid->pred(j));
         worklist.push(mid_parent);
       }
     }
@@ -384,7 +385,7 @@
 // be earlier (at a shallower dom_depth) than the true schedule_early
 // point of the node. We compute this earlier block as a more permissive
 // site for anti-dependency insertion, but only if subsume_loads is enabled.
-static Block* memory_early_block(Node* load, Block* early, Block_Array &bbs) {
+static Block* memory_early_block(Node* load, Block* early, const PhaseCFG* cfg) {
   Node* base;
   Node* index;
   Node* store = load->in(MemNode::Memory);
@@ -412,12 +413,12 @@
     Block* deepb           = NULL;        // Deepest block so far
     int    deepb_dom_depth = 0;
     for (int i = 0; i < mem_inputs_length; i++) {
-      Block* inb = bbs[mem_inputs[i]->_idx];
+      Block* inb = cfg->get_block_for_node(mem_inputs[i]);
       if (deepb_dom_depth < (int) inb->_dom_depth) {
         // The new inb must be dominated by the previous deepb.
         // The various inputs must be linearly ordered in the dom
         // tree, or else there will not be a unique deepest block.
-        DEBUG_ONLY(assert_dom(deepb, inb, load, bbs));
+        DEBUG_ONLY(assert_dom(deepb, inb, load, cfg));
         deepb = inb;                      // Save deepest block
         deepb_dom_depth = deepb->_dom_depth;
       }
@@ -488,14 +489,14 @@
   // and other inputs are first available.  (Computed by schedule_early.)
   // For normal loads, 'early' is the shallowest place (dom graph wise)
   // to look for anti-deps between this load and any store.
-  Block* early = _bbs[load_index];
+  Block* early = get_block_for_node(load);
 
   // If we are subsuming loads, compute an "early" block that only considers
   // memory or address inputs. This block may be different than the
   // schedule_early block in that it could be at an even shallower depth in the
   // dominator tree, and allow for a broader discovery of anti-dependences.
   if (C->subsume_loads()) {
-    early = memory_early_block(load, early, _bbs);
+    early = memory_early_block(load, early, this);
   }
 
   ResourceArea *area = Thread::current()->resource_area();
@@ -619,7 +620,7 @@
     // or else observe that 'store' is all the way up in the
     // earliest legal block for 'load'.  In the latter case,
     // immediately insert an anti-dependence edge.
-    Block* store_block = _bbs[store->_idx];
+    Block* store_block = get_block_for_node(store);
     assert(store_block != NULL, "unused killing projections skipped above");
 
     if (store->is_Phi()) {
@@ -637,7 +638,7 @@
       for (uint j = PhiNode::Input, jmax = store->req(); j < jmax; j++) {
         if (store->in(j) == mem) {   // Found matching input?
           DEBUG_ONLY(found_match = true);
-          Block* pred_block = _bbs[store_block->pred(j)->_idx];
+          Block* pred_block = get_block_for_node(store_block->pred(j));
           if (pred_block != early) {
             // If any predecessor of the Phi matches the load's "early block",
             // we do not need a precedence edge between the Phi and 'load'
@@ -711,7 +712,7 @@
   // preventing the load from sinking past any block containing
   // a store that may invalidate the memory state required by 'load'.
   if (must_raise_LCA)
-    LCA = raise_LCA_above_marks(LCA, load->_idx, early, _bbs);
+    LCA = raise_LCA_above_marks(LCA, load->_idx, early, this);
   if (LCA == early)  return LCA;
 
   // Insert anti-dependence edges from 'load' to each store
@@ -720,7 +721,7 @@
   if (LCA->raise_LCA_mark() == load_index) {
     while (non_early_stores.size() > 0) {
       Node* store = non_early_stores.pop();
-      Block* store_block = _bbs[store->_idx];
+      Block* store_block = get_block_for_node(store);
       if (store_block == LCA) {
         // add anti_dependence from store to load in its own block
         assert(store != load->in(0), "dependence cycle found");
@@ -754,7 +755,7 @@
 
 public:
   // Constructor for the iterator
-  Node_Backward_Iterator(Node *root, VectorSet &visited, Node_List &stack, Block_Array &bbs);
+  Node_Backward_Iterator(Node *root, VectorSet &visited, Node_List &stack, PhaseCFG &cfg);
 
   // Postincrement operator to iterate over the nodes
   Node *next();
@@ -762,12 +763,12 @@
 private:
   VectorSet   &_visited;
   Node_List   &_stack;
-  Block_Array &_bbs;
+  PhaseCFG &_cfg;
 };
 
 // Constructor for the Node_Backward_Iterator
-Node_Backward_Iterator::Node_Backward_Iterator( Node *root, VectorSet &visited, Node_List &stack, Block_Array &bbs )
-  : _visited(visited), _stack(stack), _bbs(bbs) {
+Node_Backward_Iterator::Node_Backward_Iterator( Node *root, VectorSet &visited, Node_List &stack, PhaseCFG &cfg)
+  : _visited(visited), _stack(stack), _cfg(cfg) {
   // The stack should contain exactly the root
   stack.clear();
   stack.push(root);
@@ -797,8 +798,8 @@
     _visited.set(self->_idx);
 
     // Now schedule all uses as late as possible.
-    uint src     = self->is_Proj() ? self->in(0)->_idx : self->_idx;
-    uint src_rpo = _bbs[src]->_rpo;
+    const Node* src = self->is_Proj() ? self->in(0) : self;
+    uint src_rpo = _cfg.get_block_for_node(src)->_rpo;
 
     // Schedule all nodes in a post-order visit
     Node *unvisited = NULL;  // Unvisited anti-dependent Node, if any
@@ -814,7 +815,7 @@
 
       // do not traverse backward control edges
       Node *use = n->is_Proj() ? n->in(0) : n;
-      uint use_rpo = _bbs[use->_idx]->_rpo;
+      uint use_rpo = _cfg.get_block_for_node(use)->_rpo;
 
       if ( use_rpo < src_rpo )
         continue;
@@ -852,7 +853,7 @@
     tty->print("\n#---- ComputeLatenciesBackwards ----\n");
 #endif
 
-  Node_Backward_Iterator iter((Node *)_root, visited, stack, _bbs);
+  Node_Backward_Iterator iter((Node *)_root, visited, stack, *this);
   Node *n;
 
   // Walk over all the nodes from last to first
@@ -883,7 +884,7 @@
 
   uint nlen = n->len();
   uint use_latency = _node_latency->at_grow(n->_idx);
-  uint use_pre_order = _bbs[n->_idx]->_pre_order;
+  uint use_pre_order = get_block_for_node(n)->_pre_order;
 
   for ( uint j=0; j<nlen; j++ ) {
     Node *def = n->in(j);
@@ -903,7 +904,7 @@
 #endif
 
     // If the defining block is not known, assume it is ok
-    Block *def_block = _bbs[def->_idx];
+    Block *def_block = get_block_for_node(def);
     uint def_pre_order = def_block ? def_block->_pre_order : 0;
 
     if ( (use_pre_order <  def_pre_order) ||
@@ -931,10 +932,11 @@
 // Compute the latency of a specific use
 int PhaseCFG::latency_from_use(Node *n, const Node *def, Node *use) {
   // If self-reference, return no latency
-  if (use == n || use->is_Root())
+  if (use == n || use->is_Root()) {
     return 0;
+  }
 
-  uint def_pre_order = _bbs[def->_idx]->_pre_order;
+  uint def_pre_order = get_block_for_node(def)->_pre_order;
   uint latency = 0;
 
   // If the use is not a projection, then it is simple...
@@ -946,7 +948,7 @@
     }
 #endif
 
-    uint use_pre_order = _bbs[use->_idx]->_pre_order;
+    uint use_pre_order = get_block_for_node(use)->_pre_order;
 
     if (use_pre_order < def_pre_order)
       return 0;
@@ -1018,7 +1020,7 @@
   uint start_latency = _node_latency->at_grow(LCA->_nodes[0]->_idx);
   uint end_latency   = _node_latency->at_grow(LCA->_nodes[LCA->end_idx()]->_idx);
   bool in_latency    = (target <= start_latency);
-  const Block* root_block = _bbs[_root->_idx];
+  const Block* root_block = get_block_for_node(_root);
 
   // Turn off latency scheduling if scheduling is just plain off
   if (!C->do_scheduling())
@@ -1126,12 +1128,12 @@
     tty->print("\n#---- schedule_late ----\n");
 #endif
 
-  Node_Backward_Iterator iter((Node *)_root, visited, stack, _bbs);
+  Node_Backward_Iterator iter((Node *)_root, visited, stack, *this);
   Node *self;
 
   // Walk over all the nodes from last to first
   while (self = iter.next()) {
-    Block* early = _bbs[self->_idx];   // Earliest legal placement
+    Block* early = get_block_for_node(self); // Earliest legal placement
 
     if (self->is_top()) {
       // Top node goes in bb #2 with other constants.
@@ -1179,7 +1181,7 @@
       for (DUIterator_Fast imax, i = self->fast_outs(imax); i < imax; i++) {
         // For all uses, find LCA
         Node* use = self->fast_out(i);
-        LCA = raise_LCA_above_use(LCA, use, self, _bbs);
+        LCA = raise_LCA_above_use(LCA, use, self, this);
       }
     }  // (Hide defs of imax, i from rest of block.)
 
@@ -1187,7 +1189,7 @@
     // requirement for correctness but it reduces useless
     // interference between temps and other nodes.
     if (mach != NULL && mach->is_MachTemp()) {
-      _bbs.map(self->_idx, LCA);
+      map_node_to_block(self, LCA);
       LCA->add_inst(self);
       continue;
     }
@@ -1262,10 +1264,10 @@
   }
 #endif
 
-  // Initialize the bbs.map for things on the proj_list
-  uint i;
-  for( i=0; i < proj_list.size(); i++ )
-    _bbs.map(proj_list[i]->_idx, NULL);
+  // Initialize the node to block mapping for things on the proj_list
+  for (uint i = 0; i < proj_list.size(); i++) {
+    unmap_node_from_block(proj_list[i]);
+  }
 
   // Set the basic block for Nodes pinned into blocks
   Arena *a = Thread::current()->resource_area();
@@ -1333,7 +1335,7 @@
     for( int i= matcher._null_check_tests.size()-2; i>=0; i-=2 ) {
       Node *proj = matcher._null_check_tests[i  ];
       Node *val  = matcher._null_check_tests[i+1];
-      _bbs[proj->_idx]->implicit_null_check(this, proj, val, allowed_reasons);
+      get_block_for_node(proj)->implicit_null_check(this, proj, val, allowed_reasons);
       // The implicit_null_check will only perform the transformation
       // if the null branch is truly uncommon, *and* it leads to an
       // uncommon trap.  Combined with the too_many_traps guards
@@ -1353,7 +1355,7 @@
   uint max_idx = C->unique();
   GrowableArray<int> ready_cnt(max_idx, max_idx, -1);
   visited.Clear();
-  for (i = 0; i < _num_blocks; i++) {
+  for (uint i = 0; i < _num_blocks; i++) {
     if (!_blocks[i]->schedule_local(this, matcher, ready_cnt, visited)) {
       if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
         C->record_method_not_compilable("local schedule failed");
@@ -1364,8 +1366,9 @@
 
   // If we inserted any instructions between a Call and his CatchNode,
   // clone the instructions on all paths below the Catch.
-  for( i=0; i < _num_blocks; i++ )
-    _blocks[i]->call_catch_cleanup(_bbs, C);
+  for (uint i = 0; i < _num_blocks; i++) {
+    _blocks[i]->call_catch_cleanup(this, C);
+  }
 
 #ifndef PRODUCT
   if (trace_opto_pipelining()) {
@@ -1392,7 +1395,7 @@
     Block_List worklist;
     Block* root_blk = _blocks[0];
     for (uint i = 1; i < root_blk->num_preds(); i++) {
-      Block *pb = _bbs[root_blk->pred(i)->_idx];
+      Block *pb = get_block_for_node(root_blk->pred(i));
       if (pb->has_uncommon_code()) {
         worklist.push(pb);
       }
@@ -1401,7 +1404,7 @@
       Block* uct = worklist.pop();
       if (uct == _broot) continue;
       for (uint i = 1; i < uct->num_preds(); i++) {
-        Block *pb = _bbs[uct->pred(i)->_idx];
+        Block *pb = get_block_for_node(uct->pred(i));
         if (pb->_num_succs == 1) {
           worklist.push(pb);
         } else if (pb->num_fall_throughs() == 2) {
@@ -1430,7 +1433,7 @@
     Block_List worklist;
     Block* root_blk = _blocks[0];
     for (uint i = 1; i < root_blk->num_preds(); i++) {
-      Block *pb = _bbs[root_blk->pred(i)->_idx];
+      Block *pb = get_block_for_node(root_blk->pred(i));
       if (pb->has_uncommon_code()) {
         worklist.push(pb);
       }
@@ -1439,7 +1442,7 @@
       Block* uct = worklist.pop();
       uct->_freq = PROB_MIN;
       for (uint i = 1; i < uct->num_preds(); i++) {
-        Block *pb = _bbs[uct->pred(i)->_idx];
+        Block *pb = get_block_for_node(uct->pred(i));
         if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) {
           worklist.push(pb);
         }
@@ -1499,7 +1502,7 @@
       Block* loop_head = b;
       assert(loop_head->num_preds() - 1 == 2, "loop must have 2 predecessors");
       Node* tail_n = loop_head->pred(LoopNode::LoopBackControl);
-      Block* tail = _bbs[tail_n->_idx];
+      Block* tail = get_block_for_node(tail_n);
 
       // Defensively filter out Loop nodes for non-single-entry loops.
       // For all reasonable loops, the head occurs before the tail in RPO.
@@ -1514,13 +1517,13 @@
         loop_head->_loop = nloop;
         // Add to nloop so push_pred() will skip over inner loops
         nloop->add_member(loop_head);
-        nloop->push_pred(loop_head, LoopNode::LoopBackControl, worklist, _bbs);
+        nloop->push_pred(loop_head, LoopNode::LoopBackControl, worklist, this);
 
         while (worklist.size() > 0) {
           Block* member = worklist.pop();
           if (member != loop_head) {
             for (uint j = 1; j < member->num_preds(); j++) {
-              nloop->push_pred(member, j, worklist, _bbs);
+              nloop->push_pred(member, j, worklist, this);
             }
           }
         }
@@ -1557,9 +1560,9 @@
 }
 
 //------------------------------push_pred--------------------------------------
-void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk) {
+void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, PhaseCFG* cfg) {
   Node* pred_n = blk->pred(i);
-  Block* pred = node_to_blk[pred_n->_idx];
+  Block* pred = cfg->get_block_for_node(pred_n);
   CFGLoop *pred_loop = pred->_loop;
   if (pred_loop == NULL) {
     // Filter out blocks for non-single-entry loops.
@@ -1580,7 +1583,7 @@
       Block* pred_head = pred_loop->head();
       assert(pred_head->num_preds() - 1 == 2, "loop must have 2 predecessors");
       assert(pred_head != head(), "loop head in only one loop");
-      push_pred(pred_head, LoopNode::EntryControl, worklist, node_to_blk);
+      push_pred(pred_head, LoopNode::EntryControl, worklist, cfg);
     } else {
       assert(pred_loop->_parent == this && _parent == NULL, "just checking");
     }
--- a/src/share/vm/opto/idealGraphPrinter.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/idealGraphPrinter.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -413,9 +413,9 @@
     print_prop("debug_idx", node->_debug_idx);
 #endif
 
-    if(C->cfg() != NULL) {
-      Block *block = C->cfg()->_bbs[node->_idx];
-      if(block == NULL) {
+    if (C->cfg() != NULL) {
+      Block* block = C->cfg()->get_block_for_node(node);
+      if (block == NULL) {
         print_prop("block", C->cfg()->_blocks[0]->_pre_order);
       } else {
         print_prop("block", block->_pre_order);
--- a/src/share/vm/opto/ifg.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/ifg.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -565,7 +565,7 @@
               lrgs(r)._def = 0;
             }
             n->disconnect_inputs(NULL, C);
-            _cfg._bbs.map(n->_idx,NULL);
+            _cfg.unmap_node_from_block(n);
             n->replace_by(C->top());
             // Since yanking a Node from block, high pressure moves up one
             hrp_index[0]--;
@@ -607,7 +607,7 @@
           if( n->is_SpillCopy()
               && lrgs(r).is_singledef()        // MultiDef live range can still split
               && n->outcnt() == 1              // and use must be in this block
-              && _cfg._bbs[n->unique_out()->_idx] == b ) {
+              && _cfg.get_block_for_node(n->unique_out()) == b ) {
             // All single-use MachSpillCopy(s) that immediately precede their
             // use must color early.  If a longer live range steals their
             // color, the spill copy will split and may push another spill copy
--- a/src/share/vm/opto/lcm.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/lcm.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -237,7 +237,7 @@
     }
 
     // Check ctrl input to see if the null-check dominates the memory op
-    Block *cb = cfg->_bbs[mach->_idx];
+    Block *cb = cfg->get_block_for_node(mach);
     cb = cb->_idom;             // Always hoist at least 1 block
     if( !was_store ) {          // Stores can be hoisted only one block
       while( cb->_dom_depth > (_dom_depth + 1))
@@ -262,7 +262,7 @@
         if( is_decoden ) continue;
       }
       // Block of memory-op input
-      Block *inb = cfg->_bbs[mach->in(j)->_idx];
+      Block *inb = cfg->get_block_for_node(mach->in(j));
       Block *b = this;          // Start from nul check
       while( b != inb && b->_dom_depth > inb->_dom_depth )
         b = b->_idom;           // search upwards for input
@@ -272,7 +272,7 @@
     }
     if( j > 0 )
       continue;
-    Block *mb = cfg->_bbs[mach->_idx];
+    Block *mb = cfg->get_block_for_node(mach);
     // Hoisting stores requires more checks for the anti-dependence case.
     // Give up hoisting if we have to move the store past any load.
     if( was_store ) {
@@ -291,7 +291,7 @@
           break;                // Found anti-dependent load
         // Make sure control does not do a merge (would have to check allpaths)
         if( b->num_preds() != 2 ) break;
-        b = cfg->_bbs[b->pred(1)->_idx]; // Move up to predecessor block
+        b = cfg->get_block_for_node(b->pred(1)); // Move up to predecessor block
       }
       if( b != this ) continue;
     }
@@ -303,15 +303,15 @@
 
     // Found a candidate!  Pick one with least dom depth - the highest
     // in the dom tree should be closest to the null check.
-    if( !best ||
-        cfg->_bbs[mach->_idx]->_dom_depth < cfg->_bbs[best->_idx]->_dom_depth ) {
+    if (best == NULL || cfg->get_block_for_node(mach)->_dom_depth < cfg->get_block_for_node(best)->_dom_depth) {
       best = mach;
       bidx = vidx;
-
     }
   }
   // No candidate!
-  if( !best ) return;
+  if (best == NULL) {
+    return;
+  }
 
   // ---- Found an implicit null check
   extern int implicit_null_checks;
@@ -319,29 +319,29 @@
 
   if( is_decoden ) {
     // Check if we need to hoist decodeHeapOop_not_null first.
-    Block *valb = cfg->_bbs[val->_idx];
+    Block *valb = cfg->get_block_for_node(val);
     if( this != valb && this->_dom_depth < valb->_dom_depth ) {
       // Hoist it up to the end of the test block.
       valb->find_remove(val);
       this->add_inst(val);
-      cfg->_bbs.map(val->_idx,this);
+      cfg->map_node_to_block(val, this);
       // DecodeN on x86 may kill flags. Check for flag-killing projections
       // that also need to be hoisted.
       for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) {
         Node* n = val->fast_out(j);
         if( n->is_MachProj() ) {
-          cfg->_bbs[n->_idx]->find_remove(n);
+          cfg->get_block_for_node(n)->find_remove(n);
           this->add_inst(n);
-          cfg->_bbs.map(n->_idx,this);
+          cfg->map_node_to_block(n, this);
         }
       }
     }
   }
   // Hoist the memory candidate up to the end of the test block.
-  Block *old_block = cfg->_bbs[best->_idx];
+  Block *old_block = cfg->get_block_for_node(best);
   old_block->find_remove(best);
   add_inst(best);
-  cfg->_bbs.map(best->_idx,this);
+  cfg->map_node_to_block(best, this);
 
   // Move the control dependence
   if (best->in(0) && best->in(0) == old_block->_nodes[0])
@@ -352,9 +352,9 @@
   for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) {
     Node* n = best->fast_out(j);
     if( n->is_MachProj() ) {
-      cfg->_bbs[n->_idx]->find_remove(n);
+      cfg->get_block_for_node(n)->find_remove(n);
       add_inst(n);
-      cfg->_bbs.map(n->_idx,this);
+      cfg->map_node_to_block(n, this);
     }
   }
 
@@ -385,7 +385,7 @@
   Node *old_tst = proj->in(0);
   MachNode *nul_chk = new (C) MachNullCheckNode(old_tst->in(0),best,bidx);
   _nodes.map(end_idx(),nul_chk);
-  cfg->_bbs.map(nul_chk->_idx,this);
+  cfg->map_node_to_block(nul_chk, this);
   // Redirect users of old_test to nul_chk
   for (DUIterator_Last i2min, i2 = old_tst->last_outs(i2min); i2 >= i2min; --i2)
     old_tst->last_out(i2)->set_req(0, nul_chk);
@@ -468,7 +468,7 @@
         Node* use = n->fast_out(j);
 
         // The use is a conditional branch, make them adjacent
-        if (use->is_MachIf() && cfg->_bbs[use->_idx]==this ) {
+        if (use->is_MachIf() && cfg->get_block_for_node(use) == this) {
           found_machif = true;
           break;
         }
@@ -529,13 +529,14 @@
 
 
 //------------------------------set_next_call----------------------------------
-void Block::set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs ) {
+void Block::set_next_call( Node *n, VectorSet &next_call, PhaseCFG* cfg) {
   if( next_call.test_set(n->_idx) ) return;
   for( uint i=0; i<n->len(); i++ ) {
     Node *m = n->in(i);
     if( !m ) continue;  // must see all nodes in block that precede call
-    if( bbs[m->_idx] == this )
-      set_next_call( m, next_call, bbs );
+    if (cfg->get_block_for_node(m) == this) {
+      set_next_call(m, next_call, cfg);
+    }
   }
 }
 
@@ -545,12 +546,12 @@
 // next subroutine call get priority - basically it moves things NOT needed
 // for the next call till after the call.  This prevents me from trying to
 // carry lots of stuff live across a call.
-void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs) {
+void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, PhaseCFG* cfg) {
   // Find the next control-defining Node in this block
   Node* call = NULL;
   for (DUIterator_Fast imax, i = this_call->fast_outs(imax); i < imax; i++) {
     Node* m = this_call->fast_out(i);
-    if( bbs[m->_idx] == this && // Local-block user
+    if(cfg->get_block_for_node(m) == this && // Local-block user
         m != this_call &&       // Not self-start node
         m->is_MachCall() )
       call = m;
@@ -558,7 +559,7 @@
   }
   if (call == NULL)  return;    // No next call (e.g., block end is near)
   // Set next-call for all inputs to this call
-  set_next_call(call, next_call, bbs);
+  set_next_call(call, next_call, cfg);
 }
 
 //------------------------------add_call_kills-------------------------------------
@@ -578,7 +579,7 @@
 
 
 //------------------------------sched_call-------------------------------------
-uint Block::sched_call( Matcher &matcher, Block_Array &bbs, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
+uint Block::sched_call( Matcher &matcher, PhaseCFG* cfg, uint node_cnt, Node_List &worklist, GrowableArray<int> &ready_cnt, MachCallNode *mcall, VectorSet &next_call ) {
   RegMask regs;
 
   // Schedule all the users of the call right now.  All the users are
@@ -597,12 +598,14 @@
     // Check for scheduling the next control-definer
     if( n->bottom_type() == Type::CONTROL )
       // Warm up next pile of heuristic bits
-      needed_for_next_call(n, next_call, bbs);
+      needed_for_next_call(n, next_call, cfg);
 
     // Children of projections are now all ready
     for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
       Node* m = n->fast_out(j); // Get user
-      if( bbs[m->_idx] != this ) continue;
+      if(cfg->get_block_for_node(m) != this) {
+        continue;
+      }
       if( m->is_Phi() ) continue;
       int m_cnt = ready_cnt.at(m->_idx)-1;
       ready_cnt.at_put(m->_idx, m_cnt);
@@ -620,7 +623,7 @@
   uint r_cnt = mcall->tf()->range()->cnt();
   int op = mcall->ideal_Opcode();
   MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
-  bbs.map(proj->_idx,this);
+  cfg->map_node_to_block(proj, this);
   _nodes.insert(node_cnt++, proj);
 
   // Select the right register save policy.
@@ -708,7 +711,7 @@
       uint local = 0;
       for( uint j=0; j<cnt; j++ ) {
         Node *m = n->in(j);
-        if( m && cfg->_bbs[m->_idx] == this && !m->is_top() )
+        if( m && cfg->get_block_for_node(m) == this && !m->is_top() )
           local++;              // One more block-local input
       }
       ready_cnt.at_put(n->_idx, local); // Count em up
@@ -720,7 +723,7 @@
           for (uint prec = n->req(); prec < n->len(); prec++) {
             Node* oop_store = n->in(prec);
             if (oop_store != NULL) {
-              assert(cfg->_bbs[oop_store->_idx]->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark");
+              assert(cfg->get_block_for_node(oop_store)->_dom_depth <= this->_dom_depth, "oop_store must dominate card-mark");
             }
           }
         }
@@ -753,7 +756,7 @@
     Node *n = _nodes[i3];       // Get pre-scheduled
     for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
       Node* m = n->fast_out(j);
-      if( cfg->_bbs[m->_idx] ==this ) { // Local-block user
+      if (cfg->get_block_for_node(m) == this) { // Local-block user
         int m_cnt = ready_cnt.at(m->_idx)-1;
         ready_cnt.at_put(m->_idx, m_cnt);   // Fix ready count
       }
@@ -786,7 +789,7 @@
   }
 
   // Warm up the 'next_call' heuristic bits
-  needed_for_next_call(_nodes[0], next_call, cfg->_bbs);
+  needed_for_next_call(_nodes[0], next_call, cfg);
 
 #ifndef PRODUCT
     if (cfg->trace_opto_pipelining()) {
@@ -837,7 +840,7 @@
 #endif
     if( n->is_MachCall() ) {
       MachCallNode *mcall = n->as_MachCall();
-      phi_cnt = sched_call(matcher, cfg->_bbs, phi_cnt, worklist, ready_cnt, mcall, next_call);
+      phi_cnt = sched_call(matcher, cfg, phi_cnt, worklist, ready_cnt, mcall, next_call);
       continue;
     }
 
@@ -847,7 +850,7 @@
       regs.OR(n->out_RegMask());
 
       MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj );
-      cfg->_bbs.map(proj->_idx,this);
+      cfg->map_node_to_block(proj, this);
       _nodes.insert(phi_cnt++, proj);
 
       add_call_kills(proj, regs, matcher._c_reg_save_policy, false);
@@ -856,7 +859,9 @@
     // Children are now all ready
     for (DUIterator_Fast i5max, i5 = n->fast_outs(i5max); i5 < i5max; i5++) {
       Node* m = n->fast_out(i5); // Get user
-      if( cfg->_bbs[m->_idx] != this ) continue;
+      if (cfg->get_block_for_node(m) != this) {
+        continue;
+      }
       if( m->is_Phi() ) continue;
       if (m->_idx >= max_idx) { // new node, skip it
         assert(m->is_MachProj() && n->is_Mach() && n->as_Mach()->has_call(), "unexpected node types");
@@ -914,7 +919,7 @@
 }
 
 //------------------------------catch_cleanup_find_cloned_def------------------
-static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) {
+static Node *catch_cleanup_find_cloned_def(Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) {
   assert( use_blk != def_blk, "Inter-block cleanup only");
 
   // The use is some block below the Catch.  Find and return the clone of the def
@@ -940,7 +945,8 @@
     // PhiNode, the PhiNode uses from the def and IT's uses need fixup.
     Node_Array inputs = new Node_List(Thread::current()->resource_area());
     for(uint k = 1; k < use_blk->num_preds(); k++) {
-      inputs.map(k, catch_cleanup_find_cloned_def(bbs[use_blk->pred(k)->_idx], def, def_blk, bbs, n_clone_idx));
+      Block* block = cfg->get_block_for_node(use_blk->pred(k));
+      inputs.map(k, catch_cleanup_find_cloned_def(block, def, def_blk, cfg, n_clone_idx));
     }
 
     // Check to see if the use_blk already has an identical phi inserted.
@@ -962,7 +968,7 @@
     if (fixup == NULL) {
       Node *new_phi = PhiNode::make(use_blk->head(), def);
       use_blk->_nodes.insert(1, new_phi);
-      bbs.map(new_phi->_idx, use_blk);
+      cfg->map_node_to_block(new_phi, use_blk);
       for (uint k = 1; k < use_blk->num_preds(); k++) {
         new_phi->set_req(k, inputs[k]);
       }
@@ -1002,17 +1008,17 @@
 //------------------------------catch_cleanup_inter_block---------------------
 // Fix all input edges in use that reference "def".  The use is in a different
 // block than the def.
-static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, Block_Array &bbs, int n_clone_idx) {
+static void catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, PhaseCFG* cfg, int n_clone_idx) {
   if( !use_blk ) return;        // Can happen if the use is a precedence edge
 
-  Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, bbs, n_clone_idx);
+  Node *new_def = catch_cleanup_find_cloned_def(use_blk, def, def_blk, cfg, n_clone_idx);
   catch_cleanup_fix_all_inputs(use, def, new_def);
 }
 
 //------------------------------call_catch_cleanup-----------------------------
 // If we inserted any instructions between a Call and his CatchNode,
 // clone the instructions on all paths below the Catch.
-void Block::call_catch_cleanup(Block_Array &bbs, Compile* C) {
+void Block::call_catch_cleanup(PhaseCFG* cfg, Compile* C) {
 
   // End of region to clone
   uint end = end_idx();
@@ -1037,7 +1043,7 @@
       // since clones dominate on each path.
       Node *clone = _nodes[j-1]->clone();
       sb->_nodes.insert( 1, clone );
-      bbs.map(clone->_idx,sb);
+      cfg->map_node_to_block(clone, sb);
     }
   }
 
@@ -1054,18 +1060,19 @@
     uint max = out->size();
     for (uint j = 0; j < max; j++) {// For all users
       Node *use = out->pop();
-      Block *buse = bbs[use->_idx];
+      Block *buse = cfg->get_block_for_node(use);
       if( use->is_Phi() ) {
         for( uint k = 1; k < use->req(); k++ )
           if( use->in(k) == n ) {
-            Node *fixup = catch_cleanup_find_cloned_def(bbs[buse->pred(k)->_idx], n, this, bbs, n_clone_idx);
+            Block* block = cfg->get_block_for_node(buse->pred(k));
+            Node *fixup = catch_cleanup_find_cloned_def(block, n, this, cfg, n_clone_idx);
             use->set_req(k, fixup);
           }
       } else {
         if (this == buse) {
           catch_cleanup_intra_block(use, n, this, beg, n_clone_idx);
         } else {
-          catch_cleanup_inter_block(use, buse, n, this, bbs, n_clone_idx);
+          catch_cleanup_inter_block(use, buse, n, this, cfg, n_clone_idx);
         }
       }
     } // End for all users
--- a/src/share/vm/opto/live.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/live.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -101,7 +101,7 @@
       for( uint k=1; k<cnt; k++ ) {
         Node *nk = n->in(k);
         uint nkidx = nk->_idx;
-        if( _cfg._bbs[nkidx] != b ) {
+        if (_cfg.get_block_for_node(nk) != b) {
           uint u = _names[nkidx];
           use->insert( u );
           DEBUG_ONLY(def_outside->insert( u );)
@@ -121,7 +121,7 @@
 
     // Push these live-in things to predecessors
     for( uint l=1; l<b->num_preds(); l++ ) {
-      Block *p = _cfg._bbs[b->pred(l)->_idx];
+      Block *p = _cfg.get_block_for_node(b->pred(l));
       add_liveout( p, use, first_pass );
 
       // PhiNode uses go in the live-out set of prior blocks.
@@ -142,8 +142,10 @@
       assert( delta->count(), "missing delta set" );
 
       // Add new-live-in to predecessors live-out sets
-      for( uint l=1; l<b->num_preds(); l++ )
-        add_liveout( _cfg._bbs[b->pred(l)->_idx], delta, first_pass );
+      for (uint l = 1; l < b->num_preds(); l++) {
+        Block* block = _cfg.get_block_for_node(b->pred(l));
+        add_liveout(block, delta, first_pass);
+      }
 
       freeset(b);
     } // End of while-worklist-not-empty
--- a/src/share/vm/opto/loopTransform.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/loopTransform.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -624,8 +624,6 @@
 }
 
 
-#define MAX_UNROLL 16 // maximum number of unrolls for main loop
-
 //------------------------------policy_unroll----------------------------------
 // Return TRUE or FALSE if the loop should be unrolled or not.  Unroll if
 // the loop is a CountedLoop and the body is small enough.
@@ -642,7 +640,7 @@
   if (cl->trip_count() <= (uint)(cl->is_normal_loop() ? 2 : 1)) return false;
 
   int future_unroll_ct = cl->unrolled_count() * 2;
-  if (future_unroll_ct > MAX_UNROLL) return false;
+  if (future_unroll_ct > LoopMaxUnroll) return false;
 
   // Check for initial stride being a small enough constant
   if (abs(cl->stride_con()) > (1<<2)*future_unroll_ct) return false;
--- a/src/share/vm/opto/node.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/node.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -42,7 +42,6 @@
 class AllocateArrayNode;
 class AllocateNode;
 class Block;
-class Block_Array;
 class BoolNode;
 class BoxLockNode;
 class CMoveNode;
--- a/src/share/vm/opto/output.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/output.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -68,7 +68,6 @@
     return;
   }
   // Make sure I can find the Start Node
-  Block_Array& bbs = _cfg->_bbs;
   Block *entry = _cfg->_blocks[1];
   Block *broot = _cfg->_broot;
 
@@ -77,8 +76,8 @@
   // Replace StartNode with prolog
   MachPrologNode *prolog = new (this) MachPrologNode();
   entry->_nodes.map( 0, prolog );
-  bbs.map( prolog->_idx, entry );
-  bbs.map( start->_idx, NULL ); // start is no longer in any block
+  _cfg->map_node_to_block(prolog, entry);
+  _cfg->unmap_node_from_block(start); // start is no longer in any block
 
   // Virtual methods need an unverified entry point
 
@@ -117,8 +116,7 @@
       if( m->is_Mach() && m->as_Mach()->ideal_Opcode() != Op_Halt ) {
         MachEpilogNode *epilog = new (this) MachEpilogNode(m->as_Mach()->ideal_Opcode() == Op_Return);
         b->add_inst( epilog );
-        bbs.map(epilog->_idx, b);
-        //_regalloc->set_bad(epilog->_idx); // Already initialized this way.
+        _cfg->map_node_to_block(epilog, b);
       }
     }
   }
@@ -252,7 +250,7 @@
         if (insert) {
           Node *zap = call_zap_node(n->as_MachSafePoint(), i);
           b->_nodes.insert( j, zap );
-          _cfg->_bbs.map( zap->_idx, b );
+          _cfg->map_node_to_block(zap, b);
           ++j;
         }
       }
@@ -1237,7 +1235,7 @@
 #ifdef ASSERT
     if (!b->is_connector()) {
       stringStream st;
-      b->dump_head(&_cfg->_bbs, &st);
+      b->dump_head(_cfg, &st);
       MacroAssembler(cb).block_comment(st.as_string());
     }
     jmp_target[i] = 0;
@@ -1313,7 +1311,7 @@
           MachNode *nop = new (this) MachNopNode(nops_cnt);
           b->_nodes.insert(j++, nop);
           last_inst++;
-          _cfg->_bbs.map( nop->_idx, b );
+          _cfg->map_node_to_block(nop, b);
           nop->emit(*cb, _regalloc);
           cb->flush_bundle(true);
           current_offset = cb->insts_size();
@@ -1398,7 +1396,7 @@
               if (needs_padding && replacement->avoid_back_to_back()) {
                 MachNode *nop = new (this) MachNopNode();
                 b->_nodes.insert(j++, nop);
-                _cfg->_bbs.map(nop->_idx, b);
+                _cfg->map_node_to_block(nop, b);
                 last_inst++;
                 nop->emit(*cb, _regalloc);
                 cb->flush_bundle(true);
@@ -1552,7 +1550,7 @@
       if( padding > 0 ) {
         MachNode *nop = new (this) MachNopNode(padding / nop_size);
         b->_nodes.insert( b->_nodes.size(), nop );
-        _cfg->_bbs.map( nop->_idx, b );
+        _cfg->map_node_to_block(nop, b);
         nop->emit(*cb, _regalloc);
         current_offset = cb->insts_size();
       }
@@ -1740,7 +1738,6 @@
 Scheduling::Scheduling(Arena *arena, Compile &compile)
   : _arena(arena),
     _cfg(compile.cfg()),
-    _bbs(compile.cfg()->_bbs),
     _regalloc(compile.regalloc()),
     _reg_node(arena),
     _bundle_instr_count(0),
@@ -2088,8 +2085,9 @@
     if( def->is_Proj() )        // If this is a machine projection, then
       def = def->in(0);         // propagate usage thru to the base instruction
 
-    if( _bbs[def->_idx] != bb ) // Ignore if not block-local
+    if(_cfg->get_block_for_node(def) != bb) { // Ignore if not block-local
       continue;
+    }
 
     // Compute the latency
     uint l = _bundle_cycle_number + n->latency(i);
@@ -2361,9 +2359,10 @@
       Node *inp = n->in(k);
       if (!inp) continue;
       assert(inp != n, "no cycles allowed" );
-      if( _bbs[inp->_idx] == bb ) { // Block-local use?
-        if( inp->is_Proj() )    // Skip through Proj's
+      if (_cfg->get_block_for_node(inp) == bb) { // Block-local use?
+        if (inp->is_Proj()) { // Skip through Proj's
           inp = inp->in(0);
+        }
         ++_uses[inp->_idx];     // Count 1 block-local use
       }
     }
@@ -2646,7 +2645,7 @@
     return;
 
   Node *pinch = _reg_node[def_reg]; // Get pinch point
-  if( !pinch || _bbs[pinch->_idx] != b || // No pinch-point yet?
+  if ((pinch == NULL) || _cfg->get_block_for_node(pinch) != b || // No pinch-point yet?
       is_def ) {    // Check for a true def (not a kill)
     _reg_node.map(def_reg,def); // Record def/kill as the optimistic pinch-point
     return;
@@ -2672,7 +2671,7 @@
       _cfg->C->record_method_not_compilable("too many D-U pinch points");
       return;
     }
-    _bbs.map(pinch->_idx,b);      // Pretend it's valid in this block (lazy init)
+    _cfg->map_node_to_block(pinch, b);      // Pretend it's valid in this block (lazy init)
     _reg_node.map(def_reg,pinch); // Record pinch-point
     //_regalloc->set_bad(pinch->_idx); // Already initialized this way.
     if( later_def->outcnt() == 0 || later_def->ideal_reg() == MachProjNode::fat_proj ) { // Distinguish def from kill
@@ -2716,9 +2715,9 @@
     return;
   Node *pinch = _reg_node[use_reg]; // Get pinch point
   // Check for no later def_reg/kill in block
-  if( pinch && _bbs[pinch->_idx] == b &&
+  if ((pinch != NULL) && _cfg->get_block_for_node(pinch) == b &&
       // Use has to be block-local as well
-      _bbs[use->_idx] == b ) {
+      _cfg->get_block_for_node(use) == b) {
     if( pinch->Opcode() == Op_Node && // Real pinch-point (not optimistic?)
         pinch->req() == 1 ) {   // pinch not yet in block?
       pinch->del_req(0);        // yank pointer to later-def, also set flag
@@ -2898,7 +2897,7 @@
     int trace_cnt = 0;
     for (uint k = 0; k < _reg_node.Size(); k++) {
       Node* pinch = _reg_node[k];
-      if (pinch != NULL && pinch->Opcode() == Op_Node &&
+      if ((pinch != NULL) && pinch->Opcode() == Op_Node &&
           // no predecence input edges
           (pinch->req() == pinch->len() || pinch->in(pinch->req()) == NULL) ) {
         cleanup_pinch(pinch);
--- a/src/share/vm/opto/output.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/output.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -96,9 +96,6 @@
   // List of nodes currently available for choosing for scheduling
   Node_List _available;
 
-  // Mapping from node (index) to basic block
-  Block_Array& _bbs;
-
   // For each instruction beginning a bundle, the number of following
   // nodes to be bundled with it.
   Bundle *_node_bundling_base;
--- a/src/share/vm/opto/postaloc.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/postaloc.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -78,11 +78,13 @@
 // Helper function for yank_if_dead
 int PhaseChaitin::yank( Node *old, Block *current_block, Node_List *value, Node_List *regnd ) {
   int blk_adjust=0;
-  Block *oldb = _cfg._bbs[old->_idx];
+  Block *oldb = _cfg.get_block_for_node(old);
   oldb->find_remove(old);
   // Count 1 if deleting an instruction from the current block
-  if( oldb == current_block ) blk_adjust++;
-  _cfg._bbs.map(old->_idx,NULL);
+  if (oldb == current_block) {
+    blk_adjust++;
+  }
+  _cfg.unmap_node_from_block(old);
   OptoReg::Name old_reg = lrgs(_lrg_map.live_range_id(old)).reg();
   if( regnd && (*regnd)[old_reg]==old ) { // Instruction is currently available?
     value->map(old_reg,NULL);  // Yank from value/regnd maps
@@ -433,7 +435,7 @@
     bool missing_some_inputs = false;
     Block *freed = NULL;
     for( j = 1; j < b->num_preds(); j++ ) {
-      Block *pb = _cfg._bbs[b->pred(j)->_idx];
+      Block *pb = _cfg.get_block_for_node(b->pred(j));
       // Remove copies along phi edges
       for( uint k=1; k<phi_dex; k++ )
         elide_copy( b->_nodes[k], j, b, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false );
@@ -478,7 +480,7 @@
     } else {
       if( !freed ) {            // Didn't get a freebie prior block
         // Must clone some data
-        freed = _cfg._bbs[b->pred(1)->_idx];
+        freed = _cfg.get_block_for_node(b->pred(1));
         Node_List &f_value = *blk2value[freed->_pre_order];
         Node_List &f_regnd = *blk2regnd[freed->_pre_order];
         for( uint k = 0; k < (uint)_max_reg; k++ ) {
@@ -488,7 +490,7 @@
       }
       // Merge all inputs together, setting to NULL any conflicts.
       for( j = 1; j < b->num_preds(); j++ ) {
-        Block *pb = _cfg._bbs[b->pred(j)->_idx];
+        Block *pb = _cfg.get_block_for_node(b->pred(j));
         if( pb == freed ) continue; // Did self already via freelist
         Node_List &p_regnd = *blk2regnd[pb->_pre_order];
         for( uint k = 0; k < (uint)_max_reg; k++ ) {
@@ -515,8 +517,9 @@
           u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input
       }
       if( u != NodeSentinel ) {    // Junk Phi.  Remove
-        b->_nodes.remove(j--); phi_dex--;
-        _cfg._bbs.map(phi->_idx,NULL);
+        b->_nodes.remove(j--);
+        phi_dex--;
+        _cfg.unmap_node_from_block(phi);
         phi->replace_by(u);
         phi->disconnect_inputs(NULL, C);
         continue;
--- a/src/share/vm/opto/reg_split.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/opto/reg_split.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -132,7 +132,7 @@
   }
 
   b->_nodes.insert(i,spill);    // Insert node in block
-  _cfg._bbs.map(spill->_idx,b); // Update node->block mapping to reflect
+  _cfg.map_node_to_block(spill,  b); // Update node->block mapping to reflect
   // Adjust the point where we go hi-pressure
   if( i <= b->_ihrp_index ) b->_ihrp_index++;
   if( i <= b->_fhrp_index ) b->_fhrp_index++;
@@ -219,7 +219,7 @@
         use->set_req(useidx, def);
       } else {
         // Block and index where the use occurs.
-        Block *b = _cfg._bbs[use->_idx];
+        Block *b = _cfg.get_block_for_node(use);
         // Put the clone just prior to use
         int bindex = b->find_node(use);
         // DEF is UP, so must copy it DOWN and hook in USE
@@ -270,7 +270,7 @@
   int bindex;
   // Phi input spill-copys belong at the end of the prior block
   if( use->is_Phi() ) {
-    b = _cfg._bbs[b->pred(useidx)->_idx];
+    b = _cfg.get_block_for_node(b->pred(useidx));
     bindex = b->end_idx();
   } else {
     // Put the clone just prior to use
@@ -335,7 +335,7 @@
         continue;
       }
 
-      Block *b_def = _cfg._bbs[def->_idx];
+      Block *b_def = _cfg.get_block_for_node(def);
       int idx_def = b_def->find_node(def);
       Node *in_spill = get_spillcopy_wide( in, def, i );
       if( !in_spill ) return 0; // Bailed out
@@ -589,7 +589,7 @@
         UPblock[slidx] = true;
         // Record following instruction in case 'n' rematerializes and
         // kills flags
-        Block *pred1 = _cfg._bbs[b->pred(1)->_idx];
+        Block *pred1 = _cfg.get_block_for_node(b->pred(1));
         continue;
       }
 
@@ -601,7 +601,7 @@
       // Grab predecessor block header
       n1 = b->pred(1);
       // Grab the appropriate reaching def info for inpidx
-      pred = _cfg._bbs[n1->_idx];
+      pred = _cfg.get_block_for_node(n1);
       pidx = pred->_pre_order;
       Node **Ltmp = Reaches[pidx];
       bool  *Utmp = UP[pidx];
@@ -616,7 +616,7 @@
         // Grab predecessor block headers
         n2 = b->pred(inpidx);
         // Grab the appropriate reaching def info for inpidx
-        pred = _cfg._bbs[n2->_idx];
+        pred = _cfg.get_block_for_node(n2);
         pidx = pred->_pre_order;
         Ltmp = Reaches[pidx];
         Utmp = UP[pidx];
@@ -701,7 +701,7 @@
         // Grab predecessor block header
         n1 = b->pred(1);
         // Grab the appropriate reaching def info for k
-        pred = _cfg._bbs[n1->_idx];
+        pred = _cfg.get_block_for_node(n1);
         pidx = pred->_pre_order;
         Node **Ltmp = Reaches[pidx];
         bool  *Utmp = UP[pidx];
@@ -919,7 +919,7 @@
                 return 0;
               }
               _lrg_map.extend(def->_idx, 0);
-              _cfg._bbs.map(def->_idx,b);
+              _cfg.map_node_to_block(def, b);
               n->set_req(inpidx, def);
               continue;
             }
@@ -1291,7 +1291,7 @@
   for( insidx = 0; insidx < phis->size(); insidx++ ) {
     Node *phi = phis->at(insidx);
     assert(phi->is_Phi(),"This list must only contain Phi Nodes");
-    Block *b = _cfg._bbs[phi->_idx];
+    Block *b = _cfg.get_block_for_node(phi);
     // Grab the live range number
     uint lidx = _lrg_map.find_id(phi);
     uint slidx = lrg2reach[lidx];
@@ -1315,7 +1315,7 @@
     // DEF has the wrong UP/DOWN value.
     for( uint i = 1; i < b->num_preds(); i++ ) {
       // Get predecessor block pre-order number
-      Block *pred = _cfg._bbs[b->pred(i)->_idx];
+      Block *pred = _cfg.get_block_for_node(b->pred(i));
       pidx = pred->_pre_order;
       // Grab reaching def
       Node *def = Reaches[pidx][slidx];
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -3217,15 +3217,6 @@
   JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints();
   jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop);
 
-  if (the_class_oop == Universe::reflect_invoke_cache()->klass()) {
-    // We are redefining java.lang.reflect.Method. Method.invoke() is
-    // cached and users of the cache care about each active version of
-    // the method so we have to track this previous version.
-    // Do this before methods get switched
-    Universe::reflect_invoke_cache()->add_previous_version(
-      the_class->method_with_idnum(Universe::reflect_invoke_cache()->method_idnum()));
-  }
-
   // Deoptimize all compiled code that depends on this class
   flush_dependent_code(the_class, THREAD);
 
--- a/src/share/vm/runtime/arguments.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/runtime/arguments.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -60,6 +60,28 @@
 #define DEFAULT_VENDOR_URL_BUG "http://bugreport.sun.com/bugreport/crash.jsp"
 #define DEFAULT_JAVA_LAUNCHER  "generic"
 
+// Disable options not supported in this release, with a warning if they
+// were explicitly requested on the command-line
+#define UNSUPPORTED_OPTION(opt, description)                    \
+do {                                                            \
+  if (opt) {                                                    \
+    if (FLAG_IS_CMDLINE(opt)) {                                 \
+      warning(description " is disabled in this release.");     \
+    }                                                           \
+    FLAG_SET_DEFAULT(opt, false);                               \
+  }                                                             \
+} while(0)
+
+#define UNSUPPORTED_GC_OPTION(gc)                                     \
+do {                                                                  \
+  if (gc) {                                                           \
+    if (FLAG_IS_CMDLINE(gc)) {                                        \
+      warning(#gc " is not supported in this VM.  Using Serial GC."); \
+    }                                                                 \
+    FLAG_SET_DEFAULT(gc, false);                                      \
+  }                                                                   \
+} while(0)
+
 char**  Arguments::_jvm_flags_array             = NULL;
 int     Arguments::_num_jvm_flags               = 0;
 char**  Arguments::_jvm_args_array              = NULL;
@@ -1900,6 +1922,10 @@
     warning("Using MaxGCMinorPauseMillis as minor pause goal is deprecated"
             "and will likely be removed in future release");
   }
+  if (FLAG_IS_CMDLINE(DefaultMaxRAMFraction)) {
+    warning("DefaultMaxRAMFraction is deprecated and will likely be removed in a future release. "
+        "Use MaxRAMFraction instead.");
+  }
 }
 
 // Check stack pages settings
@@ -3162,14 +3188,17 @@
     FLAG_SET_DEFAULT(UseLargePages, false);
   }
 
-  // Tiered compilation is undefined with C1.
-  TieredCompilation = false;
 #else
   if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) {
     FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1);
   }
 #endif
 
+#ifndef TIERED
+  // Tiered compilation is undefined.
+  UNSUPPORTED_OPTION(TieredCompilation, "TieredCompilation");
+#endif
+
   // If we are running in a headless jre, force java.awt.headless property
   // to be true unless the property has already been set.
   // Also allow the OS environment variable JAVA_AWT_HEADLESS to set headless state.
@@ -3312,29 +3341,6 @@
   }
 }
 
-// Disable options not supported in this release, with a warning if they
-// were explicitly requested on the command-line
-#define UNSUPPORTED_OPTION(opt, description)                    \
-do {                                                            \
-  if (opt) {                                                    \
-    if (FLAG_IS_CMDLINE(opt)) {                                 \
-      warning(description " is disabled in this release.");     \
-    }                                                           \
-    FLAG_SET_DEFAULT(opt, false);                               \
-  }                                                             \
-} while(0)
-
-
-#define UNSUPPORTED_GC_OPTION(gc)                                     \
-do {                                                                  \
-  if (gc) {                                                           \
-    if (FLAG_IS_CMDLINE(gc)) {                                        \
-      warning(#gc " is not supported in this VM.  Using Serial GC."); \
-    }                                                                 \
-    FLAG_SET_DEFAULT(gc, false);                                      \
-  }                                                                   \
-} while(0)
-
 #if !INCLUDE_ALL_GCS
 static void force_serial_gc() {
   FLAG_SET_DEFAULT(UseSerialGC, true);
--- a/src/share/vm/runtime/globals.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/runtime/globals.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1706,6 +1706,9 @@
   product(bool, CMSAbortSemantics, false,                                   \
           "Whether abort-on-overflow semantics is implemented")             \
                                                                             \
+  product(bool, CMSParallelInitialMarkEnabled, true,                        \
+          "Use the parallel initial mark.")                                 \
+                                                                            \
   product(bool, CMSParallelRemarkEnabled, true,                             \
           "Whether parallel remark enabled (only if ParNewGC)")             \
                                                                             \
@@ -1717,6 +1720,14 @@
           "Whether to always record survivor space PLAB bdries"             \
           " (effective only if CMSParallelSurvivorRemarkEnabled)")          \
                                                                             \
+  product(bool, CMSEdenChunksRecordAlways, true,                            \
+          "Whether to always record eden chunks used for "                  \
+          "the parallel initial mark or remark of eden" )                   \
+                                                                            \
+  product(bool, CMSPrintEdenSurvivorChunks, false,                          \
+          "Print the eden and the survivor chunks used for the parallel "   \
+          "initial mark or remark of the eden/survivor spaces")             \
+                                                                            \
   product(bool, CMSConcurrentMTEnabled, true,                               \
           "Whether multi-threaded concurrent work enabled (if ParNewGC)")   \
                                                                             \
--- a/src/share/vm/runtime/gpu.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/runtime/gpu.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -61,12 +61,33 @@
 }
 
 bool gpu::execute_kernel(address kernel, PTXKernelArguments & ptxka, JavaValue& ret) {
-  if (gpu::has_gpu_linkage()) {
-    if (gpu::get_target_il_type() == gpu::PTX) {
-      return (gpu::Ptx::execute_kernel(kernel, ptxka, ret));
+    if (gpu::has_gpu_linkage()) {
+        if (gpu::get_target_il_type() == gpu::PTX) {
+            return (gpu::Ptx::execute_kernel(kernel, ptxka, ret));
+        }
+        // Add kernel execution functionality of other GPUs here
     }
-    // Add kernel execution functionality of other GPUs here
-  }
-  return false;
+    return false;
 }
 
+bool gpu::execute_warp(int dimX, int dimY, int dimZ,
+                       address kernel, PTXKernelArguments & ptxka, JavaValue& ret) {
+    if (gpu::has_gpu_linkage()) {
+        if (gpu::get_target_il_type() == gpu::PTX) {
+            return (gpu::Ptx::execute_warp(dimX, dimY, dimZ, kernel, ptxka, ret));
+        }
+        // Add kernel execution functionality of other GPUs here
+    }
+    return false;
+}
+
+int gpu::available_processors() {
+    if (gpu::has_gpu_linkage()) {
+        if (gpu::get_target_il_type() == gpu::PTX) {
+            return (gpu::Ptx::total_cores());
+        }
+        // Add kernel execution functionality of other GPUs here
+    }
+    return 0;
+}
+
--- a/src/share/vm/runtime/gpu.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/runtime/gpu.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -43,9 +43,14 @@
   static void probe_gpu();
 
   static void initialize_gpu();
+
+  static int available_processors();
   
   static void * generate_kernel(unsigned char *code, int code_len, const char *name);
 
+  static bool execute_warp(int dimX, int dimY, int dimZ,
+                           address kernel, PTXKernelArguments & ptxka, JavaValue & ret);
+
   static bool execute_kernel(address kernel, PTXKernelArguments & ptxka, JavaValue & ret);
 
   static void set_available(bool value) {
--- a/src/share/vm/runtime/thread.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/runtime/thread.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1411,6 +1411,36 @@
 
 // ======= JavaThread ========
 
+#ifdef GRAAL
+
+#if GRAAL_COUNTERS_SIZE > 0
+jlong JavaThread::_graal_old_thread_counters[GRAAL_COUNTERS_SIZE];
+
+bool graal_counters_include(oop threadObj) {
+  return !GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS || threadObj == NULL || threadObj->klass() != SystemDictionary::CompilerThread_klass();
+}
+
+void JavaThread::collect_counters(typeArrayOop array) {
+  MutexLocker tl(Threads_lock);
+  for (int i = 0; i < array->length(); i++) {
+    array->long_at_put(i, _graal_old_thread_counters[i]);
+  }
+  for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
+    if (graal_counters_include(tp->threadObj())) {
+      for (int i = 0; i < array->length(); i++) {
+        array->long_at_put(i, array->long_at(i) + tp->_graal_counters[i]);
+      }
+    }
+  }
+}
+#else
+void JavaThread::collect_counters(typeArrayOop array) {
+  // empty
+}
+#endif // GRAAL_COUNTERS_SIZE > 0
+
+#endif // GRAAL
+
 // A JavaThread is a normal Java thread
 
 void JavaThread::initialize() {
@@ -1449,7 +1479,12 @@
   _stack_guard_state = stack_guard_unused;
 #ifdef GRAAL
   _graal_alternate_call_target = NULL;
-#endif
+#if GRAAL_COUNTERS_SIZE > 0
+  for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) {
+    _graal_counters[i] = 0;
+  }
+#endif // GRAAL_COUNTER_SIZE > 0
+#endif // GRAAL
   _exception_oop = NULL;
   _exception_pc  = 0;
   _exception_handler_pc = 0;
@@ -1638,6 +1673,14 @@
   ThreadSafepointState::destroy(this);
   if (_thread_profiler != NULL) delete _thread_profiler;
   if (_thread_stat != NULL) delete _thread_stat;
+
+#if defined(GRAAL) && (GRAAL_COUNTERS_SIZE > 0)
+  if (graal_counters_include(threadObj())) {
+    for (int i = 0; i < GRAAL_COUNTERS_SIZE; i++) {
+      _graal_old_thread_counters[i] += _graal_counters[i];
+    }
+  }
+#endif
 }
 
 
--- a/src/share/vm/runtime/thread.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/runtime/thread.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -919,7 +919,20 @@
 #ifdef GRAAL
   address   _graal_alternate_call_target;
   address   _graal_implicit_exception_pc;  // pc at which the most recent implicit exception occurred
-#endif
+
+  // number of counters, increase as needed. 0 == disabled
+#define GRAAL_COUNTERS_SIZE (0)
+#define GRAAL_COUNTERS_EXCLUDE_COMPILER_THREADS (true)
+
+#if GRAAL_COUNTERS_SIZE > 0
+  jlong     _graal_counters[GRAAL_COUNTERS_SIZE];
+  static jlong _graal_old_thread_counters[GRAAL_COUNTERS_SIZE];
+#endif // GRAAL_COUNTERS_SIZE > 0
+
+ public:
+  static void collect_counters(typeArrayOop array);
+ private:
+#endif // GRAAL
   StackGuardState        _stack_guard_state;
 
   nmethod*      _scanned_nmethod;  // nmethod being scanned by the sweeper
@@ -1379,7 +1392,12 @@
 #ifdef GRAAL
   static ByteSize graal_alternate_call_target_offset() { return byte_offset_of(JavaThread, _graal_alternate_call_target); }
   static ByteSize graal_implicit_exception_pc_offset() { return byte_offset_of(JavaThread, _graal_implicit_exception_pc); }
-#endif
+#if GRAAL_COUNTERS_SIZE > 0
+  static ByteSize graal_counters_offset()        { return byte_offset_of(JavaThread, _graal_counters      ); }
+#else
+  static ByteSize graal_counters_offset()        { return in_ByteSize(0); }
+#endif // GRAAL_COUNTERS_SIZE > 0
+#endif // GRAAL
   static ByteSize exception_oop_offset()         { return byte_offset_of(JavaThread, _exception_oop       ); }
   static ByteSize exception_pc_offset()          { return byte_offset_of(JavaThread, _exception_pc        ); }
   static ByteSize exception_handler_pc_offset()  { return byte_offset_of(JavaThread, _exception_handler_pc); }
--- a/src/share/vm/runtime/vmStructs.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/runtime/vmStructs.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1098,7 +1098,7 @@
                                                                                                                                      \
   c2_nonstatic_field(PhaseCFG,           _num_blocks,              uint)                                                             \
   c2_nonstatic_field(PhaseCFG,           _blocks,                  Block_List)                                                       \
-  c2_nonstatic_field(PhaseCFG,           _bbs,                     Block_Array)                                                      \
+  c2_nonstatic_field(PhaseCFG,           _node_to_block_mapping,   Block_Array)                                                      \
   c2_nonstatic_field(PhaseCFG,           _broot,                   Block*)                                                           \
                                                                                                                                      \
   c2_nonstatic_field(PhaseRegAlloc,      _node_regs,               OptoRegPair*)                                                     \
--- a/src/share/vm/services/gcNotifier.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/services/gcNotifier.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -211,9 +211,9 @@
     NotificationMark nm(request);
     Handle objGcInfo = createGcInfo(request->gcManager, request->gcStatInfo, THREAD);
 
-    Handle objName = java_lang_String::create_from_platform_dependent_str(request->gcManager->name(), CHECK);
-    Handle objAction = java_lang_String::create_from_platform_dependent_str(request->gcAction, CHECK);
-    Handle objCause = java_lang_String::create_from_platform_dependent_str(request->gcCause, CHECK);
+    Handle objName = java_lang_String::create_from_str(request->gcManager->name(), CHECK);
+    Handle objAction = java_lang_String::create_from_str(request->gcAction, CHECK);
+    Handle objCause = java_lang_String::create_from_str(request->gcCause, CHECK);
 
     Klass* k = Management::sun_management_GarbageCollectorImpl_klass(CHECK);
     instanceKlassHandle gc_mbean_klass(THREAD, k);
--- a/src/share/vm/services/management.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/services/management.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -1831,13 +1831,13 @@
  private:
   objArrayHandle _names_strings;
   char **_names_chars;
-  typeArrayOop _times;
+  typeArrayHandle _times;
   int _names_len;
   int _times_len;
   int _count;
 
  public:
-  ThreadTimesClosure(objArrayHandle names, typeArrayOop times);
+  ThreadTimesClosure(objArrayHandle names, typeArrayHandle times);
   ~ThreadTimesClosure();
   virtual void do_thread(Thread* thread);
   void do_unlocked();
@@ -1845,9 +1845,9 @@
 };
 
 ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,
-                                       typeArrayOop times) {
+                                       typeArrayHandle times) {
   assert(names() != NULL, "names was NULL");
-  assert(times != NULL, "times was NULL");
+  assert(times() != NULL, "times was NULL");
   _names_strings = names;
   _names_len = names->length();
   _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);
@@ -1925,7 +1925,7 @@
   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times));
   typeArrayHandle times_ah(THREAD, ta);
 
-  ThreadTimesClosure ttc(names_ah, times_ah());
+  ThreadTimesClosure ttc(names_ah, times_ah);
   {
     MutexLockerEx ml(Threads_lock);
     Threads::threads_do(&ttc);
--- a/src/share/vm/utilities/debug.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/utilities/debug.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -225,6 +225,22 @@
 
 void warning(const char* format, ...);
 
+#ifdef ASSERT
+// Compile-time asserts.
+template <bool> struct StaticAssert;
+template <> struct StaticAssert<true> {};
+
+// Only StaticAssert<true> is defined, so if cond evaluates to false we get
+// a compile time exception when trying to use StaticAssert<false>.
+#define STATIC_ASSERT(cond)                   \
+  do {                                        \
+    StaticAssert<(cond)> DUMMY_STATIC_ASSERT; \
+    (void)DUMMY_STATIC_ASSERT; /* ignore */   \
+  } while (false)
+#else
+#define STATIC_ASSERT(cond)
+#endif
+
 // out of shared space reporting
 enum SharedSpaceType {
   SharedPermGen,
--- a/src/share/vm/utilities/exceptions.cpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/utilities/exceptions.cpp	Fri Oct 11 17:21:14 2013 +0200
@@ -125,13 +125,13 @@
 }
 
 void Exceptions::_throw(Thread* thread, const char* file, int line, Handle h_exception, const char* message) {
+  ResourceMark rm;
   assert(h_exception() != NULL, "exception should not be NULL");
 
   // tracing (do this up front - so it works during boot strapping)
   if (TraceExceptions) {
     ttyLocker ttyl;
-    ResourceMark rm;
-    tty->print_cr("Exception <%s>%s%s (" INTPTR_FORMAT " ) \n"
+    tty->print_cr("Exception <%s%s%s> (" INTPTR_FORMAT ") \n"
                   "thrown [%s, line %d]\nfor thread " INTPTR_FORMAT,
                   h_exception->print_value_string(),
                   message ? ": " : "", message ? message : "",
@@ -141,7 +141,9 @@
   NOT_PRODUCT(Exceptions::debug_check_abort(h_exception, message));
 
   // Check for special boot-strapping/vm-thread handling
-  if (special_exception(thread, file, line, h_exception)) return;
+  if (special_exception(thread, file, line, h_exception)) {
+    return;
+  }
 
   assert(h_exception->is_a(SystemDictionary::Throwable_klass()), "exception is not a subclass of java/lang/Throwable");
 
@@ -149,7 +151,9 @@
   thread->set_pending_exception(h_exception(), file, line);
 
   // vm log
-  Events::log_exception(thread, "Threw " INTPTR_FORMAT " at %s:%d", (address)h_exception(), file, line);
+  Events::log_exception(thread, "Exception <%s%s%s> (" INTPTR_FORMAT ") thrown at [%s, line %d]",
+                        h_exception->print_value_string(), message ? ": " : "", message ? message : "",
+                        (address)h_exception(), file, line);
 }
 
 
--- a/src/share/vm/utilities/exceptions.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/utilities/exceptions.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -315,6 +315,6 @@
 // which preserves pre-existing exceptions and does not allow new
 // exceptions.
 
-#define EXCEPTION_MARK                           Thread* THREAD; ExceptionMark __em(THREAD);
+#define EXCEPTION_MARK                           Thread* THREAD = NULL; ExceptionMark __em(THREAD);
 
 #endif // SHARE_VM_UTILITIES_EXCEPTIONS_HPP
--- a/src/share/vm/utilities/globalDefinitions.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -410,6 +410,8 @@
   return align_size_down_(size, alignment);
 }
 
+#define is_size_aligned_(size, alignment) ((size) == (align_size_up_(size, alignment)))
+
 // Align objects by rounding up their size, in HeapWord units.
 
 #define align_object_size_(size) align_size_up_(size, MinObjAlignment)
@@ -428,6 +430,10 @@
   return align_size_up(offset, HeapWordsPerLong);
 }
 
+inline void* align_pointer_up(const void* addr, size_t size) {
+  return (void*) align_size_up_((uintptr_t)addr, size);
+}
+
 // Clamp an address to be within a specific page
 // 1. If addr is on the page it is returned as is
 // 2. If addr is above the page_address the start of the *next* page will be returned
@@ -449,32 +455,6 @@
 // The expected size in bytes of a cache line, used to pad data structures.
 #define DEFAULT_CACHE_LINE_SIZE 64
 
-// Bytes needed to pad type to avoid cache-line sharing; alignment should be the
-// expected cache line size (a power of two).  The first addend avoids sharing
-// when the start address is not a multiple of alignment; the second maintains
-// alignment of starting addresses that happen to be a multiple.
-#define PADDING_SIZE(type, alignment)                           \
-  ((alignment) + align_size_up_(sizeof(type), alignment))
-
-// Templates to create a subclass padded to avoid cache line sharing.  These are
-// effective only when applied to derived-most (leaf) classes.
-
-// When no args are passed to the base ctor.
-template <class T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
-class Padded: public T {
-private:
-  char _pad_buf_[PADDING_SIZE(T, alignment)];
-};
-
-// When either 0 or 1 args may be passed to the base ctor.
-template <class T, typename Arg1T, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
-class Padded01: public T {
-public:
-  Padded01(): T() { }
-  Padded01(Arg1T arg1): T(arg1) { }
-private:
-  char _pad_buf_[PADDING_SIZE(T, alignment)];
-};
 
 //----------------------------------------------------------------------------------------------------
 // Utility macros for compilers
--- a/src/share/vm/utilities/taskqueue.hpp	Fri Oct 11 17:14:35 2013 +0200
+++ b/src/share/vm/utilities/taskqueue.hpp	Fri Oct 11 17:21:14 2013 +0200
@@ -395,7 +395,13 @@
 template<class E, MEMFLAGS F, unsigned int N>
 bool GenericTaskQueue<E, F, N>::pop_global(E& t) {
   Age oldAge = _age.get();
-  uint localBot = _bottom;
+  // Architectures with weak memory model require a barrier here
+  // to guarantee that bottom is not older than age,
+  // which is crucial for the correctness of the algorithm.
+#if !(defined SPARC || defined IA32 || defined AMD64)
+  OrderAccess::fence();
+#endif
+  uint localBot = OrderAccess::load_acquire((volatile juint*)&_bottom);
   uint n_elems = size(localBot, oldAge.top());
   if (n_elems == 0) {
     return false;
@@ -644,7 +650,7 @@
 template<class E, MEMFLAGS F, unsigned int N> inline bool
 GenericTaskQueue<E, F, N>::push(E t) {
   uint localBot = _bottom;
-  assert((localBot >= 0) && (localBot < N), "_bottom out of range.");
+  assert(localBot < N, "_bottom out of range.");
   idx_t top = _age.top();
   uint dirty_n_elems = dirty_size(localBot, top);
   assert(dirty_n_elems < N, "n_elems out of range.");
--- a/test/compiler/codecache/CheckUpperLimit.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/codecache/CheckUpperLimit.java	Fri Oct 11 17:21:14 2013 +0200
@@ -35,10 +35,6 @@
     ProcessBuilder pb;
     OutputAnalyzer out;
 
-    pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2048m", "-version");
-    out = new OutputAnalyzer(pb.start());
-    out.shouldHaveExitValue(0);
-
     pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2049m", "-version");
     out = new OutputAnalyzer(pb.start());
     out.shouldContain("Invalid ReservedCodeCacheSize=");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/unsafe/GetUnsafeObjectG1PreBarrier.java	Fri Oct 11 17:21:14 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.
+ */
+
+/*
+ * @test
+ * @bug 8016474
+ * @summary The bug only happens with C1 and G1 using a different ObjectAlignmentInBytes than KlassAlignmentInBytes (which is 8)
+ * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:ObjectAlignmentInBytes=32 GetUnsafeObjectG1PreBarrier
+ */
+
+import java.lang.reflect.Field;
+
+import sun.misc.Unsafe;
+
+public class GetUnsafeObjectG1PreBarrier {
+    private static final Unsafe unsafe;
+    private static final int N = 100_000;
+
+    static {
+        try {
+            Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+            theUnsafe.setAccessible(true);
+            unsafe = (Unsafe) theUnsafe.get(null);
+        } catch (NoSuchFieldException | IllegalAccessException e) {
+            throw new IllegalStateException(e);
+        }
+    }
+
+    public Object a;
+
+    public static void main(String[] args) throws Throwable {
+        new GetUnsafeObjectG1PreBarrier();
+    }
+
+    public GetUnsafeObjectG1PreBarrier() throws Throwable {
+        doit();
+    }
+
+    private void doit() throws Throwable {
+        Field field = GetUnsafeObjectG1PreBarrier.class.getField("a");
+        long fieldOffset = unsafe.objectFieldOffset(field);
+
+        for (int i = 0; i < N; i++) {
+            readField(this, fieldOffset);
+        }
+    }
+
+    private void readField(Object o, long fieldOffset) {
+        unsafe.getObject(o, fieldOffset);
+    }
+}
--- a/test/compiler/whitebox/ClearMethodStateTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/whitebox/ClearMethodStateTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,7 +26,7 @@
  * @library /testlibrary /testlibrary/whitebox
  * @build ClearMethodStateTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ClearMethodStateTest
+ * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* ClearMethodStateTest
  * @summary testing of WB::clearMethodState()
  * @author igor.ignatyev@oracle.com
  */
--- a/test/compiler/whitebox/CompilerWhiteBoxTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/whitebox/CompilerWhiteBoxTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -61,6 +61,9 @@
     /** Value of {@code -XX:TieredStopAtLevel} */
     protected static final int TIERED_STOP_AT_LEVEL
             = Integer.parseInt(getVMOption("TieredStopAtLevel", "0"));
+    /** Flag for verbose output, true if {@code -Dverbose} specified */
+    protected static final boolean IS_VERBOSE
+            = System.getProperty("verbose") != null;
 
     /**
      * Returns value of VM option.
@@ -268,7 +271,9 @@
             }
             result += tmp == null ? 0 : tmp;
         }
-        System.out.println("method was invoked " + count + " times");
+        if (IS_VERBOSE) {
+            System.out.println("method was invoked " + count + " times");
+        }
         return result;
     }
 }
--- a/test/compiler/whitebox/DeoptimizeAllTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/whitebox/DeoptimizeAllTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,7 +26,7 @@
  * @library /testlibrary /testlibrary/whitebox
  * @build DeoptimizeAllTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeAllTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* DeoptimizeAllTest
  * @summary testing of WB::deoptimizeAll()
  * @author igor.ignatyev@oracle.com
  */
--- a/test/compiler/whitebox/DeoptimizeMethodTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/whitebox/DeoptimizeMethodTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,7 +26,7 @@
  * @library /testlibrary /testlibrary/whitebox
  * @build DeoptimizeMethodTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DeoptimizeMethodTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* DeoptimizeMethodTest
  * @summary testing of WB::deoptimizeMethod()
  * @author igor.ignatyev@oracle.com
  */
--- a/test/compiler/whitebox/EnqueueMethodForCompilationTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/whitebox/EnqueueMethodForCompilationTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,7 +26,7 @@
  * @library /testlibrary /testlibrary/whitebox
  * @build EnqueueMethodForCompilationTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI EnqueueMethodForCompilationTest
+ * @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* EnqueueMethodForCompilationTest
  * @summary testing of WB::enqueueMethodForCompilation()
  * @author igor.ignatyev@oracle.com
  */
--- a/test/compiler/whitebox/IsMethodCompilableTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/whitebox/IsMethodCompilableTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,7 +27,7 @@
  * @library /testlibrary /testlibrary/whitebox
  * @build IsMethodCompilableTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI IsMethodCompilableTest
+ * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* IsMethodCompilableTest
  * @summary testing of WB::isMethodCompilable()
  * @author igor.ignatyev@oracle.com
  */
--- a/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/whitebox/MakeMethodNotCompilableTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,7 +27,7 @@
  * @library /testlibrary /testlibrary/whitebox
  * @build MakeMethodNotCompilableTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI MakeMethodNotCompilableTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* MakeMethodNotCompilableTest
  * @summary testing of WB::makeMethodNotCompilable()
  * @author igor.ignatyev@oracle.com
  */
--- a/test/compiler/whitebox/SetDontInlineMethodTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/whitebox/SetDontInlineMethodTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,7 +26,7 @@
  * @library /testlibrary /testlibrary/whitebox
  * @build SetDontInlineMethodTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetDontInlineMethodTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* SetDontInlineMethodTest
  * @summary testing of WB::testSetDontInlineMethod()
  * @author igor.ignatyev@oracle.com
  */
--- a/test/compiler/whitebox/SetForceInlineMethodTest.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/compiler/whitebox/SetForceInlineMethodTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -26,7 +26,7 @@
  * @library /testlibrary /testlibrary/whitebox
  * @build SetForceInlineMethodTest
  * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SetForceInlineMethodTest
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* SetForceInlineMethodTest
  * @summary testing of WB::testSetForceInlineMethod()
  * @author igor.ignatyev@oracle.com
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/arguments/TestG1HeapRegionSize.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,64 @@
+/*
+* 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.
+*/
+
+/*
+ * @test TestG1HeapRegionSize
+ * @key gc
+ * @bug 8021879
+ * @summary Verify that the flag G1HeapRegionSize is updated properly
+ * @run main/othervm -Xmx64m TestG1HeapRegionSize 1048576
+ * @run main/othervm -XX:G1HeapRegionSize=2m -Xmx64m TestG1HeapRegionSize 2097152
+ * @run main/othervm -XX:G1HeapRegionSize=3m -Xmx64m TestG1HeapRegionSize 2097152
+ * @run main/othervm -XX:G1HeapRegionSize=64m -Xmx256m TestG1HeapRegionSize 33554432
+ */
+
+import sun.management.ManagementFactoryHelper;
+import com.sun.management.HotSpotDiagnosticMXBean;
+import com.sun.management.VMOption;
+
+public class TestG1HeapRegionSize {
+
+  public static void main(String[] args) {
+    HotSpotDiagnosticMXBean diagnostic = ManagementFactoryHelper.getDiagnosticMXBean();
+
+    VMOption option = diagnostic.getVMOption("UseG1GC");
+    if (option.getValue().equals("false")) {
+      System.out.println("Skipping this test. It is only a G1 test.");
+      return;
+    }
+
+    String expectedValue = getExpectedValue(args);
+    option = diagnostic.getVMOption("G1HeapRegionSize");
+    if (!expectedValue.equals(option.getValue())) {
+      throw new RuntimeException("Wrong value for G1HeapRegionSize. Expected " + expectedValue + " but got " + option.getValue());
+    }
+  }
+
+  private static String getExpectedValue(String[] args) {
+    if (args.length != 1) {
+      throw new RuntimeException("Wrong number of arguments. Expected 1 but got " + args.length);
+    }
+    return args[0];
+  }
+
+}
--- a/test/gc/g1/TestPrintRegionRememberedSetInfo.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/gc/g1/TestPrintRegionRememberedSetInfo.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,7 +27,7 @@
  * @bug 8014240
  * @summary Test output of G1PrintRegionRememberedSetInfo
  * @library /testlibrary
- * @build TestPrintRegionRememberedSetInfo
+ * @run main TestPrintRegionRememberedSetInfo
  * @author thomas.schatzl@oracle.com
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/gc/startup_warnings/TestDefaultMaxRAMFraction.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,44 @@
+/*
+* 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.
+*/
+
+/*
+* @test TestDefaultMaxRAMFraction
+* @key gc
+* @bug 8021967
+* @summary Test that the deprecated TestDefaultMaxRAMFraction flag print a warning message
+* @library /testlibrary
+*/
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class TestDefaultMaxRAMFraction {
+  public static void main(String[] args) throws Exception {
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:DefaultMaxRAMFraction=4", "-version");
+    OutputAnalyzer output = new OutputAnalyzer(pb.start());
+    output.shouldContain("warning: DefaultMaxRAMFraction is deprecated and will likely be removed in a future release. Use MaxRAMFraction instead.");
+    output.shouldNotContain("error");
+    output.shouldHaveExitValue(0);
+  }
+
+}
--- a/test/runtime/6929067/Test6929067.sh	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/runtime/6929067/Test6929067.sh	Fri Oct 11 17:21:14 2013 +0200
@@ -3,6 +3,7 @@
 ##
 ## @test Test6929067.sh
 ## @bug 6929067
+## @bug 8021296
 ## @summary Stack guard pages should be removed when thread is detached
 ## @compile T.java
 ## @run shell Test6929067.sh
@@ -21,6 +22,11 @@
 OS=`uname -s`
 case "$OS" in
   Linux)
+    gcc_cmd=`which gcc`
+    if [ "x$gcc_cmd" == "x" ]; then
+        echo "WARNING: gcc not found. Cannot execute test." 2>&1
+        exit 0;
+    fi
     NULL=/dev/null
     PS=":"
     FS="/"
@@ -119,10 +125,10 @@
 # Check to ensure you have a /usr/lib/libpthread.so if you don't please look
 # for /usr/lib/`uname -m`-linux-gnu version ensure to add that path to below compilation.
 
-gcc -DLINUX ${COMP_FLAG} -o invoke \
-  -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
-  -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
-  -ljvm -lpthread invoke.c
+$gcc_cmd -DLINUX ${COMP_FLAG} -o invoke \
+    -I${COMPILEJAVA}/include -I${COMPILEJAVA}/include/linux \
+    -L${COMPILEJAVA}/jre/lib/${ARCH}/${VMTYPE} \
+    -ljvm -lpthread invoke.c
 
 ./invoke
 exit $?
--- a/test/runtime/7107135/Test7107135.sh	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/runtime/7107135/Test7107135.sh	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,7 @@
 ##
 ## @test Test7107135.sh
 ## @bug 7107135
+## @bug 8021296
 ## @summary Stack guard pages lost after loading library with executable stack.
 ## @run shell Test7107135.sh
 ##
@@ -45,11 +46,13 @@
 case "$OS" in
   Linux)
     echo "Testing on Linux"
+    gcc_cmd=`which gcc`
+    if [ "x$gcc_cmd" == "x" ]; then
+        echo "WARNING: gcc not found. Cannot execute test." 2>&1
+        exit 0;
+    fi
     ;;
   *)
-    NULL=NUL
-    PS=";"
-    FS="\\"
     echo "Test passed; only valid for Linux"
     exit 0;
     ;;
@@ -62,7 +65,10 @@
 cp ${TESTSRC}${FS}*.java ${THIS_DIR}
 ${TESTJAVA}${FS}bin${FS}javac *.java
 
-gcc -fPIC -shared -c -o test.o -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux ${TESTSRC}${FS}test.c
+$gcc_cmd -fPIC -shared -c -o test.o \
+    -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux \
+    ${TESTSRC}${FS}test.c
+
 ld -shared -z   execstack -o libtest-rwx.so test.o
 ld -shared -z noexecstack -o libtest-rw.so  test.o
 
@@ -78,14 +84,16 @@
 
 echo
 echo Test changing of stack protection:
-echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rw
+echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx
 ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} Test test-rwx
+JAVA_RETVAL=$?
 
-if [ "$?" == "0" ]
+if [ "$JAVA_RETVAL" == "0" ]
 then
   echo
   echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx
   ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} TestMT test-rwx
+  JAVA_RETVAL=$?
 fi
 
-exit $?
+exit $JAVA_RETVAL
--- a/test/runtime/7196045/Test7196045.java	Fri Oct 11 17:14:35 2013 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +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.
- *
- */
-
-/*
- * @test
- * @bug 7196045
- * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API.
- * @run main/othervm -XX:+UsePerfData Test7196045
- */
-
-import java.lang.management.ManagementFactory;
-import javax.management.JMException;
-import javax.management.MBeanServer;
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-public class Test7196045 {
-
-    public static long duration = 1000 * 60 * 2;
-    private static final String HOTSPOT_INTERNAL = "sun.management:type=HotspotInternal";
-
-    public static void main(String[] args) {
-
-        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-        ObjectName objName= null;
-        try {
-            ObjectName hotspotInternal = new ObjectName(HOTSPOT_INTERNAL);
-            try {
-                server.registerMBean(new sun.management.HotspotInternal(), hotspotInternal);
-            } catch (JMException e) {
-                throw new RuntimeException("HotSpotWatcher: Failed to register the HotspotInternal MBean" + e);
-            }
-            objName= new ObjectName("sun.management:type=HotspotThreading");
-
-        } catch (MalformedObjectNameException e1) {
-            throw new RuntimeException("Bad object name" + e1);
-        }
-
-        long endTime = System.currentTimeMillis() + duration;
-        long i = 0;
-        while (true) {
-            try {
-                server.getAttribute(objName, "InternalThreadCpuTimes");
-            } catch (Exception ex) {
-                System.err.println("Exception while getting attribute: " + ex);
-            }
-            i++;
-            if (i % 10000 == 0) {
-                System.out.println("Successful iterations: " + i);
-            }
-            if (System.currentTimeMillis() > endTime) {
-                break;
-            }
-        }
-        System.out.println("PASSED.");
-    }
-}
--- a/test/runtime/8000968/Test8000968.sh	Fri Oct 11 17:14:35 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.
-#
-
-
-# @test Test8000968.sh
-# @bug 8000968
-# @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
-# @run shell Test8000968.sh
-#
-
-if [ "${TESTJAVA}" = "" ]
-then
-  PARENT=`dirname \`which java\``
-  TESTJAVA=`dirname ${PARENT}`
-  printf "TESTJAVA not set, selecting " ${TESTJAVA}
-  printf "  If this is incorrect, try setting the variable manually.\n"
-fi
-
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  Windows_* )
-    FS="\\"
-    NULL=NUL
-    ;;
-  * )
-    FS="/"
-    NULL=/dev/null
-    ;;
-esac
-
-JAVA=${TESTJAVA}${FS}bin${FS}java
-
-#
-# See if platform has 64 bit java.
-#
-${JAVA} ${TESTVMOPTS} -d64 -version 2>&1 | grep -i "does not support" > ${NULL}
-if [ "$?" != "1" ]
-then
-  printf "Platform is 32 bit, does not support -XX:ObjectAlignmentInBytes= option.\n"
-  printf "Passed.\n"
-  exit 0
-fi
-
-#
-# Test -XX:ObjectAlignmentInBytes with -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops.
-#
-${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=16 -version 2>&1 > ${NULL}
-if [ "$?" != "0" ]
-then
-  printf "FAILED: -XX:ObjectAlignmentInBytes=16 option did not work.\n"
-  exit 1
-fi
-
-${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=32 -version 2>&1 > ${NULL}
-if [ "$?" != "0" ]
-then
-  printf "FAILED: -XX:ObjectAlignmentInBytes=32 option did not work.\n"
-  exit 1
-fi
-
-${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=64 -version 2>&1 > ${NULL}
-if [ "$?" != "0" ]
-then
-  printf "FAILED: -XX:ObjectAlignmentInBytes=64 option did not work.\n"
-  exit 1
-fi
-
-${JAVA} ${TESTVMOPTS} -d64 -XX:+UseCompressedKlassPointers -XX:+UseCompressedOops -XX:ObjectAlignmentInBytes=128 -version 2>&1 > ${NULL}
-if [ "$?" != "0" ]
-then
-  printf "FAILED: -XX:ObjectAlignmentInBytes=128 option did not work.\n"
-  exit 1
-fi
-
-
-printf "Passed.\n"
-exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/CompressedOops/CompressedKlassPointerAndOops.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8000968
+ * @key regression
+ * @summary NPG: UseCompressedKlassPointers asserts with ObjectAlignmentInBytes=32
+ * @library /testlibrary
+ */
+
+import com.oracle.java.testlibrary.*;
+
+public class CompressedKlassPointerAndOops {
+
+    public static void main(String[] args) throws Exception {
+
+        if (!Platform.is64bit()) {
+            // Can't test this on 32 bit, just pass
+            System.out.println("Skipping test on 32bit");
+            return;
+        }
+
+        runWithAlignment(16);
+        runWithAlignment(32);
+        runWithAlignment(64);
+        runWithAlignment(128);
+    }
+
+    private static void runWithAlignment(int alignment) throws Exception {
+        ProcessBuilder pb;
+        OutputAnalyzer output;
+
+        pb = ProcessTools.createJavaProcessBuilder(
+            "-XX:+UseCompressedKlassPointers",
+            "-XX:+UseCompressedOops",
+            "-XX:ObjectAlignmentInBytes=" + alignment,
+            "-version");
+
+        output = new OutputAnalyzer(pb.start());
+        output.shouldHaveExitValue(0);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/InternalApi/ThreadCpuTimesDeadlock.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+/*
+ * @test
+ * @bug 7196045
+ * @bug 8014294
+ * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API.
+ * @run main/othervm -XX:+UsePerfData -Xmx32m ThreadCpuTimesDeadlock
+ */
+
+import java.lang.management.ManagementFactory;
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+public class ThreadCpuTimesDeadlock {
+
+    public static byte[] dummy;
+    public static long duration = 10 * 1000;
+    private static final String HOTSPOT_INTERNAL = "sun.management:type=HotspotInternal";
+
+    public static void main(String[] args) {
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        ObjectName objName= null;
+        try {
+            ObjectName hotspotInternal = new ObjectName(HOTSPOT_INTERNAL);
+            try {
+                server.registerMBean(new sun.management.HotspotInternal(), hotspotInternal);
+            } catch (JMException e) {
+                throw new RuntimeException("HotSpotWatcher: Failed to register the HotspotInternal MBean" + e);
+            }
+            objName= new ObjectName("sun.management:type=HotspotThreading");
+
+        } catch (MalformedObjectNameException e1) {
+            throw new RuntimeException("Bad object name" + e1);
+        }
+
+        // Thread that allocs memory to generate GC's
+        Thread allocThread = new Thread() {
+          public void run() {
+            while (true) {
+              dummy = new byte[4096];
+            }
+          }
+        };
+
+        allocThread.setDaemon(true);
+        allocThread.start();
+
+        long endTime = System.currentTimeMillis() + duration;
+        long i = 0;
+        while (true) {
+            try {
+                server.getAttribute(objName, "InternalThreadCpuTimes");
+            } catch (Exception ex) {
+                System.err.println("Exception while getting attribute: " + ex);
+            }
+            i++;
+            if (i % 10000 == 0) {
+                System.out.println("Successful iterations: " + i);
+            }
+            if (System.currentTimeMillis() > endTime) {
+                break;
+            }
+        }
+        System.out.println("PASSED.");
+    }
+}
--- a/test/runtime/RedefineObject/Agent.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/runtime/RedefineObject/Agent.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -22,6 +22,7 @@
  */
 import java.security.*;
 import java.lang.instrument.*;
+import java.lang.reflect.*;
 
 public class Agent implements ClassFileTransformer {
     public synchronized byte[] transform(final ClassLoader classLoader,
@@ -29,22 +30,34 @@
                                          Class<?> classBeingRedefined,
                                          ProtectionDomain protectionDomain,
                                          byte[] classfileBuffer) {
-        //System.out.println("Transforming class " + className);
+        System.out.println("Transforming class " + className);
         return classfileBuffer;
     }
 
+    public static void redefine(String agentArgs, Instrumentation instrumentation, Class to_redefine) {
+
+        try {
+            instrumentation.retransformClasses(to_redefine);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
     public static void premain(String agentArgs, Instrumentation instrumentation) {
-
         Agent transformer = new Agent();
-
         instrumentation.addTransformer(transformer, true);
 
-        Class c = Object.class;
-        try {
-            instrumentation.retransformClasses(c);
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
+        // Redefine java/lang/Object and java/lang/reflect/Method.invoke and
+        // java/lang/ClassLoader
+        Class object_class = Object.class;
+        redefine(agentArgs, instrumentation, object_class);
+
+        Class method_class = Method.class;
+        redefine(agentArgs, instrumentation, method_class);
+
+        Class loader_class = ClassLoader.class;
+        redefine(agentArgs, instrumentation, loader_class);
 
         instrumentation.removeTransformer(transformer);
     }
@@ -57,5 +70,14 @@
             System.gc();
             ba.clone();
         }
+        try {
+            // Use java/lang/reflect/Method.invoke to call
+            WalkThroughInvoke a = new WalkThroughInvoke();
+            Class aclass = WalkThroughInvoke.class;
+            Method m = aclass.getMethod("stackWalk");
+            m.invoke(a);
+        } catch (Exception x) {
+            x.printStackTrace();
+        }
     }
 }
--- a/test/runtime/RedefineObject/TestRedefineObject.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/runtime/RedefineObject/TestRedefineObject.java	Fri Oct 11 17:21:14 2013 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 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
@@ -26,14 +26,17 @@
 /*
  * Test to redefine java/lang/Object and verify that it doesn't crash on vtable
  * call on basic array type.
+ * Test to redefine java/lang/ClassLoader and java/lang/reflect/Method to make
+ * sure cached versions used afterward are the current version.
  *
  * @test
  * @bug 8005056
+ * @bug 8009728
  * @library /testlibrary
  * @build Agent
  * @run main ClassFileInstaller Agent
  * @run main TestRedefineObject
- * @run main/othervm -javaagent:agent.jar Agent
+ * @run main/othervm -javaagent:agent.jar -XX:TraceRedefineClasses=5 Agent
  */
 public class TestRedefineObject {
     public static void main(String[] args) throws Exception  {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/RedefineObject/WalkThroughInvoke.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+import java.lang.reflect.*;
+
+public class WalkThroughInvoke {
+  public void stackWalk() {
+      try {
+          Class b = Object.class;
+          SecurityManager sm = new SecurityManager();
+          // Walks the stack with Method.invoke in the stack (which is the
+          // purpose of the test) before it gets an AccessControlException.
+          sm.checkMemberAccess(b, Member.DECLARED);
+      } catch (java.security.AccessControlException e) {
+          // Ignoring an 'AccessControlException' exception since
+          // it is expected as part of this test.
+      }
+  }
+};
--- a/test/runtime/jsig/Test8017498.sh	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/runtime/jsig/Test8017498.sh	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,7 @@
 ## @test Test8017498.sh
 ## @bug 8017498
 ## @bug 8020791
+## @bug 8021296
 ## @summary sigaction(sig) results in process hang/timed-out if sig is much greater than SIGRTMAX
 ## @run shell/timeout=30 Test8017498.sh
 ##
@@ -45,6 +46,11 @@
 case "$OS" in
   Linux)
     echo "Testing on Linux"
+    gcc_cmd=`which gcc`
+    if [ "x$gcc_cmd" == "x" ]; then
+        echo "WARNING: gcc not found. Cannot execute test." 2>&1
+        exit 0;
+    fi
     if [ "$VM_BITS" = "64" ]
     then
         MY_LD_PRELOAD=${TESTJAVA}${FS}jre${FS}lib${FS}amd64${FS}libjsig.so
@@ -64,15 +70,11 @@
 cp ${TESTSRC}${FS}*.java ${THIS_DIR}
 ${TESTJAVA}${FS}bin${FS}javac *.java
 
-gcc -DLINUX -fPIC -shared \
+$gcc_cmd -DLINUX -fPIC -shared \
     -o ${TESTSRC}${FS}libTestJNI.so \
     -I${TESTJAVA}${FS}include \
     -I${TESTJAVA}${FS}include${FS}linux \
     ${TESTSRC}${FS}TestJNI.c
-if [ $? != 0 ]
-then
-    echo "WARNING: the gcc command failed." 2>&1
-fi
 
 # run the java test in the background
 cmd="LD_PRELOAD=$MY_LD_PRELOAD \
--- a/test/runtime/jsig/TestJNI.c	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/runtime/jsig/TestJNI.c	Fri Oct 11 17:21:14 2013 +0200
@@ -21,7 +21,6 @@
  * questions.
  */
 
-#define _GNU_SOURCE // for the definition of REG_RIP in ucontext.h
 #include <stdio.h>
 #include <jni.h>
 #include <signal.h>
@@ -32,11 +31,8 @@
 #endif
 
 void sig_handler(int sig, siginfo_t *info, ucontext_t *context) {
-    int thrNum;
 
     printf( " HANDLER (1) " );
-    // Move forward RIP to skip failing instruction
-    context->uc_mcontext.gregs[REG_RIP] += 6;
 }
 
 JNIEXPORT void JNICALL Java_TestJNI_doSomething(JNIEnv *env, jclass klass, jint val) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/OutputAnalyzerReportingTest.java	Fri Oct 11 17:21:14 2013 +0200
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+
+/*
+ * @test
+ * @summary Test the OutputAnalyzer reporting functionality,
+ *     such as printing additional diagnostic info
+ *     (exit code, stdout, stderr, command line, etc.)
+ * @library /testlibrary
+ */
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+
+public class OutputAnalyzerReportingTest {
+
+    public static void main(String[] args) throws Exception {
+        // Create the output analyzer under test
+        String stdout = "aaaaaa";
+        String stderr = "bbbbbb";
+        OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
+
+        // Expected summary values should be the same for all cases,
+        // since the outputAnalyzer object is the same
+        String expectedExitValue = "-1";
+        String expectedSummary =
+                " stdout: [" + stdout + "];\n" +
+                " stderr: [" + stderr + "]\n" +
+                " exitValue = " + expectedExitValue + "\n";
+
+
+        DiagnosticSummaryTestRunner testRunner =
+                new DiagnosticSummaryTestRunner();
+
+        // should have exit value
+        testRunner.init(expectedSummary);
+        int unexpectedExitValue = 2;
+        try {
+            output.shouldHaveExitValue(unexpectedExitValue);
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should not contain
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldNotContain(stdout);
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should contain
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldContain("unexpected-stuff");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should not match
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldNotMatch("[a]");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+        // should match
+        testRunner.init(expectedSummary);
+        try {
+            output.shouldMatch("[qwerty]");
+        } catch (RuntimeException e) { }
+        testRunner.closeAndCheckResults();
+
+    }
+
+    private static class DiagnosticSummaryTestRunner {
+        private ByteArrayOutputStream byteStream =
+                new ByteArrayOutputStream(10000);
+
+        private String expectedSummary = "";
+        private PrintStream errStream;
+
+
+        public void init(String expectedSummary) {
+            this.expectedSummary = expectedSummary;
+            byteStream.reset();
+            errStream = new PrintStream(byteStream);
+            System.setErr(errStream);
+        }
+
+        public void closeAndCheckResults() {
+            // check results
+            errStream.close();
+            String stdErrStr = byteStream.toString();
+            if (!stdErrStr.contains(expectedSummary)) {
+                throw new RuntimeException("The output does not contain "
+                    + "the diagnostic message, or the message is incorrect");
+            }
+        }
+    }
+
+}
--- a/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/testlibrary/com/oracle/java/testlibrary/OutputAnalyzer.java	Fri Oct 11 17:21:14 2013 +0200
@@ -76,7 +76,8 @@
    */
   public void shouldContain(String expectedString) {
     if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) {
-      throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr: [" + stdout + stderr + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr \n");
     }
   }
 
@@ -88,7 +89,8 @@
    */
   public void stdoutShouldContain(String expectedString) {
     if (!stdout.contains(expectedString)) {
-      throw new RuntimeException("'" + expectedString + "' missing from stdout: [" + stdout + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + expectedString + "' missing from stdout \n");
     }
   }
 
@@ -100,7 +102,8 @@
    */
   public void stderrShouldContain(String expectedString) {
     if (!stderr.contains(expectedString)) {
-      throw new RuntimeException("'" + expectedString + "' missing from stderr: [" + stderr + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + expectedString + "' missing from stderr \n");
     }
   }
 
@@ -112,10 +115,12 @@
    */
   public void shouldNotContain(String notExpectedString) {
     if (stdout.contains(notExpectedString)) {
-      throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
     }
     if (stderr.contains(notExpectedString)) {
-      throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
     }
   }
 
@@ -127,7 +132,8 @@
    */
   public void stdoutShouldNotContain(String notExpectedString) {
     if (stdout.contains(notExpectedString)) {
-      throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + notExpectedString + "' found in stdout \n");
     }
   }
 
@@ -139,7 +145,8 @@
    */
   public void stderrShouldNotContain(String notExpectedString) {
     if (stderr.contains(notExpectedString)) {
-      throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
+        reportDiagnosticSummary();
+        throw new RuntimeException("'" + notExpectedString + "' found in stderr \n");
     }
   }
 
@@ -154,9 +161,9 @@
       Matcher stdoutMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       Matcher stderrMatcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (!stdoutMatcher.find() && !stderrMatcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' missing from stdout/stderr: [" + stdout + stderr
-                  + "]\n");
+                + "' missing from stdout/stderr \n");
       }
   }
 
@@ -170,8 +177,9 @@
   public void stdoutShouldMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       if (!matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' missing from stdout: [" + stdout + "]\n");
+                + "' missing from stdout \n");
       }
   }
 
@@ -185,8 +193,9 @@
   public void stderrShouldMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (!matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' missing from stderr: [" + stderr + "]\n");
+                + "' missing from stderr \n");
       }
   }
 
@@ -200,13 +209,15 @@
   public void shouldNotMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       if (matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' found in stdout: [" + stdout + "]\n");
+                  + "' found in stdout \n");
       }
       matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' found in stderr: [" + stderr + "]\n");
+                  + "' found in stderr \n");
       }
   }
 
@@ -220,8 +231,9 @@
   public void stdoutShouldNotMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stdout);
       if (matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' found in stdout: [" + stdout + "]\n");
+                  + "' found in stdout \n");
       }
   }
 
@@ -235,23 +247,45 @@
   public void stderrShouldNotMatch(String pattern) {
       Matcher matcher = Pattern.compile(pattern, Pattern.MULTILINE).matcher(stderr);
       if (matcher.find()) {
+          reportDiagnosticSummary();
           throw new RuntimeException("'" + pattern
-                  + "' found in stderr: [" + stderr + "]\n");
+                  + "' found in stderr \n");
       }
   }
 
   /**
-   * Verifiy the exit value of the process
+   * Verify the exit value of the process
    *
    * @param expectedExitValue Expected exit value from process
    * @throws RuntimeException If the exit value from the process did not match the expected value
    */
   public void shouldHaveExitValue(int expectedExitValue) {
       if (getExitValue() != expectedExitValue) {
-          throw new RuntimeException("Exit value " + getExitValue() + " , expected to get " + expectedExitValue);
+          reportDiagnosticSummary();
+          throw new RuntimeException("Expected to get exit value of ["
+                  + expectedExitValue + "]\n");
       }
   }
 
+
+  /**
+   * Report summary that will help to diagnose the problem
+   * Currently includes:
+   *  - standard input produced by the process under test
+   *  - standard output
+   *  - exit code
+   *  Note: the command line is printed by the ProcessTools
+   */
+    private void reportDiagnosticSummary() {
+        String msg =
+            " stdout: [" + stdout + "];\n" +
+            " stderr: [" + stderr + "]\n" +
+            " exitValue = " + getExitValue() + "\n";
+
+        System.err.println(msg);
+    }
+
+
   /**
    * Get the contents of the output buffer (stdout and stderr)
    *
--- a/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/testlibrary/com/oracle/java/testlibrary/Platform.java	Fri Oct 11 17:21:14 2013 +0200
@@ -27,6 +27,7 @@
   private static final String osName = System.getProperty("os.name");
   private static final String dataModel = System.getProperty("sun.arch.data.model");
   private static final String vmVersion = System.getProperty("java.vm.version");
+  private static final String osArch = System.getProperty("os.arch");
 
   public static boolean is64bit() {
     return dataModel.equals("64");
@@ -59,4 +60,14 @@
   public static String getVMVersion() {
     return vmVersion;
   }
+
+  // Returns true for sparc and sparcv9.
+  public static boolean isSparc() {
+    return osArch.toLowerCase().startsWith("sparc");
+  }
+
+  public static String getOsArch() {
+    return osArch;
+  }
+
 }
--- a/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java	Fri Oct 11 17:14:35 2013 +0200
+++ b/test/testlibrary/com/oracle/java/testlibrary/ProcessTools.java	Fri Oct 11 17:21:14 2013 +0200
@@ -31,6 +31,7 @@
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.List;
 
 import sun.management.VMManagement;
 
@@ -107,6 +108,22 @@
   }
 
   /**
+   * Get the string containing input arguments passed to the VM
+   *
+   * @return arguments
+   */
+  public static String getVmInputArguments() {
+    RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+
+    List<String> args = runtime.getInputArguments();
+    StringBuilder result = new StringBuilder();
+    for (String arg : args)
+        result.append(arg).append(' ');
+
+    return result.toString();
+  }
+
+  /**
    * Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
    *
    * @return String[] with platform specific arguments, empty if there are none
@@ -132,8 +149,13 @@
     Collections.addAll(args, getPlatformSpecificVMArgs());
     Collections.addAll(args, command);
 
+    // Reporting
+    StringBuilder cmdLine = new StringBuilder();
+    for (String cmd : args)
+        cmdLine.append(cmd).append(' ');
+    System.out.println("Command line: [" + cmdLine.toString() + "]");
+
     return new ProcessBuilder(args.toArray(new String[args.size()]));
-
   }
 
 }