changeset 18387:3e5ed05b7e50

Merge.
author Chris Seaton <chris.seaton@oracle.com>
date Sun, 16 Nov 2014 15:48:34 -0800
parents 656331a61829 (current diff) df47f69cda83 (diff)
children c1eeb1658014
files graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java
diffstat 99 files changed, 1299 insertions(+), 593 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG.md	Sun Nov 16 15:44:38 2014 -0800
+++ b/CHANGELOG.md	Sun Nov 16 15:48:34 2014 -0800
@@ -17,6 +17,10 @@
 * Added PrimitiveValueProfile.
 * Added -G:TruffleTimeThreshold=5000 option to defer compilation for call targets
 * Added RootNode#getExecutionContext to identify nodes with languages
+* Removed `FrameTypeConversion` interface and changed the corresponding `FrameDescriptor` constructor to have a default value parameter instead.
+* Removed `CompilerDirectives.unsafeFrameCast` (equivalent to a `(MaterializedFrame)` cast).
+* Added `TruffleRuntime#getCapability` API method.
+* Added `NodeInterface` and allowed child field to be declared with interfaces that extend it.
 * ...
 
 ## Version 0.5
@@ -33,10 +37,6 @@
 * Added `NeverValidAssumption` to complement `AlwaysValidAssumption`.
 * Fixed a bug in `AssumedValue` that may not invalidate correctly.
 * New option, `-G:+/-TruffleCompilationExceptionsAreThrown`, that will throw an `OptimizationFailedException` for compiler errors.
-* Removed `FrameTypeConversion` interface and changed the corresponding `FrameDescriptor` constructor to have a default value parameter instead.
-* Removed `CompilerDirectives.unsafeFrameCast` (equivalent to a `(MaterializedFrame)` cast).
-* Added `TruffleRuntime#getCapability` API method.
-* Added `NodeInterface` and allowed child field to be declared with interfaces that extend it.
 
 ## Version 0.4
 19-Aug-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/shortlog/graal-0.4)
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/MethodUniverse.java	Sun Nov 16 15:48:34 2014 -0800
@@ -42,7 +42,7 @@
                 methods.put(m, method);
             }
             for (Constructor<?> m : c.getDeclaredConstructors()) {
-                constructors.put(m, metaAccess.lookupJavaConstructor(m));
+                constructors.put(m, metaAccess.lookupJavaMethod(m));
             }
         }
     }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaField.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/JavaField.java	Sun Nov 16 15:48:34 2014 -0800
@@ -44,7 +44,9 @@
      * Returns the kind of this field. This is the same as calling {@link #getType}.
      * {@link JavaType#getKind getKind}.
      */
-    Kind getKind();
+    default Kind getKind() {
+        return getType().getKind();
+    }
 
     /**
      * Returns the {@link JavaType} object representing the class or interface that declares this
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/MetaAccessProvider.java	Sun Nov 16 15:48:34 2014 -0800
@@ -53,14 +53,10 @@
     }
 
     /**
-     * Provides the {@link ResolvedJavaMethod} for a {@link Method} obtained via reflection.
+     * Provides the {@link ResolvedJavaMethod} for a {@link Method} or {@link Constructor} obtained
+     * via reflection.
      */
-    ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod);
-
-    /**
-     * Provides the {@link ResolvedJavaMethod} for a {@link Constructor} obtained via reflection.
-     */
-    ResolvedJavaMethod lookupJavaConstructor(Constructor<?> reflectionConstructor);
+    ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod);
 
     /**
      * Provides the {@link ResolvedJavaField} for a {@link Field} obtained via reflection.
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Signature.java	Sun Nov 16 15:48:34 2014 -0800
@@ -59,7 +59,9 @@
      * @param index the index into the parameters, with {@code 0} indicating the first parameter
      * @return the kind of the parameter at the specified position
      */
-    Kind getParameterKind(int index);
+    default Kind getParameterKind(int index) {
+        return getParameterType(index, null).getKind();
+    }
 
     /**
      * Gets the return type of this signature.
@@ -77,16 +79,9 @@
      * Gets the return kind of this signature. This is the same as calling {@link #getReturnType}.
      * {@link JavaType#getKind getKind}.
      */
-    Kind getReturnKind();
-
-    /**
-     * Gets the size, in Java slots, of the parameters to this signature.
-     *
-     * @param withReceiver {@code true} if to add a slot for a receiver object; {@code false} not to
-     *            include the receiver
-     * @return the size of the parameters in slots
-     */
-    int getParameterSlots(boolean withReceiver);
+    default Kind getReturnKind() {
+        return getReturnType(null).getKind();
+    }
 
     /**
      * Gets the <a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.replacements/src/com/oracle/graal/api/replacements/Fold.java	Sun Nov 16 15:48:34 2014 -0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 2014, 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.replacements;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotates a method replaced by a compile-time constant. A (resolved) call to the annotated method
+ * is replaced with a constant obtained by calling the annotated method via reflection.
+ *
+ * All arguments to such a method (including the receiver if applicable) must be compile-time
+ * constants.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Fold {
+}
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineFrameStateBuilder.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineFrameStateBuilder.java	Sun Nov 16 15:48:34 2014 -0800
@@ -32,7 +32,7 @@
 
     public BaselineFrameStateBuilder(ResolvedJavaMethod method) {
         // we always need at least one stack slot (for exceptions)
-        super(method, new Value[method.getMaxLocals()], new Value[Math.max(1, method.getMaxStackSize())], EMPTY_ARRAY);
+        super(method);
     }
 
     protected BaselineFrameStateBuilder(BaselineFrameStateBuilder other) {
@@ -40,8 +40,8 @@
     }
 
     @Override
-    protected Value[] getEmptyArray() {
-        return EMPTY_ARRAY;
+    protected Value[] allocateArray(int length) {
+        return length == 0 ? EMPTY_ARRAY : new Value[length];
     }
 
     @Override
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java	Sun Nov 16 15:48:34 2014 -0800
@@ -272,6 +272,8 @@
     public static final OptionValue<Boolean> OptFoldMemory = new OptionValue<>(false);
     @Option(help = "Allow backend to match complex expressions.")
     public static final OptionValue<Boolean> MatchExpressions = new OptionValue<>(true);
+    @Option(help = "Constant fold final fields with default values.")
+    public static final OptionValue<Boolean> TrustFinalDefaultFields = new OptionValue<>(true);
 
 
     /**
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Context.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/Context.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.common.remote;
 
+import static java.lang.reflect.Modifier.*;
+
 import java.lang.reflect.*;
 import java.nio.*;
 import java.util.*;
@@ -31,6 +33,7 @@
 import com.oracle.graal.api.code.Register.RegisterCategory;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.type.*;
 
 /**
  * Manages a context for replay or remote compilation.
@@ -56,6 +59,30 @@
         this.mode = mode;
     }
 
+    public static <K, V> HashMap<K, V> newMap() {
+        return Context.getCurrent() == null ? new HashMap<>() : new LinkedHashMap<>();
+    }
+
+    public static <K, V> HashMap<K, V> newMap(Map<K, V> m) {
+        return Context.getCurrent() == null ? new HashMap<>(m) : new LinkedHashMap<>(m);
+    }
+
+    public static <K, V> HashMap<K, V> newMap(int initialCapacity) {
+        return Context.getCurrent() == null ? new HashMap<>(initialCapacity) : new LinkedHashMap<>(initialCapacity);
+    }
+
+    public static <K, V> Map<K, V> newIdentityMap() {
+        return Context.getCurrent() == null ? new IdentityHashMap<>() : new LinkedIdentityHashMap<>();
+    }
+
+    public static <K, V> Map<K, V> newIdentityMap(int expectedMaxSize) {
+        return Context.getCurrent() == null ? new IdentityHashMap<>(expectedMaxSize) : new LinkedIdentityHashMap<>();
+    }
+
+    public static <K, V> Map<K, V> newIdentityMap(Map<K, V> m) {
+        return Context.getCurrent() == null ? new IdentityHashMap<>(m) : new LinkedIdentityHashMap<>(m);
+    }
+
     /**
      * Gets a descriptor for the fields in a class that can be used for serialization.
      */
@@ -92,16 +119,10 @@
     ));
     // @formatter:on
 
-    private static void registerStaticField(Class<?> declaringClass, String staticFieldName) {
+    private static void registerSharedGlobal(Class<?> declaringClass, String staticFieldName) {
         try {
-            Field f = declaringClass.getDeclaredField(staticFieldName);
-            assert Modifier.isStatic(f.getModifiers()) : f;
-            assert Modifier.isFinal(f.getModifiers()) : f;
-            assert !f.getType().isPrimitive() : f;
-            f.setAccessible(true);
-            Object obj = f.get(null);
-            Field existing = SpecialStaticFields.put(obj, f);
-            assert existing == null;
+            SharedGlobal global = new SharedGlobal(declaringClass.getDeclaredField(staticFieldName));
+            SharedGlobals.put(global.get(), global);
         } catch (NoSuchFieldException e) {
             // ignore non-existing fields
         } catch (Exception e) {
@@ -109,15 +130,86 @@
         }
     }
 
+    private static void registerSharedGlobals(Class<?> declaringClass, Class<?> staticFieldType) {
+        assert !staticFieldType.isPrimitive();
+        try {
+            for (Field f : declaringClass.getDeclaredFields()) {
+                if (isStatic(f.getModifiers()) && isFinal(f.getModifiers()) && !f.getType().isPrimitive()) {
+                    SharedGlobal global = new SharedGlobal(f);
+                    if (staticFieldType.isAssignableFrom(f.getType())) {
+                        SharedGlobals.put(global.get(), global);
+                    } else {
+                        Class<?> componentType = f.getType().getComponentType();
+                        if (componentType != null && staticFieldType.isAssignableFrom(componentType)) {
+                            Object[] vals = global.get();
+                            for (int i = 0; i < vals.length; i++) {
+                                SharedGlobal g = new SharedGlobal(f, i);
+                                Object obj = g.get();
+                                SharedGlobals.put(obj, g);
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            throw new GraalInternalError(e);
+        }
+    }
+
+    /**
+     * A shared global is a non-primitive value in a static final variable whose identity is
+     * important to the compiler. That is, equality tests against these values are performed with
+     * {@code ==} or these values are keys in identity hash maps.
+     */
+    static class SharedGlobal {
+        final Field staticField;
+        final Integer index;
+
+        public SharedGlobal(Field staticField) {
+            this(staticField, null);
+        }
+
+        public SharedGlobal(Field staticField, Integer index) {
+            int mods = staticField.getModifiers();
+            assert isStatic(mods) && isFinal(mods) && !staticField.getType().isPrimitive() : staticField;
+            staticField.setAccessible(true);
+            this.staticField = staticField;
+            this.index = index;
+        }
+
+        @SuppressWarnings("unchecked")
+        public <T> T get() {
+            try {
+                Object value = staticField.get(null);
+                if (index != null) {
+                    value = ((Object[]) value)[index.intValue()];
+                }
+                return (T) value;
+            } catch (Exception e) {
+                throw new GraalInternalError(e);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String res = staticField.getDeclaringClass().getName() + "." + staticField.getName();
+            if (index != null) {
+                res += "[" + index + "]";
+            }
+            return res;
+        }
+    }
+
     /**
      * Objects that should not be copied but retrieved from final static fields.
      */
-    private static final Map<Object, Field> SpecialStaticFields = new IdentityHashMap<>();
+    private static final Map<Object, SharedGlobal> SharedGlobals = new IdentityHashMap<>();
     static {
-        registerStaticField(ByteOrder.class, "BIG_ENDIAN");
-        registerStaticField(ByteOrder.class, "LITTLE_ENDIAN");
-        registerStaticField(ArrayList.class, "EMPTY_ELEMENTDATA");
-        registerStaticField(ArrayList.class, "DEFAULTCAPACITY_EMPTY_ELEMENTDATA");
+        registerSharedGlobal(ByteOrder.class, "BIG_ENDIAN");
+        registerSharedGlobal(ByteOrder.class, "LITTLE_ENDIAN");
+        registerSharedGlobal(ArrayList.class, "EMPTY_ELEMENTDATA");
+        registerSharedGlobal(ArrayList.class, "DEFAULTCAPACITY_EMPTY_ELEMENTDATA");
+        registerSharedGlobals(StampFactory.class, Stamp.class);
     }
 
     /**
@@ -231,7 +323,7 @@
     private Object copyFieldOrElement(Deque<Object> worklist, Map<Object, Object> copies, Object srcValue) {
         Object dstValue = srcValue;
         if (srcValue != null && !Proxy.isProxyClass(srcValue.getClass())) {
-            if (isAssignableTo(srcValue.getClass(), DontCopyClasses) || SpecialStaticFields.containsKey(srcValue)) {
+            if (isAssignableTo(srcValue.getClass(), DontCopyClasses) || SharedGlobals.containsKey(srcValue)) {
                 pool.put(srcValue, srcValue);
                 return srcValue;
             }
@@ -264,7 +356,7 @@
      * In addition, copies in {@link #pool} are re-used.
      */
     private Object copy(Object root) {
-        assert !(isAssignableTo(root.getClass(), DontCopyClasses) || SpecialStaticFields.containsKey(root));
+        assert !(isAssignableTo(root.getClass(), DontCopyClasses) || SharedGlobals.containsKey(root));
         // System.out.printf("----- %s ------%n", s(obj));
         assert pool.get(root) == null;
         Deque<Object> worklist = new IdentityLinkedList<>();
@@ -313,7 +405,7 @@
             return (T) proxy;
         } else {
             Object value;
-            if (isAssignableTo(obj.getClass(), DontCopyClasses) || SpecialStaticFields.containsKey(obj)) {
+            if (isAssignableTo(obj.getClass(), DontCopyClasses) || SharedGlobals.containsKey(obj)) {
                 value = obj;
             } else {
                 value = pool.get(obj);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/remote/LinkedIdentityHashMap.java	Sun Nov 16 15:48:34 2014 -0800
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.compiler.common.remote;
+
+import java.util.*;
+import java.util.function.*;
+
+import com.oracle.graal.compiler.common.remote.Context.Mode;
+
+/**
+ * A map that combines {@link IdentityHashMap} with {@link LinkedHashMap} for the purpose of
+ * ensuring a deterministic execution order during {@link Mode#Capturing}.
+ */
+final class LinkedIdentityHashMap<K, V> implements Map<K, V> {
+
+    private final LinkedHashMap<Id<K>, V> map;
+
+    public LinkedIdentityHashMap() {
+        map = new LinkedHashMap<>();
+    }
+
+    public LinkedIdentityHashMap(Map<K, V> m) {
+        map = new LinkedHashMap<>(m.size());
+        putAll(m);
+    }
+
+    public LinkedIdentityHashMap(int expectedMaxSize) {
+        map = new LinkedHashMap<>(expectedMaxSize);
+    }
+
+    /**
+     * Wrapper for an object that gives uses the object's identity for the purpose of equality
+     * comparisons and computing a hash code.
+     */
+    static final class Id<T> {
+        final T object;
+
+        public Id(T object) {
+            assert object != null;
+            this.object = object;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public boolean equals(Object obj) {
+            return obj instanceof Id && ((Id<T>) obj).object == object;
+        }
+
+        @Override
+        public int hashCode() {
+            return System.identityHashCode(object);
+        }
+    }
+
+    public int size() {
+        return map.size();
+    }
+
+    public boolean isEmpty() {
+        return map.isEmpty();
+    }
+
+    public boolean containsKey(Object key) {
+        return map.containsKey(id(key));
+    }
+
+    @SuppressWarnings("unchecked")
+    private Id<K> id(Object key) {
+        if (key == null) {
+            return null;
+        }
+        return new Id<>((K) key);
+    }
+
+    public boolean containsValue(Object value) {
+        return map.containsValue(value);
+    }
+
+    public V get(Object key) {
+        return map.get(id(key));
+    }
+
+    public V put(K key, V value) {
+        return map.put(id(key), value);
+    }
+
+    public V remove(Object key) {
+        return map.remove(id(key));
+    }
+
+    @SuppressWarnings("unchecked")
+    public void putAll(Map<? extends K, ? extends V> m) {
+        if (m == null) {
+            throw new NullPointerException();
+        }
+        if (m.getClass() == getClass()) {
+            LinkedIdentityHashMap<K, V> that = (LinkedIdentityHashMap<K, V>) m;
+            map.putAll(that.map);
+
+        } else {
+            for (K key : m.keySet()) {
+                map.put(id(key), m.get(key));
+            }
+        }
+    }
+
+    public void clear() {
+        map.clear();
+    }
+
+    final class KeySet extends AbstractSet<K> {
+        @Override
+        public int size() {
+            return map.size();
+        }
+
+        @Override
+        public void clear() {
+            map.clear();
+        }
+
+        @Override
+        public Iterator<K> iterator() {
+            return new Iterator<K>() {
+                final Iterator<Id<K>> i = map.keySet().iterator();
+
+                public boolean hasNext() {
+                    return i.hasNext();
+                }
+
+                public K next() {
+                    return i.next().object;
+                }
+
+                public void remove() {
+                    i.remove();
+                }
+            };
+        }
+
+        @Override
+        public boolean contains(Object o) {
+            return containsKey(o);
+        }
+
+        @Override
+        public boolean remove(Object o) {
+            return LinkedIdentityHashMap.this.remove(o) != null;
+        }
+
+        public Spliterator<K> spliterator() {
+            return Spliterators.spliterator(this, Spliterator.SIZED | Spliterator.ORDERED | Spliterator.DISTINCT);
+        }
+
+        public void forEach(Consumer<? super K> action) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public Set<K> keySet() {
+        return new KeySet();
+    }
+
+    public Collection<V> values() {
+        return map.values();
+    }
+
+    final class EntrySet extends AbstractSet<Map.Entry<K, V>> {
+        @Override
+        public int size() {
+            return map.size();
+        }
+
+        @Override
+        public void clear() {
+            map.clear();
+        }
+
+        @Override
+        public Iterator<Map.Entry<K, V>> iterator() {
+            return new Iterator<Map.Entry<K, V>>() {
+                final Iterator<Map.Entry<Id<K>, V>> i = map.entrySet().iterator();
+
+                public boolean hasNext() {
+                    return i.hasNext();
+                }
+
+                public Map.Entry<K, V> next() {
+                    Map.Entry<Id<K>, V> e = i.next();
+                    return new Map.Entry<K, V>() {
+
+                        public K getKey() {
+                            return e.getKey().object;
+                        }
+
+                        public V getValue() {
+                            return e.getValue();
+                        }
+
+                        public V setValue(V value) {
+                            return e.setValue(value);
+                        }
+                    };
+                }
+
+                public void remove() {
+                    i.remove();
+                }
+            };
+        }
+
+        @Override
+        public boolean contains(Object o) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean remove(Object o) {
+            throw new UnsupportedOperationException();
+        }
+
+        public Spliterator<Map.Entry<K, V>> spliterator() {
+            throw new UnsupportedOperationException();
+        }
+
+        public void forEach(Consumer<? super Map.Entry<K, V>> action) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public Set<Map.Entry<K, V>> entrySet() {
+        return new EntrySet();
+    }
+}
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampProvider.java	Sun Nov 16 15:44:38 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +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.compiler.common.type;
-
-public interface StampProvider {
-
-    Stamp stamp();
-}
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FinalizableSubclassTest.java	Sun Nov 16 15:48:34 2014 -0800
@@ -63,7 +63,7 @@
     private StructuredGraph parseAndProcess(Class<?> cl, Assumptions assumptions) {
         Constructor<?>[] constructors = cl.getConstructors();
         Assert.assertTrue(constructors.length == 1);
-        final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaConstructor(constructors[0]);
+        final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(constructors[0]);
         StructuredGraph graph = new StructuredGraph(javaMethod);
 
         GraphBuilderConfiguration conf = GraphBuilderConfiguration.getSnippetDefault();
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Sun Nov 16 15:48:34 2014 -0800
@@ -676,15 +676,18 @@
     }
 
     /**
-     * Determines if every compilation should also be attempted in a replay {@link Context}.
-     *
-     * <pre>
-     * -Dgraal.testReplay=true
-     * </pre>
+     * Determines if {@linkplain #compile(ResolvedJavaMethod, StructuredGraph) compilation} should
+     * also be attempted in a replay {@link Context} where possible.
      */
     private static final boolean TEST_REPLAY = Boolean.getBoolean("graal.testReplay");
 
     /**
+     * Determines if a {@link #checkCompilationResultsEqual mismatching} replay compilation result
+     * results in a diagnostic message or a test error.
+     */
+    private static final boolean TEST_REPLAY_MISMATCH_IS_FAILURE = Boolean.parseBoolean(System.getProperty("graal.testReplay.strict", "true"));
+
+    /**
      * Directory into which tests can dump content useful in debugging test failures.
      */
     private static final File OUTPUT_DIR = new File(System.getProperty("graal.test.output"), "testOutput");
@@ -699,8 +702,8 @@
         return OUTPUT_DIR;
     }
 
-    protected String dissasembleToFile(CompilationResult original, ResolvedJavaMethod installedCodeOwner, String fileSuffix) {
-        String dis = getCodeCache().disassemble(original, null);
+    protected String dissasembleToFile(CompilationResult result, ResolvedJavaMethod installedCodeOwner, String fileSuffix) {
+        String dis = getCodeCache().disassemble(result, null);
         File disFile = new File(getOutputDir(), installedCodeOwner.format("%H.%n_%p").replace(", ", "__") + "." + fileSuffix);
         try (PrintStream ps = new PrintStream(new FileOutputStream(disFile))) {
             ps.println(dis);
@@ -710,60 +713,51 @@
         }
     }
 
-    protected void assertCompilationResultsEqual(Context c, String prefix, CompilationResult original, CompilationResult derived, ResolvedJavaMethod installedCodeOwner) {
-        if (!derived.equals(original)) {
-            Mode mode = c.getMode();
-            // Temporarily force capturing mode as dumping/printing/disassembling
+    protected void checkCompilationResultsEqual(CompilationResult expected, CompilationResult actual, ResolvedJavaMethod installedCodeOwner) {
+        if (!actual.equals(expected)) {
+            // Reset to capturing mode as dumping/printing/disassembling
             // may need to execute proxy methods that have not yet been executed
-            c.setMode(Mode.Capturing);
-            try {
-                String originalDisFile = dissasembleToFile(original, installedCodeOwner, "original");
-                String derivedDisFile = dissasembleToFile(derived, installedCodeOwner, "derived");
-                String message = String.format("%s compilation result differs from original compilation result", prefix);
-                if (originalDisFile != null && derivedDisFile != null) {
-                    message += String.format(" [diff %s %s]", originalDisFile, derivedDisFile);
-                }
+            String expectedDisFile = dissasembleToFile(expected, installedCodeOwner, "expected");
+            String actualDisFile = dissasembleToFile(actual, installedCodeOwner, "actual");
+            String message = "Reply compilation result differs from capturing compilation result";
+            if (expectedDisFile != null && actualDisFile != null) {
+                message += String.format(" [diff %s %s]", expectedDisFile, actualDisFile);
+            }
+            if (TEST_REPLAY_MISMATCH_IS_FAILURE) {
                 Assert.fail(message);
-            } finally {
-                c.setMode(mode);
+            } else {
+                System.out.println(message);
             }
         }
     }
 
-    protected void replayCompile(CompilationResult originalResult, ResolvedJavaMethod installedCodeOwner, StructuredGraph graph) {
+    protected CompilationResult recompile(Context c, Mode mode, ResolvedJavaMethod installedCodeOwner) {
+        try (Debug.Scope s = Debug.scope(mode.name(), new DebugDumpScope(mode.name(), true))) {
 
-        StructuredGraph graphToCompile = graph == null ? parseForCompile(installedCodeOwner) : graph;
-        lastCompiledGraph = graphToCompile;
+            StructuredGraph graphToCompile = parseForCompile(installedCodeOwner);
+
+            lastCompiledGraph = graphToCompile;
 
-        CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graphToCompile.method(), false);
+            CallingConvention cc = getCallingConvention(getCodeCache(), Type.JavaCallee, graphToCompile.method(), false);
+            Request<CompilationResult> request = c.get(new GraalCompiler.Request<>(graphToCompile, null, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), null,
+                            getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graphToCompile), getSpeculationLog(), getSuites(), new CompilationResult(),
+                            CompilationResultBuilderFactory.Default));
+            return GraalCompiler.compile(request);
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+    }
+
+    protected void testReplayCompile(ResolvedJavaMethod installedCodeOwner) {
         try (Context c = new Context()) {
-            // Need to use an 'in context' copy of the original result when comparing for
-            // equality against other 'in context' results so that proxies are compared
-            // against proxies
-            CompilationResult originalResultInContext = c.get(originalResult);
 
             // Capturing compilation
-            Request<CompilationResult> capturingRequest = null;
-            try (Debug.Scope s = Debug.scope("CapturingCompiling", new DebugDumpScope("CAPTURE", true))) {
-                capturingRequest = c.get(new GraalCompiler.Request<>(graphToCompile, null, cc, installedCodeOwner, getProviders(), getBackend(), getCodeCache().getTarget(), null,
-                                getDefaultGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graphToCompile), getSpeculationLog(), getSuites(), new CompilationResult(),
-                                CompilationResultBuilderFactory.Default));
-                assertCompilationResultsEqual(c, "Capturing", originalResultInContext, GraalCompiler.compile(capturingRequest), installedCodeOwner);
-            } catch (Throwable e) {
-                throw Debug.handle(e);
-            }
+            CompilationResult expected = recompile(c, Mode.Capturing, installedCodeOwner);
 
             // Replay compilation
-            try (Debug.Scope s = Debug.scope("ReplayCompiling", new DebugDumpScope("REPLAY", true))) {
-                Request<CompilationResult> replyRequest = c.get(new GraalCompiler.Request<>(graphToCompile.copy(), null, cc, capturingRequest.installedCodeOwner, capturingRequest.providers,
-                                capturingRequest.backend, capturingRequest.target, null, capturingRequest.graphBuilderSuite, capturingRequest.optimisticOpts, capturingRequest.profilingInfo,
-                                capturingRequest.speculationLog, capturingRequest.suites, new CompilationResult(), capturingRequest.factory));
-                c.setMode(Mode.Replaying);
+            CompilationResult actual = recompile(c, Mode.Replaying, installedCodeOwner);
 
-                assertCompilationResultsEqual(c, "Replay", originalResultInContext, GraalCompiler.compile(replyRequest), installedCodeOwner);
-            } catch (Throwable e) {
-                throw Debug.handle(e);
-            }
+            checkCompilationResultsEqual(expected, actual, installedCodeOwner);
         }
     }
 
@@ -783,7 +777,7 @@
                         OptimisticOptimizations.ALL, getProfilingInfo(graphToCompile), getSpeculationLog(), getSuites(), new CompilationResult(), CompilationResultBuilderFactory.Default);
 
         if (TEST_REPLAY && graph == null) {
-            replayCompile(res, installedCodeOwner, null);
+            testReplayCompile(installedCodeOwner);
         }
         return res;
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/DebugInfoBuilder.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.gen;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 import java.util.Map.Entry;
 
@@ -49,8 +47,8 @@
         this.nodeOperands = nodeOperands;
     }
 
-    protected final Map<VirtualObjectNode, VirtualObject> virtualObjects = new HashMap<>();
-    protected final Map<VirtualObjectNode, EscapeObjectState> objectStates = newNodeIdentityMap();
+    protected final Map<VirtualObjectNode, VirtualObject> virtualObjects = Node.newMap();
+    protected final Map<VirtualObjectNode, EscapeObjectState> objectStates = Node.newIdentityMap();
 
     public LIRFrameState build(FrameState topState, LabelRef exceptionEdge) {
         assert virtualObjects.size() == 0;
@@ -79,7 +77,7 @@
             boolean changed;
             do {
                 changed = false;
-                Map<VirtualObjectNode, VirtualObject> virtualObjectsCopy = newIdentityMap(virtualObjects);
+                Map<VirtualObjectNode, VirtualObject> virtualObjectsCopy = Node.newIdentityMap(virtualObjects);
                 for (Entry<VirtualObjectNode, VirtualObject> entry : virtualObjectsCopy.entrySet()) {
                     if (entry.getValue().getValues() == null) {
                         VirtualObjectNode vobj = entry.getKey();
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java	Sun Nov 16 15:48:34 2014 -0800
@@ -332,7 +332,7 @@
 
         for (ParameterNode param : graph.getNodes(ParameterNode.class)) {
             Value paramValue = params[param.index()];
-            assert paramValue.getKind() == param.getKind().getStackKind();
+            assert paramValue.getLIRKind().equals(getLIRGeneratorTool().getLIRKind(param.stamp()));
             setResult(param, gen.emitMove(paramValue));
         }
     }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Node.java	Sun Nov 16 15:48:34 2014 -0800
@@ -31,13 +31,14 @@
 import sun.misc.*;
 
 import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.remote.*;
 import com.oracle.graal.graph.Graph.NodeEventListener;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodeinfo.*;
 
 /**
- * This class is the base class for all nodes, it represent a node which can be inserted in a
+ * This class is the base class for all nodes. It represents a node that can be inserted in a
  * {@link Graph}.
  * <p>
  * Once a node has been added to a graph, it has a graph-unique {@link #id()}. Edges in the
@@ -48,6 +49,21 @@
  * <p>
  * Nodes which are be value numberable should implement the {@link ValueNumberable} interface.
  *
+ * <h1>Replay Compilation</h1>
+ *
+ * To enable deterministic replay compilation, node sets and node maps should be instantiated with
+ * the following methods:
+ * <ul>
+ * <li>{@link #newSet()}</li>
+ * <li>{@link #newSet(Collection)}</li>
+ * <li>{@link #newMap()}</li>
+ * <li>{@link #newMap(int)}</li>
+ * <li>{@link #newMap(Map)}</li>
+ * <li>{@link #newIdentityMap()}</li>
+ * <li>{@link #newIdentityMap(int)}</li>
+ * <li>{@link #newIdentityMap(Map)}</li>
+ * </ul>
+ *
  * <h1>Assertions and Verification</h1>
  *
  * The Node class supplies the {@link #assertTrue(boolean, String, Object...)} and
@@ -193,6 +209,59 @@
     }
 
     /**
+     * Creates a {@link Node} set. If the current thread has a non-null
+     * {@linkplain Context#getCurrent() compilation replay scope}, the returned set will have a
+     * deterministic iteration order determined by the order in which elements are inserted in the
+     * map.
+     */
+    public static <E extends Node> Set<E> newSet() {
+        return Context.getCurrent() == null ? new HashSet<>() : new LinkedHashSet<>();
+    }
+
+    /**
+     * @see #newSet()
+     */
+    public static <E extends Node> Set<E> newSet(Collection<? extends E> c) {
+        return Context.getCurrent() == null ? new HashSet<>(c) : new LinkedHashSet<>(c);
+    }
+
+    public static <K extends Node, V> Map<K, V> newMap() {
+        // Node.equals() and Node.hashCode() are final and are implemented
+        // purely in terms of identity so HashMap and IdentityHashMap with
+        // Node's as keys will behave the same. We choose to use the latter
+        // due to its lighter memory footprint.
+        return newIdentityMap();
+    }
+
+    public static <K extends Node, V> Map<K, V> newMap(Map<K, V> m) {
+        // Node.equals() and Node.hashCode() are final and are implemented
+        // purely in terms of identity so HashMap and IdentityHashMap with
+        // Node's as keys will behave the same. We choose to use the latter
+        // due to its lighter memory footprint.
+        return newIdentityMap(m);
+    }
+
+    public static <K extends Node, V> Map<K, V> newMap(int expectedMaxSize) {
+        // Node.equals() and Node.hashCode() are final and are implemented
+        // purely in terms of identity so HashMap and IdentityHashMap with
+        // Node's as keys will behave the same. We choose to use the latter
+        // due to its lighter memory footprint.
+        return newIdentityMap(expectedMaxSize);
+    }
+
+    public static <K extends Node, V> Map<K, V> newIdentityMap() {
+        return Context.newIdentityMap();
+    }
+
+    public static <K extends Node, V> Map<K, V> newIdentityMap(Map<K, V> m) {
+        return Context.newIdentityMap(m);
+    }
+
+    public static <K extends Node, V> Map<K, V> newIdentityMap(int expectedMaxSize) {
+        return Context.newIdentityMap(expectedMaxSize);
+    }
+
+    /**
      * Gets the graph context of this node.
      */
     public Graph graph() {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeClass.java	Sun Nov 16 15:48:34 2014 -0800
@@ -26,7 +26,6 @@
 import static com.oracle.graal.graph.Edges.*;
 import static com.oracle.graal.graph.InputEdges.*;
 import static com.oracle.graal.graph.Node.*;
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotReplacementsImpl.java	Sun Nov 16 15:48:34 2014 -0800
@@ -90,7 +90,7 @@
     }
 
     @Override
-    protected ResolvedJavaMethod registerMethodSubstitution(ClassReplacements cr, Member originalMethod, Method substituteMethod) {
+    protected ResolvedJavaMethod registerMethodSubstitution(ClassReplacements cr, Executable originalMethod, Method substituteMethod) {
         // TODO: decide if we want to override this in any way
         return super.registerMethodSubstitution(cr, originalMethod, substituteMethod);
     }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILHotSpotReplacementsUtil.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILHotSpotReplacementsUtil.java	Sun Nov 16 15:48:34 2014 -0800
@@ -24,10 +24,10 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.replacements.*;
 import com.oracle.graal.nodes.java.*;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
 
 //JaCoCo Exclude
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/ClassSubstitutionsTests.java	Sun Nov 16 15:48:34 2014 -0800
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014, 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.test;
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+
+public class ClassSubstitutionsTests extends GraalCompilerTest {
+
+    public Number instanceField;
+
+    public Object[] arrayField;
+
+    public String[] stringArrayField;
+
+    protected StructuredGraph test(final String snippet) {
+        try (Scope s = Debug.scope("ClassSubstitutionsTest", getMetaAccess().lookupJavaMethod(getMethod(snippet)))) {
+            StructuredGraph graph = parseEager(snippet);
+            compile(graph.method(), graph);
+            assertNotInGraph(graph, Invoke.class);
+            Debug.dump(graph, snippet);
+            return graph;
+        } catch (Throwable e) {
+            throw Debug.handle(e);
+        }
+    }
+
+    protected static StructuredGraph assertNotInGraph(StructuredGraph graph, Class<?> clazz) {
+        for (Node node : graph.getNodes()) {
+            if (clazz.isInstance(node)) {
+                fail(node.toString());
+            }
+        }
+        return graph;
+    }
+
+    public boolean constantIsArray() {
+        return "".getClass().isArray();
+    }
+
+    public boolean constantIsInterface() {
+        return "".getClass().isInterface();
+    }
+
+    public boolean constantIsPrimitive() {
+        return "".getClass().isPrimitive();
+    }
+
+    @Test
+    public void testIsArray() {
+        testConstantReturn("constantIsArray", 0);
+    }
+
+    @Test
+    public void testIsInterface() {
+        testConstantReturn("constantIsInterface", 0);
+    }
+
+    @Test
+    public void testIsPrimitive() {
+        testConstantReturn("constantIsPrimitive", 0);
+    }
+
+    public boolean fieldIsNotArray() {
+        if (instanceField != null) {
+            // The base type of instanceField is not Object or an Interface, so it's provably an
+            // instance type, so isArray will always return false.
+            return instanceField.getClass().isArray();
+        }
+        return false;
+    }
+
+    @Test
+    public void testFieldIsNotArray() {
+        testConstantReturn("fieldIsNotArray", 0);
+    }
+
+    public boolean foldComponentType() {
+        return stringArrayField.getClass().getComponentType() == String.class;
+    }
+
+    @Test
+    public void testFoldComponenetType() {
+        testConstantReturn("foldComponentType", 1);
+    }
+
+    @Ignore("Can't constant fold LoadHubNode == 0 yet")
+    @Test
+    public void testFieldIsArray() {
+        testConstantReturn("fieldIsArray", 1);
+    }
+
+    public boolean fieldIsArray() {
+        if (arrayField != null) {
+            // The base type of arrayField is an array of some sort so isArray will always return
+            // true.
+            return arrayField.getClass().isArray();
+        }
+        return true;
+    }
+
+    private void testConstantReturn(String name, Object value) {
+        StructuredGraph result = test(name);
+        ReturnNode ret = result.getNodes(ReturnNode.class).first();
+        assertDeepEquals(1, result.getNodes(ReturnNode.class).count());
+
+        assertDeepEquals(true, ret.result().isConstant());
+        assertDeepEquals(value, ret.result().asJavaConstant().asBoxedPrimitive());
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java	Sun Nov 16 15:48:34 2014 -0800
@@ -293,7 +293,7 @@
 
                             // Compile each constructor/method in the class.
                             for (Constructor<?> constructor : javaClass.getDeclaredConstructors()) {
-                                HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaConstructor(constructor);
+                                HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(constructor);
                                 if (canBeCompiled(javaMethod, constructor.getModifiers())) {
                                     compileMethod(javaMethod);
                                 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Sun Nov 16 15:48:34 2014 -0800
@@ -48,7 +48,7 @@
     }
 
     @Override
-    protected ResolvedJavaMethod registerMethodSubstitution(ClassReplacements cr, Member originalMethod, Method substituteMethod) {
+    protected ResolvedJavaMethod registerMethodSubstitution(ClassReplacements cr, Executable originalMethod, Method substituteMethod) {
         final Class<?> substituteClass = substituteMethod.getDeclaringClass();
         if (substituteClass.getDeclaringClass() == BoxingSubstitutions.class) {
             if (config.useHeapProfiler) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Sun Nov 16 15:48:34 2014 -0800
@@ -90,21 +90,11 @@
         }
     }
 
-    public ResolvedJavaMethod lookupJavaMethod(Method reflectionMethod) {
+    public ResolvedJavaMethod lookupJavaMethod(Executable reflectionMethod) {
         try {
             Class<?> holder = reflectionMethod.getDeclaringClass();
-            final int slot = reflectionMethodSlot.getInt(reflectionMethod);
-            final long metaspaceMethod = runtime.getCompilerToVM().getMetaspaceMethod(holder, slot);
-            return HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod);
-        } catch (IllegalArgumentException | IllegalAccessException e) {
-            throw new GraalInternalError(e);
-        }
-    }
-
-    public ResolvedJavaMethod lookupJavaConstructor(Constructor<?> reflectionConstructor) {
-        try {
-            Class<?> holder = reflectionConstructor.getDeclaringClass();
-            final int slot = reflectionConstructorSlot.getInt(reflectionConstructor);
+            Field slotField = reflectionMethod instanceof Constructor ? reflectionConstructorSlot : reflectionMethodSlot;
+            final int slot = slotField.getInt(reflectionMethod);
             final long metaspaceMethod = runtime.getCompilerToVM().getMetaspaceMethod(holder, slot);
             return HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod);
         } catch (IllegalArgumentException | IllegalAccessException e) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java	Sun Nov 16 15:48:34 2014 -0800
@@ -23,10 +23,9 @@
 package com.oracle.graal.hotspot.meta;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 
-public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant, Remote, StampProvider {
+public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant, Remote {
 
     boolean isCompressed();
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstantImpl.java	Sun Nov 16 15:48:34 2014 -0800
@@ -25,7 +25,6 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
 
 public final class HotSpotMetaspaceConstantImpl extends PrimitiveConstant implements HotSpotMetaspaceConstant, VMConstant {
@@ -64,13 +63,6 @@
         return super.toString() + "{" + metaspaceObject + (compressed ? ";compressed}" : "}");
     }
 
-    public Stamp stamp() {
-        if (compressed) {
-            return StampFactory.forInteger(32);
-        }
-        return StampFactory.forInteger(64);
-    }
-
     public boolean isCompressed() {
         return compressed;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaFieldImpl.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaFieldImpl.java	Sun Nov 16 15:48:34 2014 -0800
@@ -220,7 +220,7 @@
                 if (isFinal()) {
                     if (isInObject(object)) {
                         JavaConstant value = readValue(receiver);
-                        if (assumeNonStaticFinalFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) {
+                        if (!value.isDefaultForKind() || assumeNonStaticFinalDefaultFieldsAsFinal(object.getClass())) {
                             return value;
                         }
                     }
@@ -274,7 +274,10 @@
         }
     }
 
-    private static boolean assumeNonStaticFinalFieldsAsFinal(Class<?> clazz) {
+    private static boolean assumeNonStaticFinalDefaultFieldsAsFinal(Class<?> clazz) {
+        if (TrustFinalDefaultFields.getValue()) {
+            return true;
+        }
         return clazz == SnippetCounter.class || clazz == NodeClass.class;
     }
 
@@ -298,11 +301,6 @@
     }
 
     @Override
-    public Kind getKind() {
-        return getType().getKind();
-    }
-
-    @Override
     public String getName() {
         return name;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethodImpl.java	Sun Nov 16 15:48:34 2014 -0800
@@ -121,7 +121,7 @@
 
     @Override
     public boolean equals(Object obj) {
-        if (obj instanceof HotSpotResolvedJavaMethod) {
+        if (obj instanceof HotSpotResolvedJavaMethodImpl) {
             HotSpotResolvedJavaMethodImpl that = (HotSpotResolvedJavaMethodImpl) obj;
             return that.metaspaceMethod == metaspaceMethod;
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectTypeImpl.java	Sun Nov 16 15:48:34 2014 -0800
@@ -833,7 +833,7 @@
         Constructor<?>[] constructors = mirror().getDeclaredConstructors();
         ResolvedJavaMethod[] result = new ResolvedJavaMethod[constructors.length];
         for (int i = 0; i < constructors.length; i++) {
-            result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaConstructor(constructors[i]);
+            result[i] = runtime().getHostProviders().getMetaAccess().lookupJavaMethod(constructors[i]);
             assert result[i].isConstructor();
         }
         return result;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSignature.java	Sun Nov 16 15:48:34 2014 -0800
@@ -29,7 +29,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.java.*;
 
 /**
  * Represents a method signature.
@@ -118,15 +117,6 @@
         return Kind.fromTypeString(parameters.get(index));
     }
 
-    @Override
-    public int getParameterSlots(boolean withReceiver) {
-        int argSlots = 0;
-        for (int i = 0; i < getParameterCount(false); i++) {
-            argSlots += HIRFrameStateBuilder.stackSlots(getParameterKind(i));
-        }
-        return argSlots + (withReceiver ? 1 : 0);
-    }
-
     private static boolean checkValidCache(JavaType type, ResolvedJavaType accessingClass) {
         assert accessingClass != null;
         if (!(type instanceof ResolvedJavaType)) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedField.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotUnresolvedField.java	Sun Nov 16 15:48:34 2014 -0800
@@ -47,10 +47,6 @@
         return type;
     }
 
-    public Kind getKind() {
-        return type.getKind();
-    }
-
     public JavaType getDeclaringClass() {
         return holder;
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Sun Nov 16 15:48:34 2014 -0800
@@ -79,7 +79,6 @@
         } else if (c instanceof HotSpotObjectConstant) {
             return ((HotSpotObjectConstant) c).compress();
         } else if (c instanceof HotSpotMetaspaceConstant) {
-            assert ((HotSpotMetaspaceConstant) c).stamp().getStackKind() == Kind.Long;
             return ((HotSpotMetaspaceConstant) c).compress(encoding);
         } else if (c instanceof PrimitiveConstant) {
             assert ((PrimitiveConstant) c).getKind() == Kind.Long;
@@ -95,7 +94,6 @@
         } else if (c instanceof HotSpotObjectConstant) {
             return ((HotSpotObjectConstant) c).uncompress();
         } else if (c instanceof HotSpotMetaspaceConstant) {
-            assert ((HotSpotMetaspaceConstant) c).stamp().getStackKind() == Kind.Int;
             return ((HotSpotMetaspaceConstant) c).uncompress(encoding);
         } else if (c instanceof PrimitiveConstant) {
             assert ((PrimitiveConstant) c).getKind() == Kind.Int;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowPointerStamp.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowPointerStamp.java	Sun Nov 16 15:48:34 2014 -0800
@@ -84,6 +84,7 @@
 
     @Override
     public Stamp constant(Constant c, MetaAccessProvider meta) {
+        assert (c instanceof HotSpotMetaspaceConstantImpl) && ((HotSpotMetaspaceConstantImpl) c).isCompressed();
         return this;
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ArrayCopySnippets.java	Sun Nov 16 15:48:34 2014 -0800
@@ -93,7 +93,7 @@
         UnsafeArrayCopyNode.arraycopy(nonNullSrc, srcPos, nonNullDest, destPos, length, baseKind);
     }
 
-    private static int checkArrayType(Pointer hub) {
+    private static int checkArrayType(TypePointer hub) {
         int layoutHelper = readLayoutHelper(hub);
         if (probability(SLOW_PATH_PROBABILITY, layoutHelper >= 0)) {
             DeoptimizeNode.deopt(DeoptimizationAction.None, DeoptimizationReason.RuntimeConstraint);
@@ -183,9 +183,9 @@
     public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) {
         Object nonNullSrc = guardingNonNull(src);
         Object nonNullDest = guardingNonNull(dest);
-        Pointer srcHub = loadHub(nonNullSrc);
-        Pointer destHub = loadHub(nonNullDest);
-        if (probability(FAST_PATH_PROBABILITY, srcHub.equal(destHub)) && probability(FAST_PATH_PROBABILITY, nonNullSrc != nonNullDest)) {
+        TypePointer srcHub = loadHub(nonNullSrc);
+        TypePointer destHub = loadHub(nonNullDest);
+        if (probability(FAST_PATH_PROBABILITY, Word.equal(srcHub, destHub)) && probability(FAST_PATH_PROBABILITY, nonNullSrc != nonNullDest)) {
             int layoutHelper = checkArrayType(srcHub);
             final boolean isObjectArray = ((layoutHelper & layoutHelperElementTypePrimitiveInPlace()) == 0);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CRC32Substitutions.java	Sun Nov 16 15:48:34 2014 -0800
@@ -33,7 +33,6 @@
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
 
 /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/CipherBlockChainingSubstitutions.java	Sun Nov 16 15:48:34 2014 -0800
@@ -34,7 +34,6 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.extended.*;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
 
 /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java	Sun Nov 16 15:48:34 2014 -0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2014, 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.replacements;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.HeapAccess.BarrierType;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Read Class::_klass to get the hub for a {@link java.lang.Class}. This node mostly exists to
+ * replace _klass._java_mirror._klass with _klass. The constant folding could be handled by
+ * {@link ReadNode#canonicalizeRead(ValueNode, LocationNode, ValueNode, CanonicalizerTool)}.
+ */
+@NodeInfo
+public class ClassGetHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable {
+    @Input protected ValueNode clazz;
+
+    public static ClassGetHubNode create(ValueNode clazz) {
+        return new ClassGetHubNode(clazz);
+    }
+
+    public static ClassGetHubNode create(ValueNode clazz, ValueNode guard) {
+        return new ClassGetHubNode(clazz, guard);
+    }
+
+    protected ClassGetHubNode(ValueNode clazz) {
+        super(StampFactory.forPointer(PointerType.Type), null);
+        this.clazz = clazz;
+    }
+
+    protected ClassGetHubNode(ValueNode clazz, ValueNode guard) {
+        super(StampFactory.forPointer(PointerType.Type), (GuardingNode) guard);
+        this.clazz = clazz;
+    }
+
+    public ValueNode getHub() {
+        return clazz;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (usages().isEmpty()) {
+            return null;
+        } else {
+            if (clazz.isConstant()) {
+                MetaAccessProvider metaAccess = tool.getMetaAccess();
+                if (metaAccess != null) {
+                    HotSpotResolvedJavaType exactType = (HotSpotResolvedJavaType) tool.getConstantReflection().asJavaType(clazz.asJavaConstant());
+                    if (exactType instanceof HotSpotResolvedObjectType) {
+                        HotSpotResolvedObjectType objectType = (HotSpotResolvedObjectType) exactType;
+                        ConstantNode cn = ConstantNode.forConstant(stamp(), objectType.getObjectHub(), metaAccess);
+                        return cn;
+                    } else if (exactType instanceof HotSpotResolvedPrimitiveType) {
+                        /*
+                         * The constant value is null but we don't have a JavaConstant subclass to
+                         * talk about a NULL pointer yet.
+                         */
+                    }
+                }
+            }
+            if (clazz instanceof HubGetClassNode) {
+                // replace _klass._java_mirror._klass -> _klass
+                return ((HubGetClassNode) clazz).getHub();
+            }
+            return this;
+        }
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
+            return;
+        }
+
+        HotSpotVMConfig config = runtime().getConfig();
+        LocationNode location = ConstantLocationNode.create(CLASS_KLASS_LOCATION, getWordKind(), config.klassOffset, graph());
+        assert !clazz.isConstant();
+        FloatingReadNode read = graph().unique(FloatingReadNode.create(clazz, location, null, stamp(), getGuard(), BarrierType.NONE));
+        graph().replaceFloating(this, read);
+    }
+
+    @NodeIntrinsic
+    public static native TypePointer readClass(Class<?> clazz);
+
+    @NodeIntrinsic
+    public static native TypePointer readClass(Class<?> clazz, GuardingNode guard);
+
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassSubstitutions.java	Sun Nov 16 15:48:34 2014 -0800
@@ -40,21 +40,23 @@
 public class ClassSubstitutions {
 
     @MacroSubstitution(macro = ClassGetModifiersNode.class, isStatic = false)
-    @MethodSubstitution(isStatic = false)
+    @MethodSubstitution(isStatic = false, forced = true)
     public static int getModifiers(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset(), CLASS_KLASS_LOCATION);
-        if (klass.equal(0)) {
+        TypePointer klass = ClassGetHubNode.readClass(thisObj);
+        TypePointer zero = Word.unsigned(0).toTypePointer();
+        if (Word.equal(klass, zero)) {
             // Class for primitive type
             return Modifier.ABSTRACT | Modifier.FINAL | Modifier.PUBLIC;
         } else {
-            return klass.readInt(klassModifierFlagsOffset(), KLASS_MODIFIER_FLAGS_LOCATION);
+            return Word.fromTypePointer(klass).readInt(klassModifierFlagsOffset(), KLASS_MODIFIER_FLAGS_LOCATION);
         }
     }
 
+    // This MacroSubstitution should be removed once non-null klass pointers can be optimized
     @MacroSubstitution(macro = ClassIsInterfaceNode.class, isStatic = false)
-    @MethodSubstitution(isStatic = false)
+    @MethodSubstitution(isStatic = false, forced = true)
     public static boolean isInterface(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset(), CLASS_KLASS_LOCATION);
+        Pointer klass = Word.fromTypePointer(ClassGetHubNode.readClass(thisObj));
         if (klass.equal(0)) {
             return false;
         } else {
@@ -63,21 +65,24 @@
         }
     }
 
+    // This MacroSubstitution should be removed once non-null klass pointers can be optimized
     @MacroSubstitution(macro = ClassIsArrayNode.class, isStatic = false)
-    @MethodSubstitution(isStatic = false)
+    @MethodSubstitution(isStatic = false, forced = true)
     public static boolean isArray(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset(), CLASS_KLASS_LOCATION);
+        TypePointer klassPtr = ClassGetHubNode.readClass(thisObj);
+        Pointer klass = Word.fromTypePointer(klassPtr);
         if (klass.equal(0)) {
             return false;
         } else {
-            return klassIsArray(klass);
+            return klassIsArray(klassPtr);
         }
     }
 
+    // This MacroSubstitution should be removed once non-null klass pointers can be optimized
     @MacroSubstitution(macro = ClassIsPrimitiveNode.class, isStatic = false)
-    @MethodSubstitution(isStatic = false)
+    @MethodSubstitution(isStatic = false, forced = true)
     public static boolean isPrimitive(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset(), CLASS_KLASS_LOCATION);
+        Pointer klass = Word.fromTypePointer(ClassGetHubNode.readClass(thisObj));
         return klass.equal(0);
     }
 
@@ -87,11 +92,12 @@
     @MacroSubstitution(macro = ClassGetSuperclassNode.class, isStatic = false)
     @MethodSubstitution(isStatic = false)
     public static Class<?> getSuperclass(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset(), CLASS_KLASS_LOCATION);
+        TypePointer klassPtr = ClassGetHubNode.readClass(thisObj);
+        Pointer klass = Word.fromTypePointer(klassPtr);
         if (klass.notEqual(0)) {
             int accessFlags = klass.readInt(klassAccessFlagsOffset(), KLASS_ACCESS_FLAGS_LOCATION);
             if ((accessFlags & Modifier.INTERFACE) == 0) {
-                if (klassIsArray(klass)) {
+                if (klassIsArray(klassPtr)) {
                     return Object.class;
                 } else {
                     Word superKlass = klass.readWord(klassSuperKlassOffset(), KLASS_SUPER_KLASS_LOCATION);
@@ -109,9 +115,10 @@
     @MacroSubstitution(macro = ClassGetComponentTypeNode.class, isStatic = false)
     @MethodSubstitution(isStatic = false)
     public static Class<?> getComponentType(final Class<?> thisObj) {
-        Word klass = loadWordFromObject(thisObj, klassOffset(), CLASS_KLASS_LOCATION);
+        TypePointer klassPtr = ClassGetHubNode.readClass(thisObj);
+        Pointer klass = Word.fromTypePointer(klassPtr);
         if (klass.notEqual(0)) {
-            if (klassIsArray(klass)) {
+            if (klassIsArray(klassPtr)) {
                 return piCastExactNonNull(klass.readObject(arrayKlassComponentMirrorOffset(), ARRAY_KLASS_COMPONENT_MIRROR), Class.class);
             }
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotNodeSubstitutions.java	Sun Nov 16 15:48:34 2014 -0800
@@ -41,7 +41,7 @@
         // HotSpot creates the NodeClass for each Node subclass while initializing it
         // so we are guaranteed to read a non-null value here. As long as NodeClass
         // is final, the stamp of the PiNode below will automatically be exact.
-        Pointer klass = loadHub(node);
-        return piCastNonNull(klass.readObject(Word.signed(instanceKlassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class);
+        TypePointer klass = loadHub(node);
+        return piCastNonNull(Word.fromTypePointer(klass).readObject(Word.signed(instanceKlassNodeClassOffset()), KLASS_NODE_CLASS), NodeClass.class);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HotSpotReplacementsUtil.java	Sun Nov 16 15:48:34 2014 -0800
@@ -29,13 +29,14 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.replacements.*;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.replacements.nodes.*;
 import com.oracle.graal.word.*;
 
@@ -297,10 +298,18 @@
         return config().klassLayoutHelperOffset;
     }
 
-    public static int readLayoutHelper(Pointer hub) {
-        return hub.readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
+    public static int readLayoutHelper(TypePointer hub) {
+        // return hub.readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
+        GuardingNode anchorNode = SnippetAnchorNode.anchor();
+        return loadKlassLayoutHelperIntrinsic(hub, anchorNode);
     }
 
+    @NodeIntrinsic(value = KlassLayoutHelperNode.class)
+    public static native int loadKlassLayoutHelperIntrinsic(TypePointer object, GuardingNode anchor);
+
+    @NodeIntrinsic(value = KlassLayoutHelperNode.class)
+    public static native int loadKlassLayoutHelperIntrinsic(TypePointer object);
+
     /**
      * Checks if class {@code klass} is an array.
      *
@@ -309,7 +318,7 @@
      * @param klass the class to be checked
      * @return true if klass is an array, false otherwise
      */
-    public static boolean klassIsArray(Word klass) {
+    public static boolean klassIsArray(TypePointer klass) {
         /*
          * The less-than check only works if both values are ints. We use local variables to make
          * sure these are still ints and haven't changed.
@@ -540,8 +549,8 @@
     /**
      * Loads the hub of an object (without null checking it first).
      */
-    public static Pointer loadHub(Object object) {
-        return Word.fromTypePointer(loadHubIntrinsic(object));
+    public static TypePointer loadHub(Object object) {
+        return loadHubIntrinsic(object);
     }
 
     public static Object verifyOop(Object object) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/HubGetClassNode.java	Sun Nov 16 15:48:34 2014 -0800
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2014, 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.replacements;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.HeapAccess.BarrierType;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.word.*;
+
+/**
+ * Read Klass::_java_mirror and incorporate non-null type information into stamp. This is also used
+ * by {@link ClassGetHubNode} to eliminate chains of klass._java_mirror._klass.
+ */
+@NodeInfo
+public class HubGetClassNode extends FloatingGuardedNode implements Lowerable, Canonicalizable {
+    @Input protected ValueNode hub;
+
+    public static HubGetClassNode create(ValueNode hub) {
+        return new HubGetClassNode(hub);
+    }
+
+    protected HubGetClassNode(ValueNode hub) {
+        super(StampFactory.declaredNonNull(runtime().fromClass(Class.class)), null);
+        this.hub = hub;
+    }
+
+    public ValueNode getHub() {
+        return hub;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (usages().isEmpty()) {
+            return null;
+        } else {
+            MetaAccessProvider metaAccess = tool.getMetaAccess();
+            if (metaAccess != null) {
+                if (hub.isConstant()) {
+                    ResolvedJavaType exactType = tool.getConstantReflection().asJavaType(hub.asJavaConstant());
+                    return ConstantNode.forConstant(exactType.getJavaClass(), metaAccess);
+                }
+            }
+            return this;
+        }
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
+            return;
+        }
+
+        HotSpotVMConfig config = runtime().getConfig();
+        LocationNode location = ConstantLocationNode.create(CLASS_MIRROR_LOCATION, Kind.Object, config.classMirrorOffset, graph());
+        assert !hub.isConstant();
+        FloatingReadNode read = graph().unique(FloatingReadNode.create(hub, location, null, stamp(), getGuard(), BarrierType.NONE));
+        graph().replaceFloating(this, read);
+    }
+
+    @NodeIntrinsic
+    public static native Class<?> readClass(TypePointer hub);
+
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java	Sun Nov 16 15:48:34 2014 -0800
@@ -186,7 +186,7 @@
             return falseValue;
         }
         GuardingNode anchorNode = SnippetAnchorNode.anchor();
-        Word hub = loadWordFromObject(mirror, klassOffset(), CLASS_KLASS_LOCATION);
+        Pointer hub = Word.fromTypePointer(ClassGetHubNode.readClass(mirror, anchorNode));
         Pointer objectHub = Word.fromTypePointer(loadHubIntrinsic(object, anchorNode));
         if (hub.equal(0) || !checkUnknownSubType(hub, objectHub)) {
             return falseValue;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/KlassLayoutHelperNode.java	Sun Nov 16 15:48:34 2014 -0800
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2014, 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.replacements;
+
+import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
+import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.spi.*;
+import com.oracle.graal.hotspot.meta.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.HeapAccess.BarrierType;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.spi.*;
+
+/**
+ * Read Klass::_layout_helper and incorporate any useful stamp information based on any type
+ * information in {@code klass}.
+ */
+@NodeInfo
+public class KlassLayoutHelperNode extends FloatingGuardedNode implements Canonicalizable, Lowerable {
+
+    @Input protected ValueNode klass;
+
+    public static KlassLayoutHelperNode create(ValueNode klass) {
+        return new KlassLayoutHelperNode(klass);
+    }
+
+    public static KlassLayoutHelperNode create(ValueNode klass, ValueNode guard) {
+        return new KlassLayoutHelperNode(klass, guard);
+    }
+
+    protected KlassLayoutHelperNode(ValueNode klass) {
+        super(StampFactory.forKind(Kind.Int));
+        this.klass = klass;
+    }
+
+    protected KlassLayoutHelperNode(ValueNode klass, ValueNode guard) {
+        super(StampFactory.forKind(Kind.Int), (GuardingNode) guard);
+        this.klass = klass;
+    }
+
+    @Override
+    public boolean inferStamp() {
+        if (klass instanceof LoadHubNode) {
+            LoadHubNode hub = (LoadHubNode) klass;
+            Stamp hubStamp = hub.getValue().stamp();
+            if (hubStamp instanceof ObjectStamp) {
+                ObjectStamp objectStamp = (ObjectStamp) hubStamp;
+                ResolvedJavaType type = objectStamp.type();
+                if (type != null && !type.isJavaLangObject()) {
+                    if (!type.isArray() && !type.isInterface()) {
+                        /*
+                         * Definitely some form of instance type.
+                         */
+                        return updateStamp(StampFactory.forInteger(Kind.Int, runtime().getConfig().klassLayoutHelperNeutralValue, Integer.MAX_VALUE));
+                    }
+                    if (type.isArray()) {
+                        return updateStamp(StampFactory.forInteger(Kind.Int, Integer.MIN_VALUE, runtime().getConfig().klassLayoutHelperNeutralValue - 1));
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public Node canonical(CanonicalizerTool tool) {
+        if (usages().isEmpty()) {
+            return null;
+        } else {
+            if (klass.isConstant()) {
+                long base = klass.asJavaConstant().asLong();
+                if (base != 0L) {
+                    Constant constant = stamp().readConstant(tool.getConstantReflection(), klass.asJavaConstant(), runtime().getConfig().klassLayoutHelperOffset);
+                    return ConstantNode.forConstant(stamp(), constant, tool.getMetaAccess());
+                }
+            }
+            if (klass instanceof LoadHubNode) {
+                LoadHubNode hub = (LoadHubNode) klass;
+                Stamp hubStamp = hub.getValue().stamp();
+                if (hubStamp instanceof ObjectStamp) {
+                    ObjectStamp ostamp = (ObjectStamp) hubStamp;
+                    HotSpotResolvedObjectType type = (HotSpotResolvedObjectType) ostamp.type();
+                    if (type != null && type.isArray() && !type.getComponentType().isPrimitive()) {
+                        // The layout for all object arrays is the same.
+                        Constant constant = stamp().readConstant(tool.getConstantReflection(), type.klass(), runtime().getConfig().klassLayoutHelperOffset);
+                        return ConstantNode.forConstant(stamp(), constant, tool.getMetaAccess());
+                    }
+                }
+            }
+            return this;
+        }
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
+            return;
+        }
+        LocationNode location = ConstantLocationNode.create(KLASS_LAYOUT_HELPER_LOCATION, Kind.Int, runtime().getConfig().klassLayoutHelperOffset, graph());
+        assert !klass.isConstant();
+        graph().replaceFloating(this, graph().unique(FloatingReadNode.create(klass, location, null, stamp(), getGuard(), BarrierType.NONE)));
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Sun Nov 16 15:48:34 2014 -0800
@@ -34,6 +34,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.graph.iterators.*;
@@ -50,7 +51,6 @@
 import com.oracle.graal.phases.common.inlining.*;
 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;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java	Sun Nov 16 15:48:34 2014 -0800
@@ -33,6 +33,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
@@ -49,7 +50,6 @@
 import com.oracle.graal.options.*;
 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;
@@ -151,10 +151,11 @@
 
     @Snippet
     public static Object allocateInstanceDynamic(Class<?> type, @ConstantParameter boolean fillContents, @ConstantParameter Register threadRegister, @ConstantParameter String typeContext) {
-        Word hub = loadWordFromObject(type, klassOffset(), CLASS_KLASS_LOCATION);
+        TypePointer hubPtr = ClassGetHubNode.readClass(type);
+        Pointer hub = Word.fromTypePointer(hubPtr);
         if (probability(FAST_PATH_PROBABILITY, !hub.equal(Word.zero()))) {
             if (probability(FAST_PATH_PROBABILITY, isInstanceKlassFullyInitialized(hub))) {
-                int layoutHelper = readLayoutHelper(hub);
+                int layoutHelper = readLayoutHelper(hubPtr);
                 /*
                  * src/share/vm/oops/klass.hpp: For instances, layout helper is a positive number,
                  * the instance size. This size is already passed through align_object_size and
@@ -223,7 +224,7 @@
             return dynamicNewArrayStub(DYNAMIC_NEW_ARRAY, elementType, length);
         }
 
-        int layoutHelper = readLayoutHelper(hub);
+        int layoutHelper = readLayoutHelper(hub.toTypePointer());
         //@formatter:off
         // from src/share/vm/oops/klass.hpp:
         //
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectGetClassNode.java	Sun Nov 16 15:44:38 2014 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2013, 2014, 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.replacements;
-
-import static com.oracle.graal.compiler.common.GraalOptions.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.spi.*;
-import com.oracle.graal.nodeinfo.*;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.spi.*;
-import com.oracle.graal.nodes.type.*;
-import com.oracle.graal.replacements.nodes.*;
-
-/**
- * This macro node will replace itself with the correct Java {@link Class} as soon as the object's
- * type is known (exact).
- */
-@NodeInfo
-public class ObjectGetClassNode extends MacroNode implements Virtualizable, Canonicalizable {
-
-    public static ObjectGetClassNode create(Invoke invoke) {
-        return new ObjectGetClassNode(invoke);
-    }
-
-    protected ObjectGetClassNode(Invoke invoke) {
-        super(invoke);
-    }
-
-    private ValueNode getObject() {
-        return arguments.get(0);
-    }
-
-    @Override
-    public void virtualize(VirtualizerTool tool) {
-        if (ImmutableCode.getValue()) {
-            return;
-        }
-        State state = tool.getObjectState(getObject());
-        if (state != null) {
-            JavaConstant clazz = state.getVirtualObject().type().getJavaClass();
-            tool.replaceWithValue(ConstantNode.forConstant(clazz, tool.getMetaAccessProvider(), graph()));
-        }
-    }
-
-    @Override
-    public Node canonical(CanonicalizerTool tool) {
-        if (ImmutableCode.getValue()) {
-            return this;
-        }
-        if (usages().isEmpty()) {
-            return null;
-        } else {
-            ResolvedJavaType type = StampTool.typeOrNull(getObject());
-            if (StampTool.isExactType(getObject())) {
-                JavaConstant clazz = type.getJavaClass();
-                return ConstantNode.forConstant(clazz, tool.getMetaAccess());
-            }
-            if (type != null && tool.assumptions().useOptimisticAssumptions()) {
-                ResolvedJavaType exactType = type.findUniqueConcreteSubtype();
-                if (exactType != null) {
-                    tool.assumptions().recordConcreteSubtype(type, exactType);
-                    JavaConstant clazz = exactType.getJavaClass();
-                    return ConstantNode.forConstant(clazz, tool.getMetaAccess());
-                }
-            }
-            return this;
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectSubstitutions.java	Sun Nov 16 15:48:34 2014 -0800
@@ -23,9 +23,9 @@
 package com.oracle.graal.hotspot.replacements;
 
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
-import static com.oracle.graal.nodes.PiNode.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.word.*;
@@ -36,11 +36,10 @@
 @ClassSubstitution(java.lang.Object.class)
 public class ObjectSubstitutions {
 
-    @MacroSubstitution(macro = ObjectGetClassNode.class, isStatic = false, forced = true)
     @MethodSubstitution(isStatic = false, forced = true)
     public static Class<?> getClass(final Object thisObj) {
-        Pointer hub = loadHub(thisObj);
-        return piCastExactNonNull(hub.readObject(Word.signed(classMirrorOffset()), CLASS_MIRROR_LOCATION), Class.class);
+        TypePointer hub = loadHub(GuardingPiNode.guardingNonNull(thisObj));
+        return HubGetClassNode.readClass(hub);
     }
 
     @MethodSubstitution(isStatic = false)
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/UnsafeArrayCopySnippets.java	Sun Nov 16 15:48:34 2014 -0800
@@ -30,13 +30,13 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.phases.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.replacements.*;
-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;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java	Sun Nov 16 15:48:34 2014 -0800
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
@@ -37,7 +38,6 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
 
 /**
@@ -135,7 +135,7 @@
          * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for
          * total size of the interpreter frames plus shadow page size. Bang one page at a time
          * because large sizes can bang beyond yellow and red zones.
-         * 
+         *
          * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository.
          */
         final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ExceptionHandlerStub.java	Sun Nov 16 15:48:34 2014 -0800
@@ -28,6 +28,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
@@ -36,7 +37,6 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
 
 /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewArrayStub.java	Sun Nov 16 15:48:34 2014 -0800
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
@@ -40,7 +41,6 @@
 import com.oracle.graal.nodes.spi.*;
 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.Arguments;
 import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
 import com.oracle.graal.word.*;
@@ -84,7 +84,7 @@
      */
     @Snippet
     private static Object newArray(TypePointer hub, int length, @ConstantParameter TypePointer intArrayHub, @ConstantParameter Register threadRegister) {
-        int layoutHelper = Word.fromTypePointer(hub).readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
+        int layoutHelper = loadKlassLayoutHelperIntrinsic(hub);
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift()) & layoutHelperLog2ElementSizeMask();
         int headerSize = (layoutHelper >> layoutHelperHeaderSizeShift()) & layoutHelperHeaderSizeMask();
         int elementKind = (layoutHelper >> layoutHelperElementTypeShift()) & layoutHelperElementTypeMask();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java	Sun Nov 16 15:48:34 2014 -0800
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
@@ -40,7 +41,6 @@
 import com.oracle.graal.nodes.spi.*;
 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.Arguments;
 import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo;
 import com.oracle.graal.word.*;
@@ -102,7 +102,7 @@
          * raw number
          */
         Pointer hubPtr = Word.fromTypePointer(hub);
-        int sizeInBytes = hubPtr.readInt(klassLayoutHelperOffset(), KLASS_LAYOUT_HELPER_LOCATION);
+        int sizeInBytes = loadKlassLayoutHelperIntrinsic(hub);
         Word thread = registerAsWord(threadRegister);
         if (!forceSlowPath() && inlineContiguousAllocationSupported()) {
             if (isInstanceKlassFullyInitialized(hubPtr)) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/StubUtil.java	Sun Nov 16 15:48:34 2014 -0800
@@ -32,12 +32,12 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.replacements.*;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
 
 //JaCoCo Exclude
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UncommonTrapStub.java	Sun Nov 16 15:48:34 2014 -0800
@@ -27,6 +27,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
@@ -36,7 +37,6 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
 
 /**
@@ -147,7 +147,7 @@
          * Stack bang to make sure there's enough room for the interpreter frames. Bang stack for
          * total size of the interpreter frames plus shadow page size. Bang one page at a time
          * because large sizes can bang beyond yellow and red zones.
-         * 
+         *
          * @deprecated This code should go away as soon as JDK-8032410 hits the Graal repository.
          */
         final int totalFrameSizes = unrollBlock.readInt(deoptimizationUnrollBlockTotalFrameSizesOffset());
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/UnwindExceptionToCallerStub.java	Sun Nov 16 15:48:34 2014 -0800
@@ -29,6 +29,7 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.hotspot.*;
@@ -37,7 +38,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.replacements.*;
 import com.oracle.graal.replacements.Snippet.ConstantParameter;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
 
 /**
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractFrameStateBuilder.java	Sun Nov 16 15:48:34 2014 -0800
@@ -23,8 +23,6 @@
 
 package com.oracle.graal.java;
 
-import java.util.*;
-
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.java.BciBlockMapping.BciBlock;
@@ -43,11 +41,11 @@
      */
     protected boolean rethrowException;
 
-    public AbstractFrameStateBuilder(ResolvedJavaMethod method, T[] l, T[] s, T[] lo) {
+    public AbstractFrameStateBuilder(ResolvedJavaMethod method) {
         this.method = method;
-        this.locals = l;
-        this.stack = s;
-        this.lockedObjects = lo;
+        this.locals = allocateArray(method.getMaxLocals());
+        this.stack = allocateArray(Math.max(1, method.getMaxStackSize()));
+        this.lockedObjects = allocateArray(0);
     }
 
     protected AbstractFrameStateBuilder(S other) {
@@ -55,7 +53,7 @@
         this.stackSize = other.stackSize;
         this.locals = other.locals.clone();
         this.stack = other.stack.clone();
-        this.lockedObjects = other.lockedObjects == getEmptyArray() ? getEmptyArray() : other.lockedObjects.clone();
+        this.lockedObjects = other.lockedObjects.length == 0 ? other.lockedObjects : other.lockedObjects.clone();
         this.rethrowException = other.rethrowException;
 
         assert locals.length == method.getMaxLocals();
@@ -64,7 +62,7 @@
 
     public abstract S copy();
 
-    protected abstract T[] getEmptyArray();
+    protected abstract T[] allocateArray(int length);
 
     public abstract boolean isCompatibleWith(S other);
 
@@ -360,18 +358,22 @@
      *
      * @return an array containing the arguments off of the stack
      */
-    public T[] popArguments(int slotSize, int argSize) {
-        int base = stackSize - slotSize;
-        List<T> r = new ArrayList<>(argSize);
-        int stackindex = 0;
-        while (stackindex < slotSize) {
-            T element = stack[base + stackindex];
-            assert element != null;
-            r.add(element);
-            stackindex += stackSlots(element.getKind());
+    public T[] popArguments(int argSize) {
+        T[] result = allocateArray(argSize);
+        int newStackSize = stackSize;
+        for (int i = argSize - 1; i >= 0; i--) {
+            newStackSize--;
+            if (stack[newStackSize] == null) {
+                /* Two-slot value. */
+                newStackSize--;
+                assert stackSlots(stack[newStackSize].getKind()) == 2;
+            } else {
+                assert stackSlots(stack[newStackSize].getKind()) == 1;
+            }
+            result[i] = stack[newStackSize];
         }
-        stackSize = base;
-        return r.toArray(getEmptyArray());
+        stackSize = newStackSize;
+        return result;
     }
 
     /**
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Sun Nov 16 15:48:34 2014 -0800
@@ -713,7 +713,7 @@
                     if (!holder.isInitialized() && ResolveClassBeforeStaticInvoke.getValue()) {
                         handleUnresolvedInvoke(target, InvokeKind.Static);
                     } else {
-                        ValueNode[] args = frameState.popArguments(resolvedTarget.getSignature().getParameterSlots(false), resolvedTarget.getSignature().getParameterCount(false));
+                        ValueNode[] args = frameState.popArguments(resolvedTarget.getSignature().getParameterCount(false));
                         appendInvoke(InvokeKind.Static, resolvedTarget, args);
                     }
                 } else {
@@ -724,7 +724,7 @@
             @Override
             protected void genInvokeInterface(JavaMethod target) {
                 if (callTargetIsResolved(target)) {
-                    ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true));
+                    ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
                     appendInvoke(InvokeKind.Interface, (ResolvedJavaMethod) target, args);
                 } else {
                     handleUnresolvedInvoke(target, InvokeKind.Interface);
@@ -738,7 +738,7 @@
                     if (appendix != null) {
                         frameState.apush(ConstantNode.forConstant(appendix, metaAccess, currentGraph));
                     }
-                    ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(false), target.getSignature().getParameterCount(false));
+                    ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(false));
                     appendInvoke(InvokeKind.Static, (ResolvedJavaMethod) target, args);
                 } else {
                     handleUnresolvedInvoke(target, InvokeKind.Static);
@@ -760,7 +760,7 @@
                     if (appendix != null) {
                         frameState.apush(ConstantNode.forConstant(appendix, metaAccess, currentGraph));
                     }
-                    ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(hasReceiver), target.getSignature().getParameterCount(hasReceiver));
+                    ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(hasReceiver));
                     if (hasReceiver) {
                         appendInvoke(InvokeKind.Virtual, (ResolvedJavaMethod) target, args);
                     } else {
@@ -777,7 +777,7 @@
                 if (callTargetIsResolved(target)) {
                     assert target != null;
                     assert target.getSignature() != null;
-                    ValueNode[] args = frameState.popArguments(target.getSignature().getParameterSlots(true), target.getSignature().getParameterCount(true));
+                    ValueNode[] args = frameState.popArguments(target.getSignature().getParameterCount(true));
                     appendInvoke(InvokeKind.Special, (ResolvedJavaMethod) target, args);
                 } else {
                     handleUnresolvedInvoke(target, InvokeKind.Special);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Sun Nov 16 15:48:34 2014 -0800
@@ -45,7 +45,7 @@
     private final StructuredGraph graph;
 
     public HIRFrameStateBuilder(ResolvedJavaMethod method, StructuredGraph graph, boolean eagerResolve) {
-        super(method, new ValueNode[method.getMaxLocals()], new ValueNode[Math.max(1, method.getMaxStackSize())], EMPTY_ARRAY);
+        super(method);
 
         assert graph != null;
 
@@ -87,7 +87,7 @@
         super(other);
         assert other.graph != null;
         graph = other.graph;
-        monitorIds = other.monitorIds == EMPTY_MONITOR_ARRAY ? EMPTY_MONITOR_ARRAY : other.monitorIds.clone();
+        monitorIds = other.monitorIds.length == 0 ? other.monitorIds : other.monitorIds.clone();
 
         assert locals.length == method.getMaxLocals();
         assert stack.length == Math.max(1, method.getMaxStackSize());
@@ -95,8 +95,8 @@
     }
 
     @Override
-    protected ValueNode[] getEmptyArray() {
-        return EMPTY_ARRAY;
+    protected ValueNode[] allocateArray(int length) {
+        return length == 0 ? EMPTY_ARRAY : new ValueNode[length];
     }
 
     @Override
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/InductionVariables.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,7 +22,7 @@
  */
 package com.oracle.graal.loop;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
+import static com.oracle.graal.graph.Node.*;
 
 import java.util.*;
 
@@ -38,7 +38,7 @@
 
     public InductionVariables(LoopEx loop) {
         this.loop = loop;
-        ivs = newNodeIdentityMap();
+        ivs = newIdentityMap();
         findDerived(findBasic());
     }
 
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Sun Nov 16 15:48:34 2014 -0800
@@ -332,7 +332,7 @@
                  * VirtualState nodes contained in the old exit's state may be shared by other
                  * dominated VirtualStates. Those dominated virtual states need to see the
                  * proxy->phi update that are applied below.
-                 * 
+                 *
                  * We now update the original fragment's nodes accordingly:
                  */
                 originalExitState.applyToVirtual(node -> original.nodes.clearAndGrow(node));
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,16 +22,14 @@
  */
 package com.oracle.graal.loop;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.graph.Graph.DuplicationReplacement;
 import com.oracle.graal.graph.*;
+import com.oracle.graal.graph.Graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.VirtualState.NodeClosure;
+import com.oracle.graal.nodes.VirtualState.*;
 import com.oracle.graal.nodes.util.*;
 
 public class LoopFragmentInside extends LoopFragment {
@@ -145,7 +143,7 @@
         final StructuredGraph graph = graph();
         return new DuplicationReplacement() {
 
-            private HashMap<Node, Node> seenNode = new HashMap<>();
+            private Map<Node, Node> seenNode = Node.newMap();
 
             @Override
             public Node replacement(Node original) {
@@ -306,7 +304,7 @@
                 reverseEnds.put(duplicate, le);
             }
         }
-        mergedInitializers = newNodeIdentityMap();
+        mergedInitializers = Node.newIdentityMap();
         BeginNode newExit;
         StructuredGraph graph = graph();
         if (endsToMerge.size() == 1) {
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopsData.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,20 +22,20 @@
  */
 package com.oracle.graal.loop;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
+import com.oracle.graal.compiler.common.remote.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 
 public class LoopsData {
 
-    private Map<Loop<Block>, LoopEx> loopToEx = newIdentityMap();
-    private Map<LoopBeginNode, LoopEx> loopBeginToEx = newNodeIdentityMap();
+    private Map<Loop<Block>, LoopEx> loopToEx = Context.newIdentityMap();
+    private Map<LoopBeginNode, LoopEx> loopBeginToEx = Node.newIdentityMap();
     private ControlFlowGraph cfg;
 
     public LoopsData(final StructuredGraph graph) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/LoopBeginNode.java	Sun Nov 16 15:48:34 2014 -0800
@@ -219,7 +219,7 @@
      */
     public void removeDeadPhis() {
         if (phis().isNotEmpty()) {
-            Set<PhiNode> alive = new HashSet<>();
+            Set<PhiNode> alive = Node.newSet();
             for (PhiNode phi : phis()) {
                 NodePredicate isAlive = u -> !isPhiAtMerge(u) || alive.contains(u);
                 if (phi.usages().filter(isAlive).isNotEmpty()) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java	Sun Nov 16 15:48:34 2014 -0800
@@ -186,7 +186,7 @@
         copy.setGuardsStage(getGuardsStage());
         copy.isAfterFloatingReadPhase = isAfterFloatingReadPhase;
         copy.hasValueProxies = hasValueProxies;
-        HashMap<Node, Node> replacements = new HashMap<>();
+        Map<Node, Node> replacements = Node.newMap();
         replacements.put(start, copy.start);
         copy.addDuplicates(getNodes(), this, this.getNodeCount(), replacements);
         return copy;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ValueNode.java	Sun Nov 16 15:48:34 2014 -0800
@@ -32,7 +32,7 @@
  * instructions.
  */
 @NodeInfo
-public abstract class ValueNode extends ScheduledNode implements StampProvider, KindProvider {
+public abstract class ValueNode extends ScheduledNode implements KindProvider {
 
     /**
      * The kind of this value. This is {@link Kind#Void} for instructions that produce no value.
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Sun Nov 16 15:48:34 2014 -0800
@@ -62,6 +62,9 @@
 
     @Override
     public void lower(LoweringTool tool) {
+        if (tool.getLoweringStage() == LoweringTool.StandardLoweringStage.HIGH_TIER) {
+            return;
+        }
         tool.getLowerer().lower(this, tool);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/StampTool.java	Sun Nov 16 15:48:34 2014 -0800
@@ -34,8 +34,8 @@
  */
 public class StampTool {
 
-    public static Stamp meet(Collection<? extends StampProvider> values) {
-        Iterator<? extends StampProvider> iterator = values.iterator();
+    public static Stamp meet(Collection<? extends ValueNode> values) {
+        Iterator<? extends ValueNode> iterator = values.iterator();
         if (iterator.hasNext()) {
             Stamp stamp = iterator.next().stamp();
             while (iterator.hasNext()) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.phases.common;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
@@ -104,39 +102,39 @@
     public static class State extends MergeableState<State> implements Cloneable {
 
         private Map<ValueNode, ResolvedJavaType> knownTypes;
-        private HashSet<ValueNode> knownNonNull;
-        private HashSet<ValueNode> knownNull;
+        private Set<ValueNode> knownNonNull;
+        private Set<ValueNode> knownNull;
         private Map<LogicNode, ValueNode> trueConditions;
         private Map<LogicNode, ValueNode> falseConditions;
         private Map<ValueNode, GuardedStamp> valueConstraints;
 
         public State() {
-            this.knownTypes = newNodeIdentityMap();
-            this.knownNonNull = new HashSet<>();
-            this.knownNull = new HashSet<>();
-            this.trueConditions = newNodeIdentityMap();
-            this.falseConditions = newNodeIdentityMap();
-            this.valueConstraints = newNodeIdentityMap();
+            this.knownTypes = Node.newIdentityMap();
+            this.knownNonNull = Node.newSet();
+            this.knownNull = Node.newSet();
+            this.trueConditions = Node.newIdentityMap();
+            this.falseConditions = Node.newIdentityMap();
+            this.valueConstraints = Node.newIdentityMap();
         }
 
         public State(State other) {
-            this.knownTypes = newNodeIdentityMap(other.knownTypes);
-            this.knownNonNull = new HashSet<>(other.knownNonNull);
-            this.knownNull = new HashSet<>(other.knownNull);
-            this.trueConditions = newNodeIdentityMap(other.trueConditions);
-            this.falseConditions = newNodeIdentityMap(other.falseConditions);
-            this.valueConstraints = newNodeIdentityMap(other.valueConstraints);
+            this.knownTypes = Node.newIdentityMap(other.knownTypes);
+            this.knownNonNull = Node.newSet(other.knownNonNull);
+            this.knownNull = Node.newSet(other.knownNull);
+            this.trueConditions = Node.newIdentityMap(other.trueConditions);
+            this.falseConditions = Node.newIdentityMap(other.falseConditions);
+            this.valueConstraints = Node.newIdentityMap(other.valueConstraints);
         }
 
         @Override
         public boolean merge(MergeNode merge, List<State> withStates) {
-            Map<ValueNode, ResolvedJavaType> newKnownTypes = newNodeIdentityMap();
-            Map<LogicNode, ValueNode> newTrueConditions = newNodeIdentityMap();
-            Map<LogicNode, ValueNode> newFalseConditions = newNodeIdentityMap();
-            Map<ValueNode, GuardedStamp> newValueConstraints = newNodeIdentityMap();
+            Map<ValueNode, ResolvedJavaType> newKnownTypes = Node.newIdentityMap();
+            Map<LogicNode, ValueNode> newTrueConditions = Node.newIdentityMap();
+            Map<LogicNode, ValueNode> newFalseConditions = Node.newIdentityMap();
+            Map<ValueNode, GuardedStamp> newValueConstraints = Node.newIdentityMap();
 
-            HashSet<ValueNode> newKnownNull = new HashSet<>(knownNull);
-            HashSet<ValueNode> newKnownNonNull = new HashSet<>(knownNonNull);
+            Set<ValueNode> newKnownNull = Node.newSet(knownNull);
+            Set<ValueNode> newKnownNonNull = Node.newSet(knownNonNull);
             for (State state : withStates) {
                 newKnownNull.retainAll(state.knownNull);
                 newKnownNonNull.retainAll(state.knownNonNull);
@@ -678,7 +676,7 @@
                 }
 
                 // Collect the guards which have produced conditional stamps.
-                HashSet<GuardNode> provers = new HashSet<>();
+                Set<GuardNode> provers = Node.newSet();
                 for (Map.Entry<ValueNode, GuardedStamp> e : state.valueConstraints.entrySet()) {
                     provers.add(e.getValue().getGuard());
                 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java	Sun Nov 16 15:48:34 2014 -0800
@@ -24,11 +24,10 @@
 
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.graph.Graph.NodeEvent.*;
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.remote.*;
 import com.oracle.graal.graph.Graph.NodeEventScope;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -131,7 +130,7 @@
 
     @Override
     protected void run(StructuredGraph graph) {
-        Map<LoopBeginNode, Set<LocationIdentity>> modifiedInLoops = newNodeIdentityMap();
+        Map<LoopBeginNode, Set<LocationIdentity>> modifiedInLoops = Node.newIdentityMap();
         ReentrantNodeIterator.apply(new CollectMemoryCheckpointsClosure(modifiedInLoops), graph.start(), new HashSet<LocationIdentity>());
         HashSetNodeEventListener listener = new HashSetNodeEventListener(EnumSet.of(NODE_ADDED, ZERO_USAGES));
         try (NodeEventScope nes = graph.trackNodeEvents(listener)) {
@@ -163,7 +162,7 @@
         if (updateExistingPhis) {
             for (MemoryPhiNode phi : merge.phis().filter(MemoryPhiNode.class)) {
                 if (existingPhis == null) {
-                    existingPhis = newIdentityMap();
+                    existingPhis = Context.newMap();
                 }
                 phi.values().clear();
                 existingPhis.put(phi.getLocationIdentity(), phi);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java	Sun Nov 16 15:48:34 2014 -0800
@@ -23,7 +23,6 @@
 package com.oracle.graal.phases.common;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
 
 import java.util.*;
 import java.util.Map.Entry;
@@ -62,7 +61,7 @@
 
     private static class UseImplicitNullChecks extends ScheduledNodeIterator {
 
-        private final Map<ValueNode, GuardNode> nullGuarded = newIdentityMap();
+        private final Map<ValueNode, GuardNode> nullGuarded = Node.newIdentityMap();
         private final int implicitNullCheckLimit;
 
         UseImplicitNullChecks(int implicitNullCheckLimit) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Sun Nov 16 15:48:34 2014 -0800
@@ -219,7 +219,7 @@
         private final MergeNode merge;
         private final StructuredGraph graph;
 
-        private final HashMap<ValueNode, PhiNode> bottomPhis = new HashMap<>();
+        private final Map<ValueNode, PhiNode> bottomPhis = Node.newMap();
         private final List<GuardedValueNode> replacements;
 
         private final CanonicalizerPhase canonicalizer;
@@ -275,7 +275,7 @@
             AbstractEndNode endAfter = createNewMerge(fixed, stateAfter);
             MergeNode mergeAfter = endAfter.merge();
             fixedNodes.add(endAfter);
-            final HashSet<Node> duplicatedNodes = buildDuplicatedNodeSet(fixedNodes, stateAfter);
+            final Set<Node> duplicatedNodes = buildDuplicatedNodeSet(fixedNodes, stateAfter);
             mergeAfter.clearEnds();
             expandDuplicated(duplicatedNodes, mergeAfter);
 
@@ -288,7 +288,7 @@
                 if (replacements == null || replacements.get(endIndex) == null) {
                     duplicates = graph.addDuplicates(duplicatedNodes, graph, duplicatedNodes.size(), (DuplicationReplacement) null);
                 } else {
-                    HashMap<Node, Node> replace = new HashMap<>();
+                    Map<Node, Node> replace = Node.newMap();
                     replace.put(replacements.get(endIndex).object(), replacements.get(endIndex));
                     duplicates = graph.addDuplicates(duplicatedNodes, graph, duplicatedNodes.size(), replace);
                 }
@@ -359,7 +359,7 @@
          *            from within the duplicated set of nodes.
          * @return The set of nodes that need to be duplicated.
          */
-        private HashSet<Node> buildDuplicatedNodeSet(final ArrayList<FixedNode> fixedNodes, FrameState stateAfter) {
+        private Set<Node> buildDuplicatedNodeSet(final ArrayList<FixedNode> fixedNodes, FrameState stateAfter) {
             final NodeBitMap aboveBound = graph.createNodeBitMap();
             final NodeBitMap belowBound = graph.createNodeBitMap();
 
@@ -434,7 +434,7 @@
 
             // build the intersection
             belowBound.intersect(aboveBound);
-            HashSet<Node> result = new HashSet<>();
+            Set<Node> result = Node.newSet();
             for (Node node : belowBound) {
                 result.add(node);
             }
@@ -480,7 +480,7 @@
          *            for newly created phis and to as a target for dependencies that pointed into
          *            the duplicated set of nodes.
          */
-        private void expandDuplicated(HashSet<Node> duplicatedNodes, MergeNode newBottomMerge) {
+        private void expandDuplicated(Set<Node> duplicatedNodes, MergeNode newBottomMerge) {
             Deque<Node> worklist = new ArrayDeque<>(duplicatedNodes);
 
             while (!worklist.isEmpty()) {
@@ -490,8 +490,8 @@
             }
         }
 
-        private void processUsages(Node duplicated, HashSet<Node> duplicatedNodes, MergeNode newBottomMerge, Deque<Node> worklist) {
-            HashSet<Node> unique = new HashSet<>();
+        private void processUsages(Node duplicated, Set<Node> duplicatedNodes, MergeNode newBottomMerge, Deque<Node> worklist) {
+            Set<Node> unique = Node.newSet();
             duplicated.usages().snapshotTo(unique);
             Node newOutsideClone = null;
             for (Node usage : unique) {
@@ -542,7 +542,7 @@
             }
         }
 
-        private void processInputs(Node duplicated, HashSet<Node> duplicatedNodes, Deque<Node> worklist) {
+        private void processInputs(Node duplicated, Set<Node> duplicatedNodes, Deque<Node> worklist) {
             // check if this node has an input that lies outside and cannot be shared
             NodePosIterator iter = duplicated.inputs().iterator();
             while (iter.hasNext()) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ValueAnchorCleanupPhase.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ValueAnchorCleanupPhase.java	Sun Nov 16 15:48:34 2014 -0800
@@ -39,14 +39,14 @@
 
     private static class State extends MergeableState<State> implements Cloneable {
 
-        private final HashSet<Node> anchoredValues;
+        private final Set<Node> anchoredValues;
 
         public State() {
-            anchoredValues = new HashSet<>();
+            anchoredValues = Node.newSet();
         }
 
         public State(State other) {
-            anchoredValues = new HashSet<>(other.anchoredValues);
+            anchoredValues = Node.newSet(other.anchoredValues);
         }
 
         @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/EquationalReasoner.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.phases.common.cfs;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
@@ -81,7 +79,7 @@
      * {@link com.oracle.graal.graph.NodeBitMap NodeBitMap} but in this set instead (those nodes are
      * added after the {@link com.oracle.graal.graph.NodeBitMap} was obtained).
      */
-    final Set<ValueNode> added = newNodeIdentitySet();
+    final Set<ValueNode> added = Node.newSet();
 
     /**
      * The reduction of a FloatingNode performed by {@link EquationalReasoner EquationalReasoner}
@@ -91,7 +89,7 @@
      * The substitutions tracked in this field become invalid as described in
      * {@link #updateState(com.oracle.graal.phases.common.cfs.State) updateState(State)}
      */
-    private final Map<ValueNode, ValueNode> substs = newNodeIdentityMap();
+    private final Map<ValueNode, ValueNode> substs = Node.newIdentityMap();
 
     public EquationalReasoner(StructuredGraph graph, CanonicalizerTool tool, LogicConstantNode trueConstant, LogicConstantNode falseConstant, ConstantNode nullConstant) {
         this.graph = graph;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/cfs/State.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,14 +22,13 @@
  */
 package com.oracle.graal.phases.common.cfs;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.lang.reflect.*;
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.extended.*;
@@ -116,20 +115,20 @@
     Map<LogicNode, GuardingNode> falseFacts;
 
     public State() {
-        this.typeRefinements = newNodeIdentityMap();
-        this.trueFacts = newNodeIdentityMap();
-        this.falseFacts = newNodeIdentityMap();
+        this.typeRefinements = Node.newIdentityMap();
+        this.trueFacts = Node.newIdentityMap();
+        this.falseFacts = Node.newIdentityMap();
     }
 
     public State(State other) {
         this.isUnreachable = other.isUnreachable;
         this.versionNr = other.versionNr;
-        this.typeRefinements = newNodeIdentityMap();
+        this.typeRefinements = Node.newIdentityMap();
         for (Map.Entry<ValueNode, Witness> entry : other.typeRefinements.entrySet()) {
             this.typeRefinements.put(entry.getKey(), new Witness(entry.getValue()));
         }
-        this.trueFacts = newNodeIdentityMap(other.trueFacts);
-        this.falseFacts = newNodeIdentityMap(other.falseFacts);
+        this.trueFacts = Node.newIdentityMap(other.trueFacts);
+        this.falseFacts = Node.newIdentityMap(other.falseFacts);
     }
 
     public boolean repOK() {
@@ -155,7 +154,7 @@
     }
 
     private Map<ValueNode, Witness> mergeKnownTypes(MergeNode merge, ArrayList<State> withReachableStates) {
-        Map<ValueNode, Witness> newKnownTypes = newNodeIdentityMap();
+        Map<ValueNode, Witness> newKnownTypes = Node.newIdentityMap();
 
         for (Map.Entry<ValueNode, Witness> entry : typeRefinements.entrySet()) {
             ValueNode node = entry.getKey();
@@ -279,7 +278,7 @@
     }
 
     private Map<LogicNode, GuardingNode> mergeTrueFacts(ArrayList<State> withReachableStates, GuardingNode merge) {
-        Map<LogicNode, GuardingNode> newTrueConditions = newNodeIdentityMap();
+        Map<LogicNode, GuardingNode> newTrueConditions = Node.newIdentityMap();
         for (Map.Entry<LogicNode, GuardingNode> entry : trueFacts.entrySet()) {
             LogicNode check = entry.getKey();
             GuardingNode guard = entry.getValue();
@@ -302,7 +301,7 @@
     }
 
     private Map<LogicNode, GuardingNode> mergeFalseFacts(ArrayList<State> withReachableStates, GuardingNode merge) {
-        Map<LogicNode, GuardingNode> newFalseConditions = newNodeIdentityMap();
+        Map<LogicNode, GuardingNode> newFalseConditions = Node.newIdentityMap();
         for (Map.Entry<LogicNode, GuardingNode> entry : falseFacts.entrySet()) {
             LogicNode check = entry.getKey();
             GuardingNode guard = entry.getValue();
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/CallsiteHolderExplorable.java	Sun Nov 16 15:48:34 2014 -0800
@@ -23,6 +23,7 @@
 package com.oracle.graal.phases.common.inlining.walker;
 
 import com.oracle.graal.api.meta.ResolvedJavaMethod;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.graph.FixedNodeProbabilityCache;
 
@@ -93,7 +94,7 @@
         if (freshlyInstantiatedArguments == null || freshlyInstantiatedArguments.isEmpty()) {
             return Collections.EMPTY_SET;
         }
-        Set<ParameterNode> result = new HashSet<>();
+        Set<ParameterNode> result = Node.newSet();
         for (ParameterNode p : graph.getNodes(ParameterNode.class)) {
             if (freshlyInstantiatedArguments.get(p.index())) {
                 result.add(p);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/ComputeInliningRelevance.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/ComputeInliningRelevance.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.phases.common.inlining.walker;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 import java.util.function.*;
 
@@ -71,10 +69,10 @@
             rootScope = new Scope(graph.start(), null);
         } else {
             if (nodeRelevances == null) {
-                nodeRelevances = newNodeIdentityMap(EXPECTED_MIN_INVOKE_COUNT + graph.getNodeCount() / EXPECTED_INVOKE_RATIO);
+                nodeRelevances = Node.newIdentityMap(EXPECTED_MIN_INVOKE_COUNT + graph.getNodeCount() / EXPECTED_INVOKE_RATIO);
             }
             NodeWorkList workList = graph.createNodeWorkList();
-            Map<LoopBeginNode, Scope> loops = newNodeIdentityMap(EXPECTED_LOOP_COUNT);
+            Map<LoopBeginNode, Scope> loops = Node.newIdentityMap(EXPECTED_LOOP_COUNT);
 
             loops.put(null, new Scope(graph.start(), null));
             for (LoopBeginNode loopBegin : graph.getNodes(LoopBeginNode.class)) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,37 +22,28 @@
  */
 package com.oracle.graal.phases.common.inlining.walker;
 
-import com.oracle.graal.api.code.Assumptions;
-import com.oracle.graal.api.code.BailoutException;
-import com.oracle.graal.api.meta.JavaTypeProfile;
-import com.oracle.graal.api.meta.ResolvedJavaMethod;
-import com.oracle.graal.api.meta.ResolvedJavaType;
-import com.oracle.graal.compiler.common.GraalInternalError;
-import com.oracle.graal.compiler.common.type.ObjectStamp;
-import com.oracle.graal.debug.Debug;
-import com.oracle.graal.debug.DebugMetric;
-import com.oracle.graal.graph.Graph;
-import com.oracle.graal.graph.Node;
-import com.oracle.graal.nodes.*;
-import com.oracle.graal.nodes.java.AbstractNewObjectNode;
-import com.oracle.graal.nodes.java.MethodCallTargetNode;
-import com.oracle.graal.nodes.virtual.AllocatedObjectNode;
-import com.oracle.graal.nodes.virtual.VirtualObjectNode;
-import com.oracle.graal.phases.OptimisticOptimizations;
-import com.oracle.graal.phases.common.CanonicalizerPhase;
-import com.oracle.graal.phases.common.inlining.InliningUtil;
-import com.oracle.graal.phases.common.inlining.info.*;
-import com.oracle.graal.phases.common.inlining.info.elem.Inlineable;
-import com.oracle.graal.phases.common.inlining.info.elem.InlineableGraph;
-import com.oracle.graal.phases.common.inlining.info.elem.InlineableMacroNode;
-import com.oracle.graal.phases.common.inlining.policy.InliningPolicy;
-import com.oracle.graal.phases.tiers.HighTierContext;
-import com.oracle.graal.phases.util.Providers;
+import static com.oracle.graal.compiler.common.GraalOptions.*;
+import static com.oracle.graal.phases.common.inlining.walker.CallsiteHolderDummy.*;
 
 import java.util.*;
 
-import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static com.oracle.graal.phases.common.inlining.walker.CallsiteHolderDummy.DUMMY_CALLSITE_HOLDER;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.*;
+import com.oracle.graal.phases.common.inlining.*;
+import com.oracle.graal.phases.common.inlining.info.*;
+import com.oracle.graal.phases.common.inlining.info.elem.*;
+import com.oracle.graal.phases.common.inlining.policy.*;
+import com.oracle.graal.phases.tiers.*;
+import com.oracle.graal.phases.util.*;
 
 /**
  * <p>
@@ -368,7 +359,7 @@
         InlineInfo calleeInfo = calleeInvocation.callee();
         try {
             try (Debug.Scope scope = Debug.scope("doInline", callerGraph)) {
-                Set<Node> canonicalizedNodes = new HashSet<>();
+                Set<Node> canonicalizedNodes = Node.newSet();
                 calleeInfo.invoke().asNode().usages().snapshotTo(canonicalizedNodes);
                 Collection<Node> parameterUsages = calleeInfo.inline(new Providers(context), callerAssumptions);
                 canonicalizedNodes.addAll(parameterUsages);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/util/HashSetNodeEventListener.java	Sun Nov 16 15:48:34 2014 -0800
@@ -40,7 +40,7 @@
      * Creates a {@link NodeEventListener} that collects nodes from all events.
      */
     public HashSetNodeEventListener() {
-        this.nodes = new HashSet<>();
+        this.nodes = Node.newSet();
         this.filter = EnumSet.allOf(NodeEvent.class);
     }
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/FixedNodeProbabilityCache.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.phases.graph;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 import java.util.function.*;
 
@@ -38,7 +36,7 @@
 
     private static final DebugMetric metricComputeNodeProbability = Debug.metric("ComputeNodeProbability");
 
-    private final Map<FixedNode, Double> cache = newIdentityMap();
+    private final Map<FixedNode, Double> cache = Node.newIdentityMap();
 
     /**
      * <p>
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/PostOrderNodeIterator.java	Sun Nov 16 15:48:34 2014 -0800
@@ -25,7 +25,6 @@
 import java.util.*;
 
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.util.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -54,7 +53,7 @@
         StructuredGraph graph = start.graph();
         visitedEnds = graph.createNodeBitMap();
         nodeQueue = new ArrayDeque<>();
-        nodeStates = CollectionsAccess.newNodeIdentityMap();
+        nodeStates = Node.newIdentityMap();
         this.start = start;
         this.state = initialState;
     }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantBlockIterator.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,11 +22,10 @@
  */
 package com.oracle.graal.phases.graph;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.compiler.common.cfg.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 
@@ -89,7 +88,7 @@
         /*
          * States are stored on EndNodes before merges, and on BeginNodes after ControlSplitNodes.
          */
-        Map<FixedNode, StateT> states = newNodeIdentityMap();
+        Map<FixedNode, StateT> states = Node.newIdentityMap();
 
         StateT state = initialState;
         Block current = start;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/ReentrantNodeIterator.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.phases.graph;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.graph.*;
@@ -37,8 +35,8 @@
         public final Map<LoopExitNode, StateT> exitStates;
 
         public LoopInfo(int endCount, int exitCount) {
-            endStates = newNodeIdentityMap(endCount);
-            exitStates = newNodeIdentityMap(exitCount);
+            endStates = Node.newIdentityMap(endCount);
+            exitStates = Node.newIdentityMap(exitCount);
         }
     }
 
@@ -90,7 +88,7 @@
     private static <StateT> Map<FixedNode, StateT> apply(NodeIteratorClosure<StateT> closure, FixedNode start, StateT initialState, LoopBeginNode boundary) {
         assert start != null;
         Deque<BeginNode> nodeQueue = new ArrayDeque<>();
-        Map<FixedNode, StateT> blockEndStates = newNodeIdentityMap();
+        Map<FixedNode, StateT> blockEndStates = Node.newIdentityMap();
 
         StateT state = initialState;
         FixedNode current = start;
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/SinglePassNodeIterator.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/graph/SinglePassNodeIterator.java	Sun Nov 16 15:48:34 2014 -0800
@@ -25,7 +25,6 @@
 import java.util.*;
 
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.util.*;
 import com.oracle.graal.nodes.*;
 
 /**
@@ -137,7 +136,7 @@
         StructuredGraph graph = start.graph();
         visitedEnds = graph.createNodeBitMap();
         nodeQueue = new ArrayDeque<>();
-        nodeStates = CollectionsAccess.newNodeIdentityMap();
+        nodeStates = Node.newIdentityMap();
         this.start = start;
         this.state = initialState;
     }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java	Sun Nov 16 15:48:34 2014 -0800
@@ -835,7 +835,7 @@
 
     private boolean noDuplicatedNodesInBlock(Block b) {
         List<ScheduledNode> list = blockToNodesMap.get(b);
-        HashSet<ScheduledNode> hashset = new HashSet<>(list);
+        Set<ScheduledNode> hashset = Node.newSet(list);
         return list.size() == hashset.size();
     }
 
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.phases.util;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.compiler.common.*;
@@ -138,7 +136,7 @@
     public static boolean assertSchedulableGraph(final StructuredGraph graph) {
         try {
             final SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.LATEST_OUT_OF_LOOPS, MemoryScheduling.NONE);
-            final Map<LoopBeginNode, NodeBitMap> loopEntryStates = newNodeIdentityMap();
+            final Map<LoopBeginNode, NodeBitMap> loopEntryStates = Node.newIdentityMap();
             schedule.apply(graph, false);
 
             BlockIteratorClosure<NodeBitMap> closure = new BlockIteratorClosure<NodeBitMap>() {
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/IdealGraphPrinter.java	Sun Nov 16 15:48:34 2014 -0800
@@ -84,7 +84,7 @@
     @Override
     public void print(Graph graph, String title, SchedulePhase predefinedSchedule) {
         beginGraph(title);
-        Set<Node> noBlockNodes = new HashSet<>();
+        Set<Node> noBlockNodes = Node.newSet();
         SchedulePhase schedule = predefinedSchedule;
         if (schedule == null && tryToSchedule) {
             if (PrintIdealGraphSchedule.getValue()) {
@@ -249,7 +249,7 @@
         endSuccessors();
         beginBlockNodes();
 
-        Set<Node> nodes = new HashSet<>();
+        Set<Node> nodes = Node.newSet();
 
         if (nodeToBlock != null) {
             for (Node n : graph.getNodes()) {
@@ -270,7 +270,7 @@
                 }
             }
 
-            Set<Node> snapshot = new HashSet<>(nodes);
+            Set<Node> snapshot = Node.newSet(nodes);
             // add all framestates and phis to their blocks
             for (Node node : snapshot) {
                 if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java	Sun Nov 16 15:48:34 2014 -0800
@@ -39,7 +39,6 @@
 import com.oracle.graal.nodes.spi.*;
 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;
 import com.oracle.graal.replacements.SnippetTemplate.Arguments;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPhase.java	Sun Nov 16 15:48:34 2014 -0800
@@ -45,7 +45,6 @@
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.util.*;
-import com.oracle.graal.replacements.Snippet.Fold;
 
 /**
  * Replaces calls to {@link NodeIntrinsic}s with nodes and calls to methods annotated with
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationVerificationPhase.java	Sun Nov 16 15:48:34 2014 -0800
@@ -23,6 +23,7 @@
 package com.oracle.graal.replacements;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
@@ -30,7 +31,6 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.phases.*;
-import com.oracle.graal.replacements.Snippet.Fold;
 
 /**
  * Checks that a graph contains no calls to {@link NodeIntrinsic} or {@link Fold} methods.
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Sun Nov 16 15:48:34 2014 -0800
@@ -61,10 +61,10 @@
 
 public class ReplacementsImpl implements Replacements {
 
-    protected final Providers providers;
-    protected final SnippetReflectionProvider snippetReflection;
-    protected final TargetDescription target;
-    protected final Assumptions assumptions;
+    public final Providers providers;
+    public final SnippetReflectionProvider snippetReflection;
+    public final TargetDescription target;
+    public final Assumptions assumptions;
 
     /**
      * The preprocessed replacement graphs.
@@ -114,7 +114,7 @@
                         }
                         String originalName = originalName(substituteMethod, methodSubstitution.value());
                         JavaSignature originalSignature = originalSignature(substituteMethod, methodSubstitution.signature(), methodSubstitution.isStatic());
-                        Member originalMethod = originalMethod(classSubstitution, methodSubstitution.optional(), originalName, originalSignature);
+                        Executable originalMethod = originalMethod(classSubstitution, methodSubstitution.optional(), originalName, originalSignature);
                         if (originalMethod != null && (guard == null || guard.execute())) {
                             ResolvedJavaMethod original = registerMethodSubstitution(this, originalMethod, substituteMethod);
                             if (original != null && methodSubstitution.forced() && shouldIntrinsify(original)) {
@@ -127,7 +127,7 @@
                     if (macroSubstitution != null && (defaultGuard == null || defaultGuard.execute())) {
                         String originalName = originalName(substituteMethod, macroSubstitution.value());
                         JavaSignature originalSignature = originalSignature(substituteMethod, macroSubstitution.signature(), macroSubstitution.isStatic());
-                        Member originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalSignature);
+                        Executable originalMethod = originalMethod(classSubstitution, macroSubstitution.optional(), originalName, originalSignature);
                         if (originalMethod != null) {
                             ResolvedJavaMethod original = registerMacroSubstitution(this, originalMethod, macroSubstitution.macro());
                             if (original != null && macroSubstitution.forced() && shouldIntrinsify(original)) {
@@ -160,7 +160,7 @@
             return new JavaSignature(returnType, parameters);
         }
 
-        private Member originalMethod(ClassSubstitution classSubstitution, boolean optional, String name, JavaSignature signature) {
+        private Executable originalMethod(ClassSubstitution classSubstitution, boolean optional, String name, JavaSignature signature) {
             Class<?> originalClass = classSubstitution.value();
             if (originalClass == ClassSubstitution.class) {
                 originalClass = resolveClass(classSubstitution.className(), classSubstitution.optional());
@@ -346,15 +346,10 @@
      * @param substituteMethod the substitute method
      * @return the original method
      */
-    protected ResolvedJavaMethod registerMethodSubstitution(ClassReplacements cr, Member originalMember, Method substituteMethod) {
+    protected ResolvedJavaMethod registerMethodSubstitution(ClassReplacements cr, Executable originalMember, Method substituteMethod) {
         MetaAccessProvider metaAccess = providers.getMetaAccess();
         ResolvedJavaMethod substitute = metaAccess.lookupJavaMethod(substituteMethod);
-        ResolvedJavaMethod original;
-        if (originalMember instanceof Method) {
-            original = metaAccess.lookupJavaMethod((Method) originalMember);
-        } else {
-            original = metaAccess.lookupJavaConstructor((Constructor<?>) originalMember);
-        }
+        ResolvedJavaMethod original = metaAccess.lookupJavaMethod(originalMember);
         if (Debug.isLogEnabled()) {
             Debug.log("substitution: %s --> %s", original.format("%H.%n(%p) %r"), substitute.format("%H.%n(%p) %r"));
         }
@@ -370,14 +365,9 @@
      * @param macro the substitute macro node class
      * @return the original method
      */
-    protected ResolvedJavaMethod registerMacroSubstitution(ClassReplacements cr, Member originalMethod, Class<? extends FixedWithNextNode> macro) {
-        ResolvedJavaMethod originalJavaMethod;
+    protected ResolvedJavaMethod registerMacroSubstitution(ClassReplacements cr, Executable originalMethod, Class<? extends FixedWithNextNode> macro) {
         MetaAccessProvider metaAccess = providers.getMetaAccess();
-        if (originalMethod instanceof Method) {
-            originalJavaMethod = metaAccess.lookupJavaMethod((Method) originalMethod);
-        } else {
-            originalJavaMethod = metaAccess.lookupJavaConstructor((Constructor<?>) originalMethod);
-        }
+        ResolvedJavaMethod originalJavaMethod = metaAccess.lookupJavaMethod(originalMethod);
         cr.macroSubstitutions.put(originalJavaMethod, macro);
         return originalJavaMethod;
     }
@@ -419,7 +409,7 @@
      * Can be overridden to return an object that specializes various parts of graph preprocessing.
      */
     protected GraphMaker createGraphMaker(ResolvedJavaMethod substitute, ResolvedJavaMethod original, FrameStateProcessing frameStateProcessing) {
-        return new GraphMaker(substitute, original, frameStateProcessing);
+        return new GraphMaker(this, substitute, original, frameStateProcessing);
     }
 
     /**
@@ -450,7 +440,10 @@
     /**
      * Creates and preprocesses a graph for a replacement.
      */
-    protected class GraphMaker {
+    public static class GraphMaker {
+        /** The replacements object that the graphs are created for. */
+        protected final ReplacementsImpl replacements;
+
         /**
          * The method for which a graph is being created.
          */
@@ -468,7 +461,8 @@
          */
         private FrameStateProcessing frameStateProcessing;
 
-        protected GraphMaker(ResolvedJavaMethod substitute, ResolvedJavaMethod substitutedMethod, FrameStateProcessing frameStateProcessing) {
+        protected GraphMaker(ReplacementsImpl replacements, ResolvedJavaMethod substitute, ResolvedJavaMethod substitutedMethod, FrameStateProcessing frameStateProcessing) {
+            this.replacements = replacements;
             this.method = substitute;
             this.substitutedMethod = substitutedMethod;
             this.frameStateProcessing = frameStateProcessing;
@@ -495,7 +489,7 @@
          * Does final processing of a snippet graph.
          */
         protected void finalizeGraph(StructuredGraph graph) {
-            createNodeIntrinsificationPhase().apply(graph);
+            replacements.createNodeIntrinsificationPhase().apply(graph);
             if (!SnippetTemplate.hasConstantParameter(method)) {
                 NodeIntrinsificationVerificationPhase.verify(graph);
             }
@@ -535,7 +529,7 @@
                         if (callTarget instanceof MethodCallTargetNode) {
                             ResolvedJavaMethod targetMethod = ((MethodCallTargetNode) callTarget).targetMethod();
                             if (targetMethod.isConstructor()) {
-                                ResolvedJavaType throwableType = providers.getMetaAccess().lookupJavaType(Throwable.class);
+                                ResolvedJavaType throwableType = replacements.providers.getMetaAccess().lookupJavaType(Throwable.class);
                                 return !throwableType.isAssignableFrom(targetMethod.getDeclaringClass());
                             }
                         }
@@ -551,17 +545,17 @@
         private static final int MAX_GRAPH_INLINING_DEPTH = 100; // more than enough
 
         private StructuredGraph parseGraph(final ResolvedJavaMethod methodToParse, final SnippetInliningPolicy policy, int inliningDepth) {
-            StructuredGraph graph = graphCache.get(methodToParse);
+            StructuredGraph graph = replacements.graphCache.get(methodToParse);
             if (graph == null) {
                 StructuredGraph newGraph = null;
                 try (Scope s = Debug.scope("ParseGraph", methodToParse)) {
-                    newGraph = buildGraph(methodToParse, policy == null ? inliningPolicy(methodToParse) : policy, inliningDepth);
+                    newGraph = buildGraph(methodToParse, policy == null ? replacements.inliningPolicy(methodToParse) : policy, inliningDepth);
                 } catch (Throwable e) {
                     throw Debug.handle(e);
                 }
 
-                graphCache.putIfAbsent(methodToParse, newGraph);
-                graph = graphCache.get(methodToParse);
+                replacements.graphCache.putIfAbsent(methodToParse, newGraph);
+                graph = replacements.graphCache.get(methodToParse);
                 assert graph != null;
             }
             return graph;
@@ -573,7 +567,7 @@
         protected StructuredGraph buildInitialGraph(final ResolvedJavaMethod methodToParse) {
             final StructuredGraph graph = new StructuredGraph(methodToParse);
             try (Scope s = Debug.scope("buildInitialGraph", graph)) {
-                MetaAccessProvider metaAccess = providers.getMetaAccess();
+                MetaAccessProvider metaAccess = replacements.providers.getMetaAccess();
 
                 if (MethodsElidedInSnippets != null && methodToParse.getSignature().getReturnKind() == Kind.Void && MethodFilter.matches(MethodsElidedInSnippets, methodToParse)) {
                     graph.addAfterFixed(graph.start(), graph.add(ReturnNode.create(null)));
@@ -581,11 +575,9 @@
                     createGraphBuilder(metaAccess, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph);
                 }
                 afterParsing(graph);
-                new WordTypeVerificationPhase(metaAccess, snippetReflection, target.wordKind).apply(graph);
-                new WordTypeRewriterPhase(metaAccess, snippetReflection, target.wordKind).apply(graph);
 
                 if (OptCanonicalizer.getValue()) {
-                    new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
+                    new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers, replacements.assumptions));
                 }
             } catch (Throwable e) {
                 throw Debug.handle(e);
@@ -597,7 +589,10 @@
             return new GraphBuilderPhase.Instance(metaAccess, graphBuilderConfig, optimisticOpts);
         }
 
-        protected void afterParsing(@SuppressWarnings("unused") StructuredGraph graph) {
+        protected void afterParsing(StructuredGraph graph) {
+            MetaAccessProvider metaAccess = replacements.providers.getMetaAccess();
+            new WordTypeVerificationPhase(metaAccess, replacements.snippetReflection, replacements.target.wordKind).apply(graph);
+            new WordTypeRewriterPhase(metaAccess, replacements.snippetReflection, replacements.target.wordKind).apply(graph);
         }
 
         protected Object beforeInline(@SuppressWarnings("unused") MethodCallTargetNode callTarget, @SuppressWarnings("unused") StructuredGraph callee) {
@@ -613,7 +608,7 @@
          */
         protected void afterInline(StructuredGraph caller, StructuredGraph callee, Object beforeInlineData) {
             if (OptCanonicalizer.getValue()) {
-                new CanonicalizerPhase(true).apply(caller, new PhaseContext(providers, assumptions));
+                new CanonicalizerPhase(true).apply(caller, new PhaseContext(replacements.providers, replacements.assumptions));
             }
         }
 
@@ -621,10 +616,10 @@
          * Called after all inlining for a given graph is complete.
          */
         protected void afterInlining(StructuredGraph graph) {
-            createNodeIntrinsificationPhase().apply(graph);
+            replacements.createNodeIntrinsificationPhase().apply(graph);
             new DeadCodeEliminationPhase(Optional).apply(graph);
             if (OptCanonicalizer.getValue()) {
-                new CanonicalizerPhase(true).apply(graph, new PhaseContext(providers, assumptions));
+                new CanonicalizerPhase(true).apply(graph, new PhaseContext(replacements.providers, replacements.assumptions));
             }
         }
 
@@ -662,11 +657,11 @@
                             afterInline(graph, originalGraph, null);
                         }
                     } else {
-                        Class<? extends FixedWithNextNode> macroNodeClass = InliningUtil.getMacroNodeClass(ReplacementsImpl.this, callee);
+                        Class<? extends FixedWithNextNode> macroNodeClass = InliningUtil.getMacroNodeClass(replacements, callee);
                         if (macroNodeClass != null) {
                             InliningUtil.inlineMacroNode(callTarget.invoke(), callee, macroNodeClass);
                         } else {
-                            StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(ReplacementsImpl.this, callee);
+                            StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(replacements, callee);
                             if ((callTarget.invokeKind() == InvokeKind.Static || callTarget.invokeKind() == InvokeKind.Special) &&
                                             (policy.shouldInline(callee, methodToParse) || (intrinsicGraph != null && policy.shouldUseReplacement(callee, methodToParse)))) {
                                 StructuredGraph targetGraph;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/Snippet.java	Sun Nov 16 15:48:34 2014 -0800
@@ -25,6 +25,7 @@
 import java.lang.annotation.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.replacements.nodes.*;
 import com.oracle.graal.word.*;
@@ -62,7 +63,7 @@
 
         /**
          * Determines if {@code method} should be inlined using its replacement graph.
-         * 
+         *
          * @return true if the replacement graph should be used, false for normal inlining.
          */
         boolean shouldUseReplacement(ResolvedJavaMethod callee, ResolvedJavaMethod methodToParse);
@@ -115,24 +116,12 @@
     }
 
     /**
-     * Annotates a method replaced by a compile-time constant. A (resolved) call to the annotated
-     * method is replaced with a constant obtained by calling the annotated method via reflection.
-     * 
-     * All arguments to such a method (including the receiver if applicable) must be compile-time
-     * constants.
-     */
-    @Retention(RetentionPolicy.RUNTIME)
-    @Target(ElementType.METHOD)
-    public static @interface Fold {
-    }
-
-    /**
      * Denotes a snippet parameter representing 0 or more arguments that will be bound during
      * snippet template {@linkplain SnippetTemplate#instantiate instantiation}. During snippet
      * template creation, its value must be an array whose length specifies the number of arguments
      * (the contents of the array are ignored) bound to the parameter during
      * {@linkplain SnippetTemplate#instantiate instantiation}.
-     * 
+     *
      * Such a parameter must be used in a counted loop in the snippet preceded by a call to
      * {@link ExplodeLoopNode#explodeLoop()}. The counted looped must be a standard iteration over
      * all the loop's elements (i.e. {@code for (T e : arr) ... }).
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetCounter.java	Sun Nov 16 15:48:34 2014 -0800
@@ -30,8 +30,8 @@
 import java.util.*;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.replacements.Snippet.Fold;
 import com.oracle.graal.word.*;
 
 /**
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sun Nov 16 15:48:34 2014 -0800
@@ -25,7 +25,6 @@
 import static com.oracle.graal.api.meta.LocationIdentity.*;
 import static com.oracle.graal.compiler.common.GraalOptions.*;
 import static com.oracle.graal.debug.Debug.*;
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
 import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*;
 import static com.oracle.graal.replacements.SnippetTemplate.AbstractTemplates.*;
 import static java.util.FormattableFlags.*;
@@ -569,7 +568,7 @@
 
         // Copy snippet graph, replacing constant parameters with given arguments
         final StructuredGraph snippetCopy = new StructuredGraph(snippetGraph.name, snippetGraph.method());
-        Map<Node, Node> nodeReplacements = newNodeIdentityMap();
+        Map<Node, Node> nodeReplacements = Node.newIdentityMap();
         nodeReplacements.put(snippetGraph.start(), snippetCopy.start());
 
         MetaAccessProvider metaAccess = providers.getMetaAccess();
@@ -863,7 +862,7 @@
      * @return the map that will be used to bind arguments to parameters when inlining this template
      */
     private Map<Node, Node> bind(StructuredGraph replaceeGraph, MetaAccessProvider metaAccess, Arguments args) {
-        Map<Node, Node> replacements = newNodeIdentityMap();
+        Map<Node, Node> replacements = Node.newIdentityMap();
         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++) {
             Object parameter = parameters[i];
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/BasicObjectCloneNode.java	Sun Nov 16 15:48:34 2014 -0800
@@ -47,7 +47,11 @@
 
     @Override
     public boolean inferStamp() {
-        return updateStamp(getObject().stamp());
+        Stamp objectStamp = getObject().stamp();
+        if (objectStamp instanceof ObjectStamp) {
+            objectStamp = objectStamp.join(StampFactory.objectNonNull());
+        }
+        return updateStamp(objectStamp);
     }
 
     public ValueNode getObject() {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java	Sun Nov 16 15:48:34 2014 -0800
@@ -68,29 +68,20 @@
 
     private static final Signature signature = new Signature() {
 
+        @Override
         public JavaType getReturnType(ResolvedJavaType accessingClass) {
             return declaringClass;
         }
 
-        public Kind getReturnKind() {
-            return declaringClass.getKind();
-        }
-
-        public JavaType getParameterType(int index, ResolvedJavaType accessingClass) {
-            throw new IndexOutOfBoundsException();
-        }
-
-        public int getParameterSlots(boolean withReceiver) {
+        @Override
+        public int getParameterCount(boolean receiver) {
             return 0;
         }
 
-        public Kind getParameterKind(int index) {
+        @Override
+        public JavaType getParameterType(int index, ResolvedJavaType accessingClass) {
             throw new IndexOutOfBoundsException();
         }
-
-        public int getParameterCount(boolean receiver) {
-            return 0;
-        }
     };
 
     public TruffleDebugJavaMethod(RootCallTarget compilable) {
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/EffectsClosure.java	Sun Nov 16 15:48:34 2014 -0800
@@ -23,12 +23,11 @@
 package com.oracle.graal.virtual.phases.ea;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.cfg.*;
+import com.oracle.graal.compiler.common.remote.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
@@ -46,8 +45,8 @@
 
     protected final NodeMap<ValueNode> aliases;
     protected final BlockMap<GraphEffectList> blockEffects;
-    private final Map<Loop<Block>, GraphEffectList> loopMergeEffects = newIdentityMap();
-    private final Map<LoopBeginNode, BlockT> loopEntryStates = newNodeIdentityMap();
+    private final Map<Loop<Block>, GraphEffectList> loopMergeEffects = Context.newIdentityMap();
+    private final Map<LoopBeginNode, BlockT> loopEntryStates = Node.newIdentityMap();
 
     protected boolean changed;
 
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeBlockState.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,10 +22,9 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
 import com.oracle.graal.nodes.java.*;
@@ -34,7 +33,7 @@
 
 public abstract class PartialEscapeBlockState<T extends PartialEscapeBlockState<T>> extends EffectsBlockState<T> {
 
-    protected final Map<VirtualObjectNode, ObjectState> objectStates = newIdentityMap();
+    protected final Map<VirtualObjectNode, ObjectState> objectStates = Node.newIdentityMap();
 
     /**
      * Final subclass of PartialEscapeBlockState, for performance and to make everything behave
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Sun Nov 16 15:48:34 2014 -0800
@@ -22,12 +22,11 @@
  */
 package com.oracle.graal.virtual.phases.ea;
 
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
-
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.common.remote.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
@@ -222,7 +221,7 @@
 
     @Override
     protected void processLoopExit(LoopExitNode exitNode, BlockT initialState, BlockT exitState, GraphEffectList effects) {
-        HashMap<VirtualObjectNode, ProxyNode> proxies = new HashMap<>();
+        Map<VirtualObjectNode, ProxyNode> proxies = Node.newMap();
 
         for (ProxyNode proxy : exitNode.proxies()) {
             ObjectState obj = getObjectState(exitState, proxy.value());
@@ -272,9 +271,9 @@
 
     protected class MergeProcessor extends EffectsClosure<BlockT>.MergeProcessor {
 
-        private final HashMap<Object, ValuePhiNode> materializedPhis = new HashMap<>();
-        private final Map<ValueNode, ValuePhiNode[]> valuePhis = newIdentityMap();
-        private final Map<ValuePhiNode, VirtualObjectNode> valueObjectVirtuals = newNodeIdentityMap();
+        private final HashMap<Object, ValuePhiNode> materializedPhis = Context.newMap();
+        private final Map<ValueNode, ValuePhiNode[]> valuePhis = Node.newIdentityMap();
+        private final Map<ValuePhiNode, VirtualObjectNode> valueObjectVirtuals = Node.newIdentityMap();
 
         public MergeProcessor(Block mergeBlock) {
             super(mergeBlock);
@@ -322,7 +321,7 @@
             super.merge(states);
 
             // calculate the set of virtual objects that exist in all predecessors
-            HashSet<VirtualObjectNode> virtualObjTemp = new HashSet<>(states.get(0).getVirtualObjects());
+            Set<VirtualObjectNode> virtualObjTemp = Node.newSet(states.get(0).getVirtualObjects());
             for (int i = 1; i < states.size(); i++) {
                 virtualObjTemp.retainAll(states.get(i).getVirtualObjects());
             }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/VirtualUtil.java	Sun Nov 16 15:48:34 2014 -0800
@@ -23,7 +23,6 @@
 package com.oracle.graal.virtual.phases.ea;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
-import static com.oracle.graal.graph.util.CollectionsAccess.*;
 
 import java.util.*;
 
@@ -43,7 +42,7 @@
         // helper code that determines the paths that keep obsolete nodes alive:
 
         NodeFlood flood = graph.createNodeFlood();
-        Map<Node, Node> path = newIdentityMap();
+        Map<Node, Node> path = Node.newIdentityMap();
         flood.add(graph.start());
         for (Node current : flood) {
             if (current instanceof AbstractEndNode) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInterface.java	Sun Nov 16 15:44:38 2014 -0800
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInterface.java	Sun Nov 16 15:48:34 2014 -0800
@@ -24,29 +24,10 @@
  */
 package com.oracle.truffle.api.nodes;
 
-import com.oracle.truffle.api.source.*;
-
 /**
  * Common base interface for all Truffle nodes.
  *
  * @see Node
  */
 public interface NodeInterface {
-    SourceSection getSourceSection();
-
-    SourceSection getEncapsulatingSourceSection();
-
-    Node copy();
-
-    <T extends Node> T replace(T newNode, CharSequence reason);
-
-    <T extends Node> T replace(T newNode);
-
-    Node getParent();
-
-    void accept(NodeVisitor nodeVisitor);
-
-    Iterable<Node> getChildren();
-
-    RootNode getRootNode();
 }