changeset 15973:b048110014ff

Merge with ef43e8c355ade5ed058a5496f6e51ff4af66f0c0
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Wed, 28 May 2014 20:36:10 -0700
parents 6ee370b4d452 (current diff) ef43e8c355ad (diff)
children 3a537502f40f
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSymbol.java
diffstat 97 files changed, 842 insertions(+), 1093 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Wed May 28 20:36:10 2014 -0700
@@ -97,20 +97,14 @@
     }
 
     @Override
-    public boolean canStoreConstant(Constant c, boolean isCompressed) {
+    public boolean canStoreConstant(Constant c) {
         // there is no immediate move of 64-bit constants on Intel
         switch (c.getKind()) {
             case Long:
-                if (isCompressed) {
-                    return true;
-                }
                 return Util.isInt(c.asLong()) && !getCodeCache().needsDataPatch(c);
             case Double:
                 return false;
             case Object:
-                if (isCompressed) {
-                    return true;
-                }
                 return c.isNull();
             default:
                 return true;
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/FieldIntrospection.java	Wed May 28 20:36:10 2014 -0700
@@ -86,7 +86,7 @@
             Class<?> currentClazz = clazz;
             do {
                 for (Field field : currentClazz.getDeclaredFields()) {
-                    if (Modifier.isStatic(field.getModifiers())) {
+                    if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers())) {
                         continue;
                     }
                     Class<?> type = field.getType();
--- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java	Wed May 28 20:36:10 2014 -0700
@@ -208,6 +208,9 @@
         if (!(otherStamp instanceof IntegerStamp)) {
             return StampFactory.illegal(Kind.Illegal);
         }
+        if (equals(otherStamp)) {
+            return this;
+        }
         IntegerStamp other = (IntegerStamp) otherStamp;
         return createStamp(other, Math.max(upperBound, other.upperBound), Math.min(lowerBound, other.lowerBound), downMask & other.downMask, upMask | other.upMask);
     }
--- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java	Wed May 28 20:36:10 2014 -0700
@@ -62,7 +62,7 @@
     }
 
     @Override
-    public boolean canStoreConstant(Constant c, boolean isCompressed) {
+    public boolean canStoreConstant(Constant c) {
         // Operand b must be in the .reg state space.
         return false;
     }
--- a/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler.ptx/src/com/oracle/graal/compiler/ptx/PTXLIRGenerator.java	Wed May 28 20:36:10 2014 -0700
@@ -95,7 +95,7 @@
     }
 
     @Override
-    public boolean canStoreConstant(Constant c, boolean isCompressed) {
+    public boolean canStoreConstant(Constant c) {
         // Operand b must be in the .reg state space.
         return false;
     }
--- a/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler.sparc/src/com/oracle/graal/compiler/sparc/SPARCLIRGenerator.java	Wed May 28 20:36:10 2014 -0700
@@ -63,7 +63,7 @@
     }
 
     @Override
-    public boolean canStoreConstant(Constant c, boolean isCompressed) {
+    public boolean canStoreConstant(Constant c) {
         // SPARC can only store integer null constants (via g0)
         switch (c.getKind()) {
             case Float:
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java	Wed May 28 20:36:10 2014 -0700
@@ -53,6 +53,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.*;
+import com.oracle.graal.phases.common.inlining.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
@@ -85,6 +86,33 @@
     private final Backend backend;
     private final Suites suites;
 
+    /**
+     * Can be overridden by unit tests to verify properties of the graph.
+     *
+     * @param graph the graph at the end of HighTier
+     */
+    protected boolean checkHighTierGraph(StructuredGraph graph) {
+        return true;
+    }
+
+    /**
+     * Can be overridden by unit tests to verify properties of the graph.
+     *
+     * @param graph the graph at the end of MidTier
+     */
+    protected boolean checkMidTierGraph(StructuredGraph graph) {
+        return true;
+    }
+
+    /**
+     * Can be overridden by unit tests to verify properties of the graph.
+     *
+     * @param graph the graph at the end of LowTier
+     */
+    protected boolean checkLowTierGraph(StructuredGraph graph) {
+        return true;
+    }
+
     private static boolean substitutionsInstalled;
 
     private void installSubstitutions() {
@@ -94,10 +122,43 @@
         }
     }
 
+    protected Suites createSuites() {
+        Suites ret = backend.getSuites().createSuites();
+        ret.getHighTier().findPhase(InliningPhase.class).add(new Phase("ComputeLoopFrequenciesPhase") {
+
+            @Override
+            protected void run(StructuredGraph graph) {
+                ComputeLoopFrequenciesClosure.compute(graph);
+            }
+        });
+        ret.getHighTier().appendPhase(new Phase("CheckGraphPhase") {
+
+            @Override
+            protected void run(StructuredGraph graph) {
+                assert checkHighTierGraph(graph);
+            }
+        });
+        ret.getMidTier().appendPhase(new Phase("CheckGraphPhase") {
+
+            @Override
+            protected void run(StructuredGraph graph) {
+                assert checkMidTierGraph(graph);
+            }
+        });
+        ret.getLowTier().appendPhase(new Phase("CheckGraphPhase") {
+
+            @Override
+            protected void run(StructuredGraph graph) {
+                assert checkLowTierGraph(graph);
+            }
+        });
+        return ret;
+    }
+
     public GraalCompilerTest() {
         this.backend = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend();
         this.providers = getBackend().getProviders();
-        this.suites = backend.getSuites().createSuites();
+        this.suites = createSuites();
         installSubstitutions();
     }
 
@@ -117,7 +178,7 @@
             this.backend = runtime.getHostBackend();
         }
         this.providers = backend.getProviders();
-        this.suites = backend.getSuites().createSuites();
+        this.suites = createSuites();
         installSubstitutions();
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchProcessor.java	Wed May 28 20:36:10 2014 -0700
@@ -45,7 +45,7 @@
  * be retrieved as follows:
  *
  * <pre>
- *     ServiceLoader<MatchStatementSet> sl = ServiceLoader.loadInstalled(MatchStatementSet.class);
+ *     Iterable<MatchStatementSet> sl = Services.load(MatchStatementSet.class);
  *     for (MatchStatementSet rules : sl) {
  *         ...
  *     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java	Wed May 28 20:36:10 2014 -0700
@@ -27,6 +27,7 @@
 import java.util.*;
 import java.util.Map.Entry;
 
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.gen.*;
 import com.oracle.graal.debug.*;
@@ -125,7 +126,7 @@
      */
     public static Map<Class<? extends ValueNode>, List<MatchStatement>> createRules(Class<? extends NodeLIRBuilder> theClass, NodeClassLookup lookup) {
         HashMap<Class<? extends NodeLIRBuilder>, MatchStatementSet> matchSets = new HashMap<>();
-        ServiceLoader<MatchStatementSet> sl = ServiceLoader.loadInstalled(MatchStatementSet.class);
+        Iterable<MatchStatementSet> sl = Services.load(MatchStatementSet.class);
         for (MatchStatementSet rules : sl) {
             matchSets.put(rules.forClass(), rules);
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java	Wed May 28 20:36:10 2014 -0700
@@ -24,9 +24,10 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.compiler.gen.*;
 
-public interface MatchStatementSet {
+public interface MatchStatementSet extends Service {
     /**
      * @return the {@link NodeLIRBuilder} subclass which defined this set of {@link MatchStatement}
      *         instances.
--- a/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugHistogramTest.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.debug.test/src/com/oracle/graal/debug/test/DebugHistogramTest.java	Wed May 28 20:36:10 2014 -0700
@@ -111,7 +111,7 @@
         DebugHistogram histogram = Debug.createHistogram("TestHistogram");
         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
         histogram.add("MyCustomValue");
-        new DebugHistogramAsciiPrinter(new PrintStream(outputStream), Integer.MAX_VALUE, 10, 10).print(histogram);
+        new DebugHistogramAsciiPrinter(new PrintStream(outputStream), Integer.MAX_VALUE, 10, 10, 1).print(histogram);
         String[] lines = outputStream.toString().split("\n");
         Assert.assertEquals(4, lines.length);
         Assert.assertEquals("TestHistogram has 1 unique elements and 1 total elements:", lines[0]);
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugHistogram.java	Wed May 28 20:36:10 2014 -0700
@@ -40,16 +40,18 @@
      */
     void add(Object value);
 
+    void add(Object value, long count);
+
     /**
      * A value and a frequency. The ordering imposed by {@link #compareTo(CountedValue)} places
      * values with higher frequencies first.
      */
     public class CountedValue implements Comparable<CountedValue> {
 
-        private int count;
+        private long count;
         private final Object value;
 
-        public CountedValue(int count, Object value) {
+        public CountedValue(long count, Object value) {
             this.count = count;
             this.value = value;
         }
@@ -72,11 +74,11 @@
             count++;
         }
 
-        public void add(int n) {
+        public void add(long n) {
             count += n;
         }
 
-        public int getCount() {
+        public long getCount() {
             return count;
         }
 
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramAsciiPrinter.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramAsciiPrinter.java	Wed May 28 20:36:10 2014 -0700
@@ -37,14 +37,16 @@
     public static final int NumberSize = 10;
     public static final int DefaultNameSize = 50;
     public static final int DefaultBarSize = 100;
+    public static final int DefaultScale = 1;
 
-    private PrintStream os;
-    private int limit;
-    private int nameSize;
-    private int barSize;
+    private final PrintStream os;
+    private final int limit;
+    private final int nameSize;
+    private final int barSize;
+    private final int scale;
 
     public DebugHistogramAsciiPrinter(PrintStream os) {
-        this(os, Integer.MAX_VALUE, DefaultNameSize, DefaultBarSize);
+        this(os, Integer.MAX_VALUE, DefaultNameSize, DefaultBarSize, DefaultScale);
     }
 
     /**
@@ -52,12 +54,14 @@
      * @param limit limits printing to the {@code limit} most frequent values
      * @param nameSize the width of the value names column
      * @param barSize the width of the value frequency column
+     * @param scale a factor by which every result is divided
      */
-    public DebugHistogramAsciiPrinter(PrintStream os, int limit, int nameSize, int barSize) {
+    public DebugHistogramAsciiPrinter(PrintStream os, int limit, int nameSize, int barSize, int scale) {
         this.os = os;
         this.limit = limit;
         this.nameSize = nameSize;
         this.barSize = barSize;
+        this.scale = scale;
     }
 
     public void print(DebugHistogram histogram) {
@@ -68,21 +72,18 @@
         }
 
         // Sum up the total number of elements.
-        int total = 0;
-        for (CountedValue cv : list) {
-            total += cv.getCount();
-        }
+        long total = list.stream().mapToLong(CountedValue::getCount).sum();
 
         // Print header.
-        os.printf("%s has %d unique elements and %d total elements:%n", histogram.getName(), list.size(), total);
+        os.printf("%s has %d unique elements and %d total elements:%n", histogram.getName(), list.size(), total / scale);
 
-        int max = list.get(0).getCount();
+        long max = list.get(0).getCount() / scale;
         final int lineSize = nameSize + NumberSize + barSize + 10;
         printLine(os, '-', lineSize);
         String formatString = "| %-" + nameSize + "s | %-" + NumberSize + "d | %-" + barSize + "s |\n";
         for (int i = 0; i < list.size() && i < limit; ++i) {
             CountedValue cv = list.get(i);
-            int value = cv.getCount();
+            long value = cv.getCount() / scale;
             char[] bar = new char[(int) (((double) value / (double) max) * barSize)];
             Arrays.fill(bar, '=');
             String objectString = String.valueOf(cv.getValue());
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramImpl.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugHistogramImpl.java	Wed May 28 20:36:10 2014 -0700
@@ -44,6 +44,15 @@
         }
     }
 
+    public void add(Object value, long count) {
+        CountedValue cv = map.get(value);
+        if (cv == null) {
+            map.put(value, new CountedValue(count, value));
+        } else {
+            cv.add(count);
+        }
+    }
+
     @Override
     public String getName() {
         return name;
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MemUseTrackerImpl.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/MemUseTrackerImpl.java	Wed May 28 20:36:10 2014 -0700
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.debug.internal;
 
+import static java.lang.Thread.*;
+
 import java.lang.management.*;
 
 import com.oracle.graal.debug.*;
@@ -31,6 +33,15 @@
 
     private static final ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
 
+    /**
+     * The amount of memory allocated by {@link ThreadMXBean#getThreadAllocatedBytes(long)} itself.
+     */
+    private static final long threadMXBeanOverhead = -getCurrentThreadAllocatedBytes() + getCurrentThreadAllocatedBytes();
+
+    private static long getCurrentThreadAllocatedBytes() {
+        return threadMXBean.getThreadAllocatedBytes(currentThread().getId()) - threadMXBeanOverhead;
+    }
+
     public static final Closeable VOID_CLOSEABLE = new Closeable() {
 
         @Override
@@ -84,12 +95,12 @@
 
         private CloseableImpl() {
             this.parent = currentTracker.get();
-            this.start = threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId());
+            this.start = getCurrentThreadAllocatedBytes();
         }
 
         @Override
         public void close() {
-            long end = threadMXBean.getThreadAllocatedBytes(Thread.currentThread().getId());
+            long end = getCurrentThreadAllocatedBytes();
             long allocated = end - start;
             if (parent != null) {
                 parent.nestedAmountToSubtract += allocated;
--- a/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeMapTest.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.graph.test/src/com/oracle/graal/graph/test/NodeMapTest.java	Wed May 28 20:36:10 2014 -0700
@@ -121,17 +121,4 @@
         map.setAndGrow(newNode, 1);
         assertEquals((Integer) 1, map.get(newNode));
     }
-
-    @Test(expected = AssertionError.class)
-    public void testNewSetAndGrowMultiple() {
-        TestNode newNode = graph.add(new TestNode());
-        map.setAndGrow(newNode, 1);
-        assertEquals((Integer) 1, map.get(newNode));
-        /*
-         * Failing here is not required, but if this behavior changes, usages of getAndGrow and
-         * setAndGrow need to be checked for compatibility.
-         */
-        TestNode newNode2 = graph.add(new TestNode());
-        map.get(newNode2);
-    }
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java	Wed May 28 20:36:10 2014 -0700
@@ -740,11 +740,7 @@
     }
 
     public NodeBitMap createNodeBitMap() {
-        return createNodeBitMap(false);
-    }
-
-    public NodeBitMap createNodeBitMap(boolean autoGrow) {
-        return new NodeBitMap(this, autoGrow);
+        return new NodeBitMap(this);
     }
 
     public <T> NodeMap<T> createNodeMap() {
@@ -756,11 +752,11 @@
     }
 
     public NodeWorkList createNodeWorkList() {
-        return new NodeWorkList(this);
+        return new NodeWorkList.SingletonNodeWorkList(this);
     }
 
-    public NodeWorkList createNodeWorkList(boolean fill, int iterationLimitPerNode) {
-        return new NodeWorkList(this, fill, iterationLimitPerNode);
+    public NodeWorkList createIterativeNodeWorkList(boolean fill, int iterationLimitPerNode) {
+        return new NodeWorkList.IterativeNodeWorkList(this, fill, iterationLimitPerNode);
     }
 
     void register(Node node) {
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeBitMap.java	Wed May 28 20:36:10 2014 -0700
@@ -27,92 +27,109 @@
 import com.oracle.graal.graph.iterators.*;
 
 public final class NodeBitMap implements NodeIterable<Node> {
+    private static final int SHIFT = 6;
 
-    private final boolean autoGrow;
-    private final BitSet bitMap;
+    private long[] bits;
     private int nodeCount;
     private final NodeIdAccessor nodeIdAccessor;
 
     public NodeBitMap(Graph graph) {
-        this(graph, false);
+        nodeCount = graph.nodeIdCount();
+        bits = new long[sizeForNodeCount(nodeCount)];
+        this.nodeIdAccessor = new NodeIdAccessor(graph);
     }
 
-    public NodeBitMap(Graph graph, boolean autoGrow) {
-        this(graph, autoGrow, graph.nodeIdCount(), new BitSet(graph.nodeIdCount()));
+    private static int sizeForNodeCount(int nodeCount) {
+        return (nodeCount + Long.SIZE - 1) >> SHIFT;
     }
 
-    private NodeBitMap(Graph graph, boolean autoGrow, int nodeCount, BitSet bits) {
-        this.nodeIdAccessor = new NodeIdAccessor(graph);
-        this.autoGrow = autoGrow;
-        this.nodeCount = nodeCount;
-        bitMap = bits;
+    private NodeBitMap(NodeBitMap other) {
+        this.bits = other.bits.clone();
+        this.nodeCount = other.nodeCount;
+        this.nodeIdAccessor = other.nodeIdAccessor;
     }
 
     public Graph graph() {
         return nodeIdAccessor.getGraph();
     }
 
-    public void setUnion(NodeBitMap other) {
-        bitMap.or(other.bitMap);
-    }
-
-    public void negate() {
-        grow();
-        bitMap.flip(0, nodeCount);
-    }
-
-    public boolean isNotNewMarked(Node node) {
-        return !isNew(node) && isMarked(node);
-    }
-
-    public boolean isNotNewNotMarked(Node node) {
-        return !isNew(node) && !isMarked(node);
-    }
-
-    public boolean isMarked(Node node) {
-        return bitMap.get(nodeIdAccessor.getNodeId(node));
-    }
-
     public boolean isNew(Node node) {
         return nodeIdAccessor.getNodeId(node) >= nodeCount;
     }
 
+    public boolean isMarked(Node node) {
+        assert check(node, false);
+        int id = nodeIdAccessor.getNodeId(node);
+        return (bits[id >> SHIFT] & (1L << id)) != 0;
+    }
+
+    public boolean isMarkedAndGrow(Node node) {
+        assert check(node, true);
+        int id = nodeIdAccessor.getNodeId(node);
+        checkGrow(id);
+        return (bits[id >> SHIFT] & (1L << id)) != 0;
+    }
+
     public void mark(Node node) {
-        if (autoGrow && isNew(node)) {
-            grow();
-        }
-        assert check(node);
-        bitMap.set(nodeIdAccessor.getNodeId(node));
+        assert check(node, false);
+        int id = nodeIdAccessor.getNodeId(node);
+        bits[id >> SHIFT] |= (1L << id);
+    }
+
+    public void markAndGrow(Node node) {
+        assert check(node, true);
+        int id = nodeIdAccessor.getNodeId(node);
+        checkGrow(id);
+        bits[id >> SHIFT] |= (1L << id);
     }
 
     public void clear(Node node) {
-        if (autoGrow && isNew(node)) {
-            return;
+        assert check(node, false);
+        int id = nodeIdAccessor.getNodeId(node);
+        bits[id >> SHIFT] &= ~(1L << id);
+    }
+
+    public void clearAndGrow(Node node) {
+        assert check(node, true);
+        int id = nodeIdAccessor.getNodeId(node);
+        checkGrow(id);
+        bits[id >> SHIFT] &= ~(1L << id);
+    }
+
+    private void checkGrow(int id) {
+        if (id >= nodeCount) {
+            if ((id >> SHIFT) >= bits.length) {
+                grow();
+            } else {
+                nodeCount = id + 1;
+            }
         }
-        assert check(node);
-        bitMap.clear(nodeIdAccessor.getNodeId(node));
     }
 
     public void clearAll() {
-        bitMap.clear();
+        Arrays.fill(bits, 0);
     }
 
     public void intersect(NodeBitMap other) {
         assert graph() == other.graph();
-        bitMap.and(other.bitMap);
-    }
-
-    public void grow(Node node) {
-        nodeCount = Math.max(nodeCount, nodeIdAccessor.getNodeId(node) + 1);
+        int commonLength = Math.min(bits.length, other.bits.length);
+        for (int i = commonLength; i < bits.length; i++) {
+            bits[i] = 0;
+        }
+        for (int i = 0; i < commonLength; i++) {
+            bits[i] &= other.bits[i];
+        }
     }
 
-    public void grow() {
+    private void grow() {
         nodeCount = Math.max(nodeCount, graph().nodeIdCount());
+        int newLength = Math.max((bits.length * 3 / 2) + 1, sizeForNodeCount(nodeCount));
+        bits = Arrays.copyOf(bits, newLength);
     }
 
-    private boolean check(Node node) {
+    private boolean check(Node node, boolean grow) {
         assert node.graph() == graph() : "this node is not part of the graph";
-        assert !isNew(node) : "node was added to the graph after creating the node bitmap: " + node;
+        assert grow || !isNew(node) : "node was added to the graph after creating the node bitmap: " + node;
         assert node.isAlive() : "node is deleted!";
         return true;
     }
@@ -175,12 +192,8 @@
         return new MarkedNodeIterator(NodeBitMap.this, graph().getNodes().iterator());
     }
 
-    public int cardinality() {
-        return bitMap.cardinality();
-    }
-
     public NodeBitMap copy() {
-        return new NodeBitMap(graph(), autoGrow, nodeCount, (BitSet) bitMap.clone());
+        return new NodeBitMap(this);
     }
 
     @Override
@@ -190,7 +203,11 @@
 
     @Override
     public int count() {
-        return bitMap.cardinality();
+        int count = 0;
+        for (long l : bits) {
+            count += Long.bitCount(l);
+        }
+        return count;
     }
 
     @Override
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeMap.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeMap.java	Wed May 28 20:36:10 2014 -0700
@@ -28,6 +28,8 @@
 
 public class NodeMap<T> extends NodeIdAccessor {
 
+    private static final int MIN_REALLOC_SIZE = 16;
+
     protected Object[] values;
 
     public NodeMap(Graph graph) {
@@ -54,7 +56,7 @@
 
     private void checkAndGrow(Node node) {
         if (isNew(node)) {
-            this.values = Arrays.copyOf(values, graph.nodeIdCount());
+            this.values = Arrays.copyOf(values, Math.max(MIN_REALLOC_SIZE, graph.nodeIdCount() * 3 / 2));
         }
         assert check(node);
     }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/NodeWorkList.java	Wed May 28 20:36:10 2014 -0700
@@ -24,23 +24,11 @@
 
 import java.util.*;
 
-public class NodeWorkList implements Iterable<Node> {
+public abstract class NodeWorkList implements Iterable<Node> {
 
-    private final NodeBitMap visited;
-    private final NodeBitMap inQueue;
-    private final Queue<Node> worklist;
-    private int iterationLimit = Integer.MAX_VALUE;
-    private Node firstNoChange;
-    private Node lastPull;
-    private Node lastChain;
+    protected final Queue<Node> worklist;
 
-    public NodeWorkList(Graph graph) {
-        this(graph, false, -1);
-    }
-
-    public NodeWorkList(Graph graph, boolean fill, int iterationLimitPerNode) {
-        visited = graph.createNodeBitMap();
-        inQueue = graph.createNodeBitMap();
+    private NodeWorkList(Graph graph, boolean fill) {
         if (fill) {
             ArrayDeque<Node> deque = new ArrayDeque<>(graph.getNodeCount());
             for (Node node : graph.getNodes()) {
@@ -50,9 +38,6 @@
         } else {
             worklist = new ArrayDeque<>();
         }
-        if (iterationLimitPerNode > 0) {
-            iterationLimit = iterationLimitPerNode * graph.getNodeCount();
-        }
     }
 
     public void addAll(Iterable<? extends Node> nodes) {
@@ -63,111 +48,13 @@
         }
     }
 
-    public void add(Node node) {
-        if (node != null) {
-            if (visited.isNew(node)) {
-                visited.grow(node);
-                inQueue.grow(node);
-            }
-            if (!visited.isMarked(node)) {
-                addAgain(node);
-            }
-        }
-    }
+    public abstract void add(Node node);
 
-    public void addAgain(Node node) {
-        if (visited.isNew(node)) {
-            visited.grow(node);
-            inQueue.grow(node);
-        }
-        if (node != null && !inQueue.isMarked(node)) {
-            if (lastPull == node) {
-                if (firstNoChange == null) {
-                    firstNoChange = node;
-                    lastChain = node;
-                } else if (node == firstNoChange) {
-                    throw new InfiniteWorkException("ReAdded " + node);
-                } else {
-                    lastChain = node;
-                }
-            } else {
-                firstNoChange = null;
-            }
-            visited.mark(node);
-            inQueue.mark(node);
-            worklist.add(node);
-        }
-    }
-
-    public void clearVisited() {
-        visited.clearAll();
-    }
-
-    public void replaced(Node newNode, Node oldNode) {
-        this.replaced(newNode, oldNode, false);
-    }
+    private abstract class QueueConsumingIterator implements Iterator<Node> {
 
-    public void replaced(Node newNode, Node oldNode, boolean add) {
-        worklist.remove(oldNode);
-        if (newNode == null) {
-            return;
-        }
-        if (add) {
-            this.add(newNode);
-        }
-        for (Node n : newNode.usages()) {
-            addAgain(n);
-        }
-    }
-
-    public boolean isMarked(Node node) {
-        return visited.isMarked(node);
-    }
-
-    public boolean isNew(Node node) {
-        return visited.isNew(node);
-    }
-
-    public boolean isEmpty() {
-        return worklist.isEmpty();
-    }
-
-    public boolean isInQueue(Node node) {
-        return !inQueue.isNew(node) && inQueue.isMarked(node);
-    }
-
-    private class QueueConsumingIterator implements Iterator<Node> {
-
-        private final Queue<Node> queue;
-
-        public QueueConsumingIterator(Queue<Node> queue) {
-            this.queue = queue;
-        }
-
-        @Override
-        public boolean hasNext() {
-            dropDeleted();
-            return iterationLimit > 0 && !queue.isEmpty();
-        }
-
-        @Override
-        public Node next() {
-            if (iterationLimit-- <= 0) {
-                throw new NoSuchElementException();
-            }
-            dropDeleted();
-            Node node = queue.remove();
-            if (lastPull != lastChain) {
-                firstNoChange = null;
-            }
-            lastPull = node;
-            inQueue.clear(node);
-            return node;
-        }
-
-        private void dropDeleted() {
-            while (!queue.isEmpty() && queue.peek().isDeleted()) {
-                queue.remove();
+        protected void dropDeleted() {
+            while (!worklist.isEmpty() && worklist.peek().isDeleted()) {
+                worklist.remove();
             }
         }
 
@@ -177,74 +64,142 @@
         }
     }
 
-    @Override
-    public Iterator<Node> iterator() {
-        return new QueueConsumingIterator(worklist);
-    }
-
-    private static class UnmarkedNodeIterator implements Iterator<Node> {
+    public static final class IterativeNodeWorkList extends NodeWorkList {
 
-        private final NodeBitMap visited;
-        private Iterator<Node> nodes;
-        private Node nextNode;
-
-        public UnmarkedNodeIterator(NodeBitMap visited, Iterator<Node> nodes) {
-            this.visited = visited;
-            this.nodes = nodes;
-            forward();
-        }
+        private static final int EXPLICIT_BITMAP_THRESHOLD = 10;
+        protected NodeBitMap inQueue;
 
-        private void forward() {
-            do {
-                if (!nodes.hasNext()) {
-                    nextNode = null;
-                    return;
-                }
-                nextNode = nodes.next();
-            } while (visited.isMarked(nextNode));
-        }
+        private int iterationLimit = Integer.MAX_VALUE;
+        private Node firstNoChange;
+        private Node lastPull;
+        private Node lastChain;
 
-        @Override
-        public boolean hasNext() {
-            return nextNode != null;
-        }
-
-        @Override
-        public Node next() {
-            try {
-                return nextNode;
-            } finally {
-                forward();
+        public IterativeNodeWorkList(Graph graph, boolean fill, int iterationLimitPerNode) {
+            super(graph, fill);
+            if (iterationLimitPerNode > 0) {
+                iterationLimit = iterationLimitPerNode * graph.getNodeCount();
             }
         }
 
         @Override
-        public void remove() {
-            throw new UnsupportedOperationException();
+        public Iterator<Node> iterator() {
+            return new QueueConsumingIterator() {
+                @Override
+                public boolean hasNext() {
+                    dropDeleted();
+                    return iterationLimit > 0 && !worklist.isEmpty();
+                }
+
+                @Override
+                public Node next() {
+                    if (iterationLimit-- <= 0) {
+                        throw new NoSuchElementException();
+                    }
+                    dropDeleted();
+                    Node node = worklist.remove();
+                    assert updateInfiniteWork(node);
+                    if (inQueue != null) {
+                        inQueue.clearAndGrow(node);
+                    }
+                    return node;
+                }
+
+                private boolean updateInfiniteWork(Node node) {
+                    if (lastPull != lastChain) {
+                        firstNoChange = null;
+                    }
+                    lastPull = node;
+                    return true;
+                }
+            };
         }
 
+        @Override
+        public void add(Node node) {
+            if (node != null) {
+                if (inQueue != null) {
+                    if (inQueue.isMarkedAndGrow(node)) {
+                        return;
+                    }
+                } else {
+                    if (worklist.size() > EXPLICIT_BITMAP_THRESHOLD) {
+                        inflateToBitMap(node.graph());
+                    } else {
+                        for (Node queuedNode : worklist) {
+                            if (queuedNode == node) {
+                                return;
+                            }
+                        }
+                    }
+                }
+                assert checkInfiniteWork(node) : "Readded " + node;
+                if (inQueue != null) {
+                    inQueue.markAndGrow(node);
+                }
+                worklist.add(node);
+            }
+        }
+
+        private boolean checkInfiniteWork(Node node) {
+            if (lastPull == node) {
+                if (firstNoChange == null) {
+                    firstNoChange = node;
+                    lastChain = node;
+                } else if (node == firstNoChange) {
+                    return false;
+                } else {
+                    lastChain = node;
+                }
+            } else {
+                firstNoChange = null;
+            }
+            return true;
+        }
+
+        private void inflateToBitMap(Graph graph) {
+            assert inQueue == null;
+            inQueue = graph.createNodeBitMap();
+            for (Node queuedNode : worklist) {
+                if (queuedNode.isAlive()) {
+                    inQueue.mark(queuedNode);
+                }
+            }
+        }
     }
 
-    public Iterable<Node> unmarkedNodes() {
-        return new Iterable<Node>() {
+    public static final class SingletonNodeWorkList extends NodeWorkList {
+        protected final NodeBitMap visited;
 
-            @Override
-            public Iterator<Node> iterator() {
-                return new UnmarkedNodeIterator(visited, visited.graph().getNodes().iterator());
-            }
-        };
-    }
-
-    public static class InfiniteWorkException extends RuntimeException {
-
-        private static final long serialVersionUID = -5319329402219396658L;
-
-        public InfiniteWorkException() {
-            super();
+        public SingletonNodeWorkList(Graph graph) {
+            super(graph, false);
+            visited = graph.createNodeBitMap();
         }
 
-        public InfiniteWorkException(String message) {
-            super(message);
+        @Override
+        public void add(Node node) {
+            if (node != null) {
+                if (!visited.isMarkedAndGrow(node)) {
+                    visited.mark(node);
+                    worklist.add(node);
+                }
+            }
+        }
+
+        @Override
+        public Iterator<Node> iterator() {
+            return new QueueConsumingIterator() {
+                @Override
+                public boolean hasNext() {
+                    dropDeleted();
+                    return !worklist.isEmpty();
+                }
+
+                @Override
+                public Node next() {
+                    dropDeleted();
+                    return worklist.remove();
+                }
+            };
         }
     }
 }
--- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctPredicatedProxyNodeIterator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/iterators/DistinctPredicatedProxyNodeIterator.java	Wed May 28 20:36:10 2014 -0700
@@ -50,7 +50,7 @@
             return true;
         }
         if (visited == null) {
-            visited = n.graph().createNodeBitMap(true);
+            visited = n.graph().createNodeBitMap();
         }
         boolean accept = !visited.isMarked(n);
         visited.mark(n);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotEnterUnpackFramesStackFrameOp.java	Wed May 28 20:36:10 2014 -0700
@@ -29,7 +29,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.amd64.*;
@@ -37,7 +37,7 @@
 
 /**
  * Emits code that enters a stack frame which is tailored to call the C++ method
- * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}.
+ * {@link HotSpotBackend#UNPACK_FRAMES Deoptimization::unpack_frames}.
  */
 @Opcode("ENTER_UNPACK_FRAMES_STACK_FRAME")
 final class AMD64HotSpotEnterUnpackFramesStackFrameOp extends AMD64LIRInstruction {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Wed May 28 20:36:10 2014 -0700
@@ -42,7 +42,6 @@
 import com.oracle.graal.hotspot.amd64.AMD64HotSpotMove.HotSpotStoreConstantOp;
 import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.hotspot.meta.*;
-import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.nodes.type.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
@@ -323,7 +322,7 @@
     }
 
     public Value emitDeoptimizationFetchUnrollInfoCall(SaveRegistersOp saveRegisterOp) {
-        ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(DeoptimizationFetchUnrollInfoCallNode.FETCH_UNROLL_INFO);
+        ForeignCallLinkage linkage = getForeignCalls().lookupForeignCall(FETCH_UNROLL_INFO);
 
         Register thread = getProviders().getRegisters().getThreadRegister();
         append(new AMD64HotSpotCRuntimeCallPrologueOp(config.threadLastJavaSpOffset(), thread));
@@ -479,7 +478,7 @@
         AMD64AddressValue storeAddress = asAddressValue(address);
         if (isConstant(inputVal)) {
             Constant c = asConstant(inputVal);
-            if (canStoreConstant(c, false)) {
+            if (canStoreConstant(c)) {
                 append(new HotSpotStoreConstantOp(getMemoryKind(kind), storeAddress, c, state));
                 return;
             }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLeaveUnpackFramesStackFrameOp.java	Wed May 28 20:36:10 2014 -0700
@@ -25,7 +25,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.lir.amd64.*;
@@ -33,7 +33,7 @@
 
 /**
  * Emits code that leaves a stack frame which is tailored to call the C++ method
- * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}.
+ * {@link HotSpotBackend#UNPACK_FRAMES Deoptimization::unpack_frames}.
  */
 @Opcode("LEAVE_UNPACK_FRAMES_STACK_FRAME")
 final class AMD64HotSpotLeaveUnpackFramesStackFrameOp extends AMD64LIRInstruction {
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Wed May 28 20:36:10 2014 -0700
@@ -25,7 +25,6 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
-import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
@@ -38,44 +37,11 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.lir.amd64.*;
-import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
 import com.oracle.graal.lir.amd64.AMD64Move.StoreConstantOp;
 import com.oracle.graal.lir.asm.*;
 
 public class AMD64HotSpotMove {
 
-    public static class StoreCompressedConstantOp extends StoreConstantOp {
-
-        public StoreCompressedConstantOp(Kind kind, AMD64AddressValue address, Constant input, LIRFrameState state) {
-            super(kind, address, input, state);
-        }
-
-        @Override
-        public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            if (kind == Kind.Long) {
-                if (NumUtil.isInt(input.asLong())) {
-                    if (input instanceof HotSpotMetaspaceConstant) {
-                        crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(input), true));
-                    }
-                    masm.movl(address.toAddress(), (int) input.asLong());
-                } else {
-                    throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                }
-            } else if (kind == Kind.Object) {
-                if (input.isNull()) {
-                    masm.movl(address.toAddress(), 0);
-                } else if (crb.target.inlineObjects) {
-                    crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(input), true));
-                    masm.movl(address.toAddress(), 0xDEADDEAD);
-                } else {
-                    throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
-                }
-            } else {
-                throw GraalInternalError.shouldNotReachHere("Attempt to store compressed constant of wrong type.");
-            }
-        }
-    }
-
     public static class HotSpotLoadConstantOp extends AMD64LIRInstruction implements MoveOp {
 
         @Def({REG, STACK}) private AllocatableValue result;
@@ -276,175 +242,6 @@
         }
     }
 
-    public static class LoadCompressedPointer extends LoadOp {
-
-        private final CompressEncoding encoding;
-        @Temp({REG, ILLEGAL}) protected AllocatableValue scratch;
-
-        public LoadCompressedPointer(Kind kind, AllocatableValue result, AllocatableValue scratch, AMD64AddressValue address, LIRFrameState state, CompressEncoding encoding) {
-            super(kind, result, address, state);
-            this.encoding = encoding;
-            this.scratch = scratch != null ? scratch : Value.ILLEGAL;
-            assert kind == Kind.Object || kind == Kind.Long;
-        }
-
-        @Override
-        public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            Register resRegister = asRegister(result);
-            if (kind == Kind.Object) {
-                masm.movl(resRegister, address.toAddress());
-                decodePointer(masm, resRegister, asRegister(scratch), encoding);
-            } else {
-                Register base = scratch.equals(Value.ILLEGAL) ? null : asRegister(scratch);
-                decodeKlassPointer(masm, resRegister, base, address.toAddress(), encoding);
-            }
-        }
-    }
-
-    public static class StoreCompressedPointer extends AMD64LIRInstruction {
-
-        protected final Kind kind;
-        private final Register heapBaseReg;
-        private final CompressEncoding encoding;
-        @Temp({REG}) private AllocatableValue scratch;
-        @Alive({REG}) protected Value input;
-        @Alive({COMPOSITE}) protected AMD64AddressValue address;
-        @State protected LIRFrameState state;
-
-        public StoreCompressedPointer(Kind kind, AMD64AddressValue address, AllocatableValue input, AllocatableValue scratch, LIRFrameState state, CompressEncoding encoding, Register heapBaseReg) {
-            this.encoding = encoding;
-            this.heapBaseReg = heapBaseReg;
-            this.scratch = scratch;
-            this.kind = kind;
-            this.address = address;
-            this.state = state;
-            this.input = input;
-            assert kind == Kind.Object || kind == Kind.Long;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            masm.movq(asRegister(scratch), asRegister(input));
-            if (kind == Kind.Long && (encoding.base & 0xffffffffL) == 0 && encoding.shift == 0) {
-                // Compressing the pointer won't change the low 32 bits, so just store it
-                masm.movl(address.toAddress(), asRegister(input));
-            } else if (kind == Kind.Object) {
-                encodePointer(masm, asRegister(scratch), heapBaseReg, encoding);
-            } else {
-                masm.movq(asRegister(scratch), asRegister(input));
-                if (kind == Kind.Object) {
-                    encodePointer(masm, asRegister(scratch), heapBaseReg, encoding);
-                } else {
-                    assert !asRegister(scratch).equals(heapBaseReg) : "need to restore value otherwise";
-                    encodeKlassPointer(masm, asRegister(scratch), heapBaseReg, encoding);
-                }
-                if (state != null) {
-                    crb.recordImplicitException(masm.position(), state);
-                }
-                masm.movl(address.toAddress(), asRegister(scratch));
-            }
-            if (state != null) {
-                crb.recordImplicitException(masm.position(), state);
-            }
-            masm.movl(address.toAddress(), asRegister(scratch));
-        }
-    }
-
-    @Opcode("CAS")
-    public static class CompareAndSwapCompressedOp extends AMD64LIRInstruction {
-
-        @Def protected AllocatableValue result;
-        @Alive({COMPOSITE}) protected AMD64AddressValue address;
-        @Alive protected AllocatableValue cmpValue;
-        @Alive protected AllocatableValue newValue;
-        @Temp({REG}) protected AllocatableValue scratch;
-
-        private CompressEncoding encoding;
-        private final Register heapBaseReg;
-
-        public CompareAndSwapCompressedOp(AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue, AllocatableValue newValue, AllocatableValue scratch,
-                        CompressEncoding encoding, Register heapBaseReg) {
-            this.heapBaseReg = heapBaseReg;
-            this.scratch = scratch;
-            this.encoding = encoding;
-            this.result = result;
-            this.address = address;
-            this.cmpValue = cmpValue;
-            this.newValue = newValue;
-            assert cmpValue.getKind() == Kind.Object;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            compareAndSwapCompressed(crb, masm, result, address, cmpValue, newValue, scratch, encoding, heapBaseReg);
-        }
-    }
-
-    protected static void compareAndSwapCompressed(CompilationResultBuilder crb, AMD64MacroAssembler masm, AllocatableValue result, AMD64AddressValue address, AllocatableValue cmpValue,
-                    AllocatableValue newValue, AllocatableValue scratch, CompressEncoding encoding, Register heapBaseReg) {
-        assert AMD64.rax.equals(asRegister(cmpValue)) && AMD64.rax.equals(asRegister(result));
-        final Register scratchRegister = asRegister(scratch);
-        final Register cmpRegister = asRegister(cmpValue);
-        final Register newRegister = asRegister(newValue);
-        Register heapBase = heapBaseReg;
-        encodePointer(masm, cmpRegister, heapBase, encoding);
-        masm.movq(scratchRegister, newRegister);
-        encodePointer(masm, scratchRegister, heapBase, encoding);
-        if (crb.target.isMP) {
-            masm.lock();
-        }
-        masm.cmpxchgl(scratchRegister, address.toAddress());
-    }
-
-    private static void encodePointer(AMD64MacroAssembler masm, Register scratchRegister, Register heapBaseRegister, CompressEncoding encoding) {
-        // If the base is zero, the uncompressed address has to be shifted right
-        // in order to be compressed.
-        if (encoding.base == 0) {
-            if (encoding.shift != 0) {
-                assert encoding.alignment == encoding.shift : "Encode algorithm is wrong";
-                masm.shrq(scratchRegister, encoding.alignment);
-            }
-        } else {
-            // Otherwise the heap base, which resides always in register 12, is subtracted
-            // followed by right shift.
-            masm.testq(scratchRegister, scratchRegister);
-            // If the stored reference is null, move the heap to scratch
-            // register and then calculate the compressed oop value.
-            masm.cmovq(ConditionFlag.Equal, scratchRegister, heapBaseRegister);
-            masm.subq(scratchRegister, heapBaseRegister);
-            masm.shrq(scratchRegister, encoding.alignment);
-        }
-    }
-
-    public static void decodePointer(AMD64MacroAssembler masm, Register resRegister, Register heapBaseRegister, CompressEncoding encoding) {
-        // If the base is zero, the compressed address has to be shifted left
-        // in order to be uncompressed.
-        if (encoding.base == 0) {
-            if (encoding.shift != 0) {
-                assert encoding.alignment == encoding.shift : "Decode algorithm is wrong";
-                masm.shlq(resRegister, encoding.alignment);
-            }
-        } else {
-            Label done = new Label();
-            masm.shlq(resRegister, encoding.alignment);
-            masm.jccb(ConditionFlag.Equal, done);
-            // Otherwise the heap base is added to the shifted address.
-            masm.addq(resRegister, heapBaseRegister);
-            masm.bind(done);
-        }
-    }
-
-    private static void encodeKlassPointer(AMD64MacroAssembler masm, Register scratchRegister, Register heapBaseRegister, CompressEncoding encoding) {
-        if (encoding.base != 0) {
-            masm.movq(heapBaseRegister, encoding.base);
-            masm.subq(scratchRegister, heapBaseRegister);
-        }
-        if (encoding.shift != 0) {
-            assert encoding.alignment == encoding.shift : "Encode algorithm is wrong";
-            masm.shrq(scratchRegister, encoding.alignment);
-        }
-    }
-
     public static void decodeKlassPointer(AMD64MacroAssembler masm, Register register, Register scratch, AMD64Address address, CompressEncoding encoding) {
         masm.movl(register, address);
         if (encoding.shift != 0) {
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Wed May 28 20:36:10 2014 -0700
@@ -93,7 +93,7 @@
     }
 
     @Override
-    public boolean canStoreConstant(Constant c, boolean isCompressed) {
+    public boolean canStoreConstant(Constant c) {
         return !(c instanceof HotSpotObjectConstant);
     }
 
@@ -134,7 +134,7 @@
             if (HotSpotCompressedNullConstant.COMPRESSED_NULL.equals(c)) {
                 c = Constant.INT_0;
             }
-            if (canStoreConstant(c, false)) {
+            if (canStoreConstant(c)) {
                 append(new StoreConstantOp(getMemoryKind(kind), storeAddress, c, state));
                 return;
             }
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXWrapperBuilder.java	Wed May 28 20:36:10 2014 -0700
@@ -211,7 +211,7 @@
             for (int slot : objectSlots) {
                 int offset = slot * wordSize;
                 LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, Kind.Int, index * intSize, getGraph());
-                append(new WriteNode(objectParametersOffsets, ConstantNode.forInt(offset, getGraph()), location, BarrierType.NONE, false, false));
+                append(new WriteNode(objectParametersOffsets, ConstantNode.forInt(offset, getGraph()), location, BarrierType.NONE, false));
                 index++;
             }
         }
@@ -234,12 +234,12 @@
             ParameterNode javaParameter = javaParameters[javaParametersIndex];
             int javaParameterOffset = javaParameterOffsetsInKernelParametersBuffer[javaParametersIndex];
             LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, javaParameter.getKind(), javaParameterOffset, getGraph());
-            append(new WriteNode(buf, javaParameter, location, BarrierType.NONE, false, false));
+            append(new WriteNode(buf, javaParameter, location, BarrierType.NONE, false));
             updateDimArg(method, sig, sigIndex++, args, javaParameter);
         }
         if (returnKind != Kind.Void) {
             LocationNode location = ConstantLocationNode.create(FINAL_LOCATION, wordKind, bufSize - wordSize, getGraph());
-            append(new WriteNode(buf, nullWord, location, BarrierType.NONE, false, false));
+            append(new WriteNode(buf, nullWord, location, BarrierType.NONE, false));
         }
 
         HIRFrameStateBuilder fsb = new HIRFrameStateBuilder(method, getGraph(), true);
--- a/graal/com.oracle.graal.hotspot.sourcegen/src/com/oracle/graal/hotspot/sourcegen/GenGraalRuntimeInlineHpp.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sourcegen/src/com/oracle/graal/hotspot/sourcegen/GenGraalRuntimeInlineHpp.java	Wed May 28 20:36:10 2014 -0700
@@ -77,24 +77,42 @@
             }
         }
 
-        out.println("Handle GraalRuntime::get_service_impls(KlassHandle serviceKlass, TRAPS) {");
+        Set<Integer> lengths = new TreeSet<>();
         for (Class<?> service : services) {
-            out.printf("  if (serviceKlass->name()->equals(\"%s\")) {%n", toInternalName(service));
-            List<Class<?>> impls = new ArrayList<>();
-            for (Object impl : ServiceLoader.load(service)) {
-                impls.add(impl.getClass());
+            lengths.add(toInternalName(service).length());
+        }
+
+        out.println("Handle GraalRuntime::get_service_impls(KlassHandle serviceKlass, TRAPS) {");
+        out.println("  switch (serviceKlass->name()->utf8_length()) {");
+        for (int len : lengths) {
+            boolean printedCase = false;
+            for (Class<?> service : services) {
+                String serviceName = toInternalName(service);
+                if (len == serviceName.length()) {
+                    if (!printedCase) {
+                        printedCase = true;
+                        out.println("  case " + len + ":");
+                    }
+                    out.printf("    if (serviceKlass->name()->equals(\"%s\", %d)) {%n", serviceName, serviceName.length());
+                    List<Class<?>> impls = new ArrayList<>();
+                    for (Object impl : ServiceLoader.load(service)) {
+                        impls.add(impl.getClass());
+                    }
+
+                    out.printf("      objArrayOop servicesOop = oopFactory::new_objArray(serviceKlass(), %d, CHECK_NH);%n", impls.size());
+                    out.println("      objArrayHandle services(THREAD, servicesOop);");
+                    for (int i = 0; i < impls.size(); i++) {
+                        String name = toInternalName(impls.get(i));
+                        out.printf("      %sservice = create_Service(\"%s\", CHECK_NH);%n", (i == 0 ? "Handle " : ""), name);
+                        out.printf("      services->obj_at_put(%d, service());%n", i);
+                    }
+                    out.println("      return services;");
+                    out.println("    }");
+                }
             }
 
-            out.printf("    objArrayOop servicesOop = oopFactory::new_objArray(serviceKlass(), %d, CHECK_NH);%n", impls.size());
-            out.println("    objArrayHandle services(THREAD, servicesOop);");
-            for (int i = 0; i < impls.size(); i++) {
-                String name = toInternalName(impls.get(i));
-                out.printf("    %sservice = create_Service(\"%s\", CHECK_NH);%n", (i == 0 ? "Handle " : ""), name);
-                out.printf("    services->obj_at_put(%d, service());%n", i);
-            }
-            out.println("    return services;");
-            out.println("  }");
         }
+        out.println("  }");
         out.println("  return Handle();");
         out.println("}");
     }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotEnterUnpackFramesStackFrameOp.java	Wed May 28 20:36:10 2014 -0700
@@ -30,14 +30,14 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
  * Emits code that enters a stack frame which is tailored to call the C++ method
- * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}.
+ * {@link HotSpotBackend#UNPACK_FRAMES Deoptimization::unpack_frames}.
  */
 @Opcode("ENTER_UNPACK_FRAMES_STACK_FRAME")
 final class SPARCHotSpotEnterUnpackFramesStackFrameOp extends SPARCLIRInstruction {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLIRGenerator.java	Wed May 28 20:36:10 2014 -0700
@@ -43,7 +43,6 @@
 import com.oracle.graal.lir.sparc.SPARCMove.NullCheckOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StoreConstantOp;
 import com.oracle.graal.lir.sparc.SPARCMove.StoreOp;
-import com.oracle.graal.nodes.extended.*;
 
 public class SPARCHotSpotLIRGenerator extends SPARCLIRGenerator implements HotSpotLIRGenerator {
 
@@ -167,33 +166,11 @@
         append(new SPARCHotSpotDeoptimizeCallerOp());
     }
 
-    private static boolean isCompressCandidate(Access access) {
-        return access != null && access.isCompressible();
-    }
-
     @Override
     public Variable emitLoad(PlatformKind kind, Value address, LIRFrameState state) {
         SPARCAddressValue loadAddress = asAddressValue(address);
         Variable result = newVariable(kind);
-        if (isCompressCandidate(null)) {
-            if (config.useCompressedOops && kind == Kind.Object) {
-                // append(new LoadCompressedPointer(kind, result, loadAddress, access != null ?
-                // state(access) :
-                // null, config.narrowOopBase, config.narrowOopShift,
-                // config.logMinObjAlignment));
-                throw GraalInternalError.unimplemented();
-            } else if (config.useCompressedClassPointers && kind == Kind.Long) {
-                // append(new LoadCompressedPointer(kind, result, loadAddress, access != null ?
-                // state(access) :
-                // null, config.narrowKlassBase, config.narrowKlassShift,
-                // config.logKlassAlignment));
-                throw GraalInternalError.unimplemented();
-            } else {
-                append(new LoadOp((Kind) kind, result, loadAddress, state));
-            }
-        } else {
-            append(new LoadOp((Kind) kind, result, loadAddress, state));
-        }
+        append(new LoadOp((Kind) kind, result, loadAddress, state));
         return result;
     }
 
@@ -202,42 +179,13 @@
         SPARCAddressValue storeAddress = asAddressValue(address);
         if (isConstant(inputVal)) {
             Constant c = asConstant(inputVal);
-            if (canStoreConstant(c, isCompressCandidate(null))) {
-                if (inputVal.getKind() == Kind.Object) {
-                    append(new StoreConstantOp((Kind) kind, storeAddress, c, state, config.useCompressedOops && isCompressCandidate(null)));
-                } else if (inputVal.getKind() == Kind.Long) {
-                    append(new StoreConstantOp((Kind) kind, storeAddress, c, state, config.useCompressedClassPointers && isCompressCandidate(null)));
-                } else {
-                    append(new StoreConstantOp((Kind) kind, storeAddress, c, state, false));
-                }
+            if (canStoreConstant(c)) {
+                append(new StoreConstantOp((Kind) kind, storeAddress, c, state));
                 return;
             }
         }
         Variable input = load(inputVal);
-        if (isCompressCandidate(null)) {
-            if (config.useCompressedOops && kind == Kind.Object) {
-                // if (input.getKind() == Kind.Object) {
-                // Variable scratch = newVariable(Kind.Long);
-                // append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state,
-                // config.narrowOopBase, config.narrowOopShift,
-                // config.logMinObjAlignment));
-                // } else {
-                // // the input oop is already compressed
-                // append(new StoreOp(input.getKind(), storeAddress, input, state));
-                // }
-                throw GraalInternalError.unimplemented();
-            } else if (config.useCompressedClassPointers && kind == Kind.Long) {
-                // Variable scratch = newVariable(Kind.Long);
-                // append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state,
-                // config.narrowKlassBase, config.narrowKlassShift,
-                // config.logKlassAlignment));
-                throw GraalInternalError.unimplemented();
-            } else {
-                append(new StoreOp((Kind) kind, storeAddress, input, state));
-            }
-        } else {
-            append(new StoreOp((Kind) kind, storeAddress, input, state));
-        }
+        append(new StoreOp((Kind) kind, storeAddress, input, state));
     }
 
     public Value emitCompareAndSwap(Value address, Value expectedValue, Value newValue, Value trueValue, Value falseValue) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotLeaveUnpackFramesStackFrameOp.java	Wed May 28 20:36:10 2014 -0700
@@ -27,14 +27,14 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.asm.sparc.*;
-import com.oracle.graal.hotspot.stubs.*;
+import com.oracle.graal.hotspot.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.sparc.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
  * Emits code that leaves a stack frame which is tailored to call the C++ method
- * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}.
+ * {@link HotSpotBackend#UNPACK_FRAMES Deoptimization::unpack_frames}.
  */
 @Opcode("LEAVE_UNPACK_FRAMES_STACK_FRAME")
 final class SPARCHotSpotLeaveUnpackFramesStackFrameOp extends SPARCLIRInstruction {
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java	Wed May 28 20:36:10 2014 -0700
@@ -23,15 +23,18 @@
 package com.oracle.graal.hotspot.test;
 
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
+
 import java.lang.ref.*;
 import java.lang.reflect.*;
 
 import com.oracle.graal.phases.common.inlining.policy.InlineEverythingPolicy;
+
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.test.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
@@ -160,7 +163,7 @@
     }
 
     public static Object test5Snippet() throws Exception {
-        return UnsafeLoadNode.load(wr, useCompressedOops() ? 12 : 16, Kind.Object, LocationIdentity.ANY_LOCATION);
+        return UnsafeAccess.unsafe.getObject(wr, useCompressedOops() ? 12L : 16L);
     }
 
     /**
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Wed May 28 20:36:10 2014 -0700
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot;
 
+import static com.oracle.graal.hotspot.stubs.StubUtil.*;
+
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
@@ -72,6 +74,16 @@
     private final HotSpotGraalRuntime runtime;
 
     /**
+     * @see DeoptimizationFetchUnrollInfoCallNode
+     */
+    public static final ForeignCallDescriptor FETCH_UNROLL_INFO = new ForeignCallDescriptor("fetchUnrollInfo", Word.class, long.class);
+
+    /**
+     * @see DeoptimizationStub#unpackFrames(ForeignCallDescriptor, Word, int)
+     */
+    public static final ForeignCallDescriptor UNPACK_FRAMES = newDescriptor(DeoptimizationStub.class, "unpackFrames", int.class, Word.class, int.class);
+
+    /**
      * @see AESCryptSubstitutions#encryptBlockStub(ForeignCallDescriptor, Word, Word, Word)
      */
     public static final ForeignCallDescriptor ENCRYPT_BLOCK = new ForeignCallDescriptor("encrypt_block", void.class, Word.class, Word.class, Word.class);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotSymbol.java	Wed May 28 20:33:49 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot;
-
-import static com.oracle.graal.compiler.common.UnsafeAccess.*;
-import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*;
-
-import java.io.*;
-
-import com.oracle.graal.compiler.common.*;
-
-/**
- * Represents a metaspace {@code Symbol}.
- */
-public class HotSpotSymbol {
-
-    private final long metaspaceSymbol;
-
-    public HotSpotSymbol(long metaspaceSymbol) {
-        assert metaspaceSymbol != 0;
-        this.metaspaceSymbol = metaspaceSymbol;
-    }
-
-    /**
-     * Decodes this {@code Symbol} and returns the symbol string as {@link java.lang.String}.
-     */
-    public String asString() {
-        return readModifiedUTF8(asByteArray());
-    }
-
-    private static String readModifiedUTF8(byte[] buf) {
-        try {
-            final int length = buf.length;
-            byte[] tmp = new byte[length + 2];
-            // write modified UTF-8 length as short in big endian
-            tmp[0] = (byte) ((length >>> 8) & 0xFF);
-            tmp[1] = (byte) ((length >>> 0) & 0xFF);
-            // copy the data
-            System.arraycopy(buf, 0, tmp, 2, length);
-            DataInputStream dis = new DataInputStream(new ByteArrayInputStream(tmp));
-            return dis.readUTF();
-        } catch (IOException e) {
-            // This should never happen so let's fail hard here.
-            throw GraalInternalError.shouldNotReachHere("error reading symbol: " + e);
-        }
-    }
-
-    private byte[] asByteArray() {
-        final int length = getLength();
-        byte[] result = new byte[length];
-        for (int index = 0; index < length; index++) {
-            result[index] = getByteAt(index);
-        }
-        return result;
-    }
-
-    private int getLength() {
-        return unsafe.getShort(metaspaceSymbol + runtime().getConfig().symbolLengthOffset);
-    }
-
-    private byte getByteAt(int index) {
-        return unsafe.getByte(metaspaceSymbol + runtime().getConfig().symbolBodyOffset + index);
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVmSymbols.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVmSymbols.java	Wed May 28 20:36:10 2014 -0700
@@ -32,17 +32,17 @@
 public final class HotSpotVmSymbols {
 
     /**
-     * Returns the {@link HotSpotSymbol} in the {@code vmSymbols} table at position {@code index} as
-     * {@link String}.
-     * 
+     * Returns the symbol in the {@code vmSymbols} table at position {@code index} as {@link String}
+     * .
+     *
      * @param index position in the symbol table
      * @return the symbol at position id
      */
     public static String symbolAt(int index) {
-        HotSpotVMConfig config = runtime().getConfig();
+        HotSpotGraalRuntime runtime = runtime();
+        HotSpotVMConfig config = runtime.getConfig();
         assert config.vmSymbolsFirstSID <= index && index < config.vmSymbolsSIDLimit : "index " + index + " is out of bounds";
         assert config.symbolPointerSize == Unsafe.ADDRESS_SIZE : "the following address read is broken";
-        final long metaspaceSymbol = unsafe.getAddress(config.vmSymbolsSymbols + index * config.symbolPointerSize);
-        return new HotSpotSymbol(metaspaceSymbol).asString();
+        return runtime.getCompilerToVM().getSymbol(unsafe.getAddress(config.vmSymbolsSymbols + index * config.symbolPointerSize));
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Wed May 28 20:36:10 2014 -0700
@@ -123,9 +123,9 @@
 
     int lookupNameAndTypeRefIndexInPool(long metaspaceConstantPool, int cpi);
 
-    long lookupNameRefInPool(long metaspaceConstantPool, int cpi);
+    String lookupNameRefInPool(long metaspaceConstantPool, int cpi);
 
-    long lookupSignatureRefInPool(long metaspaceConstantPool, int cpi);
+    String lookupSignatureRefInPool(long metaspaceConstantPool, int cpi);
 
     int lookupKlassRefIndexInPool(long metaspaceConstantPool, int cpi);
 
@@ -333,6 +333,13 @@
     long getTimeStamp();
 
     /**
+     * Gets the value of a metaspace {@code Symbol} as a String.
+     * 
+     * @param metaspaceSymbol
+     */
+    String getSymbol(long metaspaceSymbol);
+
+    /**
      * Looks for the next Java stack frame with the given method.
      *
      * @param frame the starting point of the search, where {@code null} refers to the topmost frame
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Wed May 28 20:36:10 2014 -0700
@@ -71,10 +71,10 @@
     public native int lookupNameAndTypeRefIndexInPool(long metaspaceConstantPool, int cpi);
 
     @Override
-    public native long lookupNameRefInPool(long metaspaceConstantPool, int cpi);
+    public native String lookupNameRefInPool(long metaspaceConstantPool, int cpi);
 
     @Override
-    public native long lookupSignatureRefInPool(long metaspaceConstantPool, int cpi);
+    public native String lookupSignatureRefInPool(long metaspaceConstantPool, int cpi);
 
     @Override
     public native int lookupKlassRefIndexInPool(long metaspaceConstantPool, int cpi);
@@ -181,6 +181,8 @@
 
     public native long getTimeStamp();
 
+    public native String getSymbol(long metaspaceSymbol);
+
     public native void resolveInvokeDynamic(long metaspaceConstantPool, int index);
 
     public native int getVtableIndexForInterface(long metaspaceKlass, long metaspaceMethod);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java	Wed May 28 20:36:10 2014 -0700
@@ -383,11 +383,11 @@
             throw new GraalInternalError("too many counters, reduce number of counters or increase -XX:GraalCounterSize=... (current value: " + config.graalCountersSize + ")");
         }
         ConstantLocationNode arrayLocation = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, wordKind, config.graalCountersThreadOffset, graph);
-        ReadNode readArray = graph.add(new ReadNode(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE, false));
+        ReadNode readArray = graph.add(new ReadNode(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE));
         ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Kind.Long, Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph);
-        ReadNode read = graph.add(new ReadNode(readArray, location, StampFactory.forKind(Kind.Long), BarrierType.NONE, false));
+        ReadNode read = graph.add(new ReadNode(readArray, location, StampFactory.forKind(Kind.Long), BarrierType.NONE));
         IntegerAddNode add = graph.unique(new IntegerAddNode(StampFactory.forKind(Kind.Long), read, counter.getIncrement()));
-        WriteNode write = graph.add(new WriteNode(readArray, add, location, BarrierType.NONE, false));
+        WriteNode write = graph.add(new WriteNode(readArray, add, location, BarrierType.NONE));
 
         graph.addBeforeFixed(counter, thread);
         graph.addBeforeFixed(counter, readArray);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Wed May 28 20:36:10 2014 -0700
@@ -194,7 +194,7 @@
                     // compiled code entry as HotSpot does not guarantee they are final
                     // values.
                     ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, ConstantLocationNode.create(ANY_LOCATION, wordKind, runtime.getConfig().methodCompiledEntryOffset, graph),
-                                    StampFactory.forKind(wordKind), BarrierType.NONE, false));
+                                    StampFactory.forKind(wordKind), BarrierType.NONE));
 
                     loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(),
                                     CallingConvention.Type.JavaCall));
@@ -305,7 +305,7 @@
                 int size = HIRFrameStateBuilder.stackSlots(osrLocal.getKind());
                 int offset = localsOffset - (osrLocal.index() + size - 1) * 8;
                 IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, osrLocal.getKind(), offset, ConstantNode.forLong(0, graph), graph, 1);
-                ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE, false));
+                ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE));
                 osrLocal.replaceAndDelete(load);
                 graph.addBeforeFixed(migrationEnd, load);
             }
@@ -388,7 +388,7 @@
         assert vtableEntryOffset > 0;
         // We use LocationNode.ANY_LOCATION for the reads that access the vtable
         // entry as HotSpot does not guarantee that this is a final value.
-        ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind), BarrierType.NONE, false));
+        ReadNode metaspaceMethod = graph.add(new ReadNode(hub, ConstantLocationNode.create(ANY_LOCATION, wordKind, vtableEntryOffset, graph), StampFactory.forKind(wordKind), BarrierType.NONE));
         return metaspaceMethod;
     }
 
@@ -406,7 +406,7 @@
             hubStamp = StampFactory.forKind(wordKind);
         }
 
-        FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(object, location, null, hubStamp, guard, BarrierType.NONE, false));
+        FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(object, location, null, hubStamp, guard, BarrierType.NONE));
         if (config.useCompressedClassPointers) {
             return CompressionNode.uncompress(memoryRead, config.getKlassEncoding());
         } else {
@@ -424,7 +424,7 @@
             writeValue = CompressionNode.compress(value, config.getKlassEncoding());
         }
 
-        return graph.add(new WriteNode(object, writeValue, location, BarrierType.NONE, false));
+        return graph.add(new WriteNode(object, writeValue, location, BarrierType.NONE));
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantPool.java	Wed May 28 20:36:10 2014 -0700
@@ -256,9 +256,7 @@
      * @return name as {@link String}
      */
     private String getNameRefAt(int index) {
-        final long name = runtime().getCompilerToVM().lookupNameRefInPool(metaspaceConstantPool, index);
-        HotSpotSymbol symbol = new HotSpotSymbol(name);
-        return symbol.asString();
+        return runtime().getCompilerToVM().lookupNameRefInPool(metaspaceConstantPool, index);
     }
 
     /**
@@ -282,9 +280,7 @@
      * @return signature as {@link String}
      */
     private String getSignatureRefAt(int index) {
-        final long name = runtime().getCompilerToVM().lookupSignatureRefInPool(metaspaceConstantPool, index);
-        HotSpotSymbol symbol = new HotSpotSymbol(name);
-        return symbol.asString();
+        return runtime().getCompilerToVM().lookupSignatureRefInPool(metaspaceConstantPool, index);
     }
 
     /**
@@ -383,9 +379,7 @@
     @Override
     public String lookupUtf8(int cpi) {
         assertTag(cpi, JVM_CONSTANT.Utf8);
-        final long metaspaceSymbol = getEntryAt(cpi);
-        HotSpotSymbol symbol = new HotSpotSymbol(metaspaceSymbol);
-        return symbol.asString();
+        return runtime().getCompilerToVM().getSymbol(getEntryAt(cpi));
     }
 
     @Override
@@ -412,10 +406,11 @@
      * @param metaspacePointer either a metaspace Klass or a metaspace Symbol
      */
     private static JavaType getJavaType(final long metaspacePointer) {
-        HotSpotVMConfig config = runtime().getConfig();
+        HotSpotGraalRuntime runtime = runtime();
+        HotSpotVMConfig config = runtime.getConfig();
         if ((metaspacePointer & config.compilerToVMSymbolTag) != 0) {
             final long metaspaceSymbol = metaspacePointer & ~config.compilerToVMSymbolTag;
-            String name = new HotSpotSymbol(metaspaceSymbol).asString();
+            String name = runtime.getCompilerToVM().getSymbol(metaspaceSymbol);
             return HotSpotUnresolvedJavaType.create("L" + name + ";");
         } else {
             assert (metaspacePointer & config.compilerToVMKlassTag) == 0;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotHostForeignCallsProvider.java	Wed May 28 20:36:10 2014 -0700
@@ -34,7 +34,6 @@
 import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*;
 import static com.oracle.graal.hotspot.replacements.ThreadSubstitutions.*;
 import static com.oracle.graal.hotspot.replacements.WriteBarrierSnippets.*;
-import static com.oracle.graal.hotspot.stubs.DeoptimizationStub.*;
 import static com.oracle.graal.hotspot.stubs.ExceptionHandlerStub.*;
 import static com.oracle.graal.hotspot.stubs.NewArrayStub.*;
 import static com.oracle.graal.hotspot.stubs.NewInstanceStub.*;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaField.java	Wed May 28 20:36:10 2014 -0700
@@ -216,23 +216,29 @@
             // Canonicalization may attempt to process an unsafe read before
             // processing a guard (e.g. a null check or a type check) for this read
             // so we need to check the object being read
-            if (object != null && isInObject(object)) {
+            if (object != null) {
                 if (isFinal()) {
-                    Constant value = readValue(receiver);
-                    if (assumeNonStaticFinalFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) {
-                        return value;
+                    if (isInObject(object)) {
+                        Constant value = readValue(receiver);
+                        if (assumeNonStaticFinalFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) {
+                            return value;
+                        }
                     }
                 } else if (isStable()) {
-                    Constant value = readValue(receiver);
-                    if (assumeDefaultStableFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) {
-                        return value;
+                    if (isInObject(object)) {
+                        Constant value = readValue(receiver);
+                        if (assumeDefaultStableFieldsAsFinal(object.getClass()) || !value.isDefaultForKind()) {
+                            return value;
+                        }
                     }
                 } else {
                     Class<?> clazz = object.getClass();
                     if (StableOptionValue.class.isAssignableFrom(clazz)) {
-                        assert getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this;
-                        StableOptionValue<?> option = (StableOptionValue<?>) object;
-                        return HotSpotObjectConstant.forObject(option.getValue());
+                        if (isInObject(object)) {
+                            assert getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this;
+                            StableOptionValue<?> option = (StableOptionValue<?>) object;
+                            return HotSpotObjectConstant.forObject(option.getValue());
+                        }
                     }
                 }
             }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DeoptimizationFetchUnrollInfoCallNode.java	Wed May 28 20:36:10 2014 -0700
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.hotspot.nodes;
 
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
@@ -41,7 +43,6 @@
 
     @Input private SaveAllRegistersNode registerSaver;
     private final ForeignCallsProvider foreignCalls;
-    public static final ForeignCallDescriptor FETCH_UNROLL_INFO = new ForeignCallDescriptor("fetchUnrollInfo", Word.class, Word.class);
 
     public DeoptimizationFetchUnrollInfoCallNode(@InjectedNodeParameter ForeignCallsProvider foreignCalls, ValueNode registerSaver) {
         super(StampFactory.forKind(Kind.fromJavaClass(FETCH_UNROLL_INFO.getResultType())));
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EnterUnpackFramesStackFrameNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/EnterUnpackFramesStackFrameNode.java	Wed May 28 20:36:10 2014 -0700
@@ -25,7 +25,6 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
@@ -33,7 +32,7 @@
 
 /**
  * Emits code to enter a low-level stack frame specifically to call out to the C++ method
- * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}.
+ * {@link HotSpotBackend#UNPACK_FRAMES Deoptimization::unpack_frames}.
  */
 public class EnterUnpackFramesStackFrameNode extends FixedWithNextNode implements LIRLowerable {
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveUnpackFramesStackFrameNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/LeaveUnpackFramesStackFrameNode.java	Wed May 28 20:36:10 2014 -0700
@@ -24,14 +24,13 @@
 
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.hotspot.*;
-import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.StandardOp.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.spi.*;
 
 /**
  * Emits code to leave a low-level stack frame specifically to call out to the C++ method
- * {@link DeoptimizationStub#UNPACK_FRAMES Deoptimization::unpack_frames}.
+ * {@link HotSpotBackend#UNPACK_FRAMES Deoptimization::unpack_frames}.
  */
 public class LeaveUnpackFramesStackFrameNode extends FixedWithNextNode implements LIRLowerable {
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/DeoptimizationStub.java	Wed May 28 20:36:10 2014 -0700
@@ -22,8 +22,9 @@
  */
 package com.oracle.graal.hotspot.stubs;
 
+import static com.oracle.graal.hotspot.HotSpotBackend.*;
+import static com.oracle.graal.hotspot.nodes.DeoptimizationFetchUnrollInfoCallNode.*;
 import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*;
-import static com.oracle.graal.hotspot.stubs.StubUtil.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -111,7 +112,7 @@
         final Word thread = registerAsWord(threadRegister);
         final long registerSaver = SaveAllRegistersNode.saveAllRegisters();
 
-        final Word unrollBlock = DeoptimizationFetchUnrollInfoCallNode.fetchUnrollInfo(registerSaver);
+        final Word unrollBlock = fetchUnrollInfo(registerSaver);
 
         // Pop all the frames we must move/replace.
         //
@@ -271,12 +272,6 @@
         return config().deoptimizationUnpackUncommonTrap;
     }
 
-    public static final ForeignCallDescriptor FETCH_UNROLL_INFO = newDescriptor(DeoptimizationStub.class, "fetchUnrollInfo", Word.class, Word.class);
-    public static final ForeignCallDescriptor UNPACK_FRAMES = newDescriptor(DeoptimizationStub.class, "unpackFrames", int.class, Word.class, int.class);
-
-    @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true)
-    public static native Word fetchUnrollInfo(@ConstantNodeParameter ForeignCallDescriptor fetchUnrollInfo, Word thread);
-
     @NodeIntrinsic(value = StubForeignCallNode.class, setStampFromReturnType = true)
     public static native int unpackFrames(@ConstantNodeParameter ForeignCallDescriptor unpackFrames, Word thread, int mode);
 }
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Wed May 28 20:36:10 2014 -0700
@@ -229,67 +229,6 @@
         }
     }
 
-    public static class LoadCompressedPointer extends LoadOp {
-
-        private final long base;
-        private final int shift;
-        private final int alignment;
-        @Temp({REG}) private AllocatableValue scratch;
-
-        public LoadCompressedPointer(Kind kind, AllocatableValue result, AllocatableValue scratch, HSAILAddressValue address, LIRFrameState state, long base, int shift, int alignment) {
-            super(kind, result, address, state);
-            this.base = base;
-            this.shift = shift;
-            this.alignment = alignment;
-            this.scratch = scratch;
-            assert kind == Kind.Object || kind == Kind.Long;
-        }
-
-        @Override
-        public void emitMemAccess(HSAILAssembler masm) {
-            // we will do a 32 bit load, zero extending into a 64 bit register
-            masm.emitLoad(result, address.toAddress(), "u32");
-            boolean testForNull = (kind == Kind.Object);
-            decodePointer(masm, result, base, shift, alignment, testForNull);
-        }
-    }
-
-    public static class StoreCompressedPointer extends HSAILLIRInstruction {
-
-        protected final Kind kind;
-        private final long base;
-        private final int shift;
-        private final int alignment;
-        @Temp({REG}) private AllocatableValue scratch;
-        @Alive({REG}) protected AllocatableValue input;
-        @Alive({COMPOSITE}) protected HSAILAddressValue address;
-        @State protected LIRFrameState state;
-
-        public StoreCompressedPointer(Kind kind, HSAILAddressValue address, AllocatableValue input, AllocatableValue scratch, LIRFrameState state, long base, int shift, int alignment) {
-            this.base = base;
-            this.shift = shift;
-            this.alignment = alignment;
-            this.scratch = scratch;
-            this.kind = kind;
-            this.address = address;
-            this.state = state;
-            this.input = input;
-            assert kind == Kind.Object || kind == Kind.Long;
-        }
-
-        @Override
-        public void emitCode(CompilationResultBuilder crb, HSAILAssembler masm) {
-            masm.emitMov(kind, scratch, input);
-            boolean testForNull = (kind == Kind.Object);
-            encodePointer(masm, scratch, base, shift, alignment, testForNull);
-            if (state != null) {
-                throw new InternalError("NYI");
-                // crb.recordImplicitException(masm.position(), state);
-            }
-            masm.emitStore(scratch, address.toAddress(), "u32");
-        }
-    }
-
     public static class CompressPointer extends HSAILLIRInstruction {
 
         private final long base;
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Wed May 28 20:36:10 2014 -0700
@@ -329,12 +329,10 @@
     public static class StoreConstantOp extends MemOp {
 
         protected final Constant input;
-        private final boolean compress;
 
-        public StoreConstantOp(Kind kind, SPARCAddressValue address, Constant input, LIRFrameState state, boolean compress) {
+        public StoreConstantOp(Kind kind, SPARCAddressValue address, Constant input, LIRFrameState state) {
             super(kind, address, state);
             this.input = input;
-            this.compress = compress;
             if (!input.isDefaultForKind()) {
                 throw GraalInternalError.shouldNotReachHere("Can only store null constants to memory");
             }
@@ -356,11 +354,7 @@
                     break;
                 case Long:
                 case Object:
-                    if (compress) {
-                        new Stw(g0, address.toAddress()).emit(masm);
-                    } else {
-                        new Stx(g0, address.toAddress()).emit(masm);
-                    }
+                    new Stx(g0, address.toAddress()).emit(masm);
                     break;
                 case Float:
                 case Double:
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java	Wed May 28 20:36:10 2014 -0700
@@ -157,16 +157,6 @@
 
     private LIRGenerationResult res;
 
-    /**
-     * Checks whether the supplied constant can be used without loading it into a register for store
-     * operations, i.e., on the right hand side of a memory access.
-     *
-     * @param c The constant to check.
-     * @return True if the constant can be used directly, false if the constant needs to be in a
-     *         register.
-     */
-    public abstract boolean canStoreConstant(Constant c, boolean isCompressed);
-
     public LIRGenerator(CodeGenProviders providers, CallingConvention cc, LIRGenerationResult res) {
         this.res = res;
         this.providers = providers;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java	Wed May 28 20:36:10 2014 -0700
@@ -101,7 +101,15 @@
      */
     boolean canInlineConstant(Constant c);
 
-    boolean canStoreConstant(Constant c, boolean isCompressed);
+    /**
+     * Checks whether the supplied constant can be used without loading it into a register for store
+     * operations, i.e., on the right hand side of a memory access.
+     *
+     * @param c The constant to check.
+     * @return True if the constant can be used directly, false if the constant needs to be in a
+     *         register.
+     */
+    boolean canStoreConstant(Constant c);
 
     RegisterAttributes attributes(Register register);
 
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Wed May 28 20:36:10 2014 -0700
@@ -66,7 +66,7 @@
     }
 
     public boolean contains(Node n) {
-        return nodes().contains(n);
+        return nodes().isMarkedAndGrow(n);
     }
 
     @SuppressWarnings("unchecked")
@@ -96,7 +96,7 @@
         return original;
     }
 
-    public abstract NodeIterable<Node> nodes();
+    public abstract NodeBitMap nodes();
 
     public StructuredGraph graph() {
         LoopEx l;
@@ -155,7 +155,7 @@
     }
 
     protected static NodeBitMap computeNodes(Graph graph, Iterable<BeginNode> blocks, Iterable<LoopExitNode> earlyExits) {
-        final NodeBitMap nodes = graph.createNodeBitMap(true);
+        final NodeBitMap nodes = graph.createNodeBitMap();
         for (BeginNode b : blocks) {
             if (b.isDeleted()) {
                 continue;
@@ -187,7 +187,7 @@
             }
         }
 
-        final NodeBitMap notloopNodes = graph.createNodeBitMap(true);
+        final NodeBitMap notloopNodes = graph.createNodeBitMap();
         for (BeginNode b : blocks) {
             if (b.isDeleted()) {
                 continue;
@@ -336,8 +336,8 @@
                  *
                  * We now update the original fragment's nodes accordingly:
                  */
-                state.applyToVirtual(node -> original.nodes.clear(node));
-                exitState.applyToVirtual(node -> original.nodes.mark(node));
+                state.applyToVirtual(node -> original.nodes.clearAndGrow(node));
+                exitState.applyToVirtual(node -> original.nodes.markAndGrow(node));
             }
             FrameState finalExitState = exitState;
 
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Wed May 28 20:36:10 2014 -0700
@@ -102,7 +102,7 @@
     }
 
     @Override
-    public NodeIterable<Node> nodes() {
+    public NodeBitMap nodes() {
         if (nodes == null) {
             LoopFragmentWhole whole = loop().whole();
             whole.nodes(); // init nodes bitmap in whole
@@ -203,10 +203,10 @@
         for (LoopExitNode exit : exits()) {
             FrameState exitState = exit.stateAfter();
             if (exitState != null) {
-                exitState.applyToVirtual(v -> usagesToPatch.mark(v));
+                exitState.applyToVirtual(v -> usagesToPatch.markAndGrow(v));
             }
             for (ProxyNode proxy : exit.proxies()) {
-                usagesToPatch.mark(proxy);
+                usagesToPatch.markAndGrow(proxy);
             }
         }
 
@@ -232,7 +232,7 @@
             newPhis.add(newPhi);
             for (Node usage : phi.usages().snapshot()) {
                 // patch only usages that should use the new phi ie usages that were peeled
-                if (usagesToPatch.isMarked(usage)) {
+                if (usagesToPatch.isMarkedAndGrow(usage)) {
                     usage.replaceFirstInput(phi, newPhi);
                 }
             }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideBefore.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideBefore.java	Wed May 28 20:36:10 2014 -0700
@@ -23,7 +23,6 @@
 package com.oracle.graal.loop;
 
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
 
 public class LoopFragmentInsideBefore extends LoopFragmentInside {
@@ -51,8 +50,7 @@
     }
 
     @Override
-    public NodeIterable<Node> nodes() {
-        // TODO Auto-generated method stub
+    public NodeBitMap nodes() {
         return null;
     }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideFrom.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInsideFrom.java	Wed May 28 20:36:10 2014 -0700
@@ -23,7 +23,6 @@
 package com.oracle.graal.loop;
 
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
 
 public class LoopFragmentInsideFrom extends LoopFragmentInside {
@@ -51,8 +50,7 @@
     }
 
     @Override
-    public NodeIterable<Node> nodes() {
-        // TODO Auto-generated method stub
+    public NodeBitMap nodes() {
         return null;
     }
 }
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentWhole.java	Wed May 28 20:36:10 2014 -0700
@@ -25,7 +25,6 @@
 import com.oracle.graal.compiler.common.cfg.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Graph.DuplicationReplacement;
-import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
 
@@ -55,7 +54,7 @@
     }
 
     @Override
-    public NodeIterable<Node> nodes() {
+    public NodeBitMap nodes() {
         if (nodes == null) {
             Loop<Block> lirLoop = loop().lirLoop();
             nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(lirLoop.getBlocks()), LoopFragment.toHirExits(lirLoop.getExits()));
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopPolicies.java	Wed May 28 20:36:10 2014 -0700
@@ -72,7 +72,7 @@
         for (Node successor : controlSplit.successors()) {
             BeginNode branch = (BeginNode) successor;
             // this may count twice because of fall-through in switches
-            inBranchTotal += loop.nodesInLoopFrom(branch, postDom).cardinality();
+            inBranchTotal += loop.nodesInLoopFrom(branch, postDom).count();
             double probability = controlSplit.probability(branch);
             if (probability > maxProbability) {
                 maxProbability = probability;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/HeapAccess.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/HeapAccess.java	Wed May 28 20:36:10 2014 -0700
@@ -49,9 +49,4 @@
      * Gets the write barrier type for that particular access.
      */
     BarrierType getBarrierType();
-
-    /**
-     * Returns whether or not the heap access is a compressed pointer candidate.
-     */
-    boolean isCompressible();
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/IfNode.java	Wed May 28 20:36:10 2014 -0700
@@ -149,65 +149,27 @@
             LogicNegationNode negation = (LogicNegationNode) condition();
             IfNode newIfNode = graph().add(new IfNode(negation.getInput(), falseSucc, trueSucc, 1 - trueSuccessorProbability));
             predecessor().replaceFirstSuccessor(this, newIfNode);
-            this.safeDelete();
+            GraphUtil.killWithUnusedFloatingInputs(this);
             return;
         }
-        if (trueSuccessor().usages().isEmpty() && falseSuccessor().usages().isEmpty()) {
-            // push similar nodes upwards through the if, thereby deduplicating them
-            do {
-                BeginNode trueSucc = trueSuccessor();
-                BeginNode falseSucc = falseSuccessor();
-                if (trueSucc.getClass() == BeginNode.class && falseSucc.getClass() == BeginNode.class && trueSucc.next() instanceof FixedWithNextNode && falseSucc.next() instanceof FixedWithNextNode) {
-                    FixedWithNextNode trueNext = (FixedWithNextNode) trueSucc.next();
-                    FixedWithNextNode falseNext = (FixedWithNextNode) falseSucc.next();
-                    NodeClass nodeClass = trueNext.getNodeClass();
-                    if (trueNext.getClass() == falseNext.getClass()) {
-                        if (nodeClass.inputsEqual(trueNext, falseNext) && nodeClass.valueEqual(trueNext, falseNext)) {
-                            falseNext.replaceAtUsages(trueNext);
-                            graph().removeFixed(falseNext);
-                            FixedNode next = trueNext.next();
-                            trueNext.setNext(null);
-                            trueNext.replaceAtPredecessor(next);
-                            graph().addBeforeFixed(this, trueNext);
-                            for (Node usage : trueNext.usages().snapshot()) {
-                                if (usage.getNodeClass().valueNumberable() && !usage.getNodeClass().isLeafNode()) {
-                                    Node newNode = graph().findDuplicate(usage);
-                                    if (newNode != null) {
-                                        usage.replaceAtUsages(newNode);
-                                        usage.safeDelete();
-                                    }
-                                }
-                                if (usage.isAlive()) {
-                                    tool.addToWorkList(usage);
-                                }
-                            }
-                            continue;
-                        }
-                    }
-                }
-            } while (false);
-        }
-
-        if (checkForUnsignedCompare(tool)) {
-            return;
-        }
-
         if (condition() instanceof LogicConstantNode) {
             LogicConstantNode c = (LogicConstantNode) condition();
             if (c.getValue()) {
                 tool.deleteBranch(falseSuccessor());
                 tool.addToWorkList(trueSuccessor());
                 graph().removeSplit(this, trueSuccessor());
-                return;
             } else {
                 tool.deleteBranch(trueSuccessor());
                 tool.addToWorkList(falseSuccessor());
                 graph().removeSplit(this, falseSuccessor());
-                return;
             }
-        } else if (trueSuccessor().usages().isEmpty() && falseSuccessor().usages().isEmpty()) {
+            return;
+        }
+        if (trueSuccessor().usages().isEmpty() && falseSuccessor().usages().isEmpty()) {
 
-            if (removeOrMaterializeIf(tool)) {
+            pushNodesThroughIf(tool);
+
+            if (checkForUnsignedCompare(tool) || removeOrMaterializeIf(tool)) {
                 return;
             }
         }
@@ -248,6 +210,43 @@
         }
     }
 
+    private void pushNodesThroughIf(SimplifierTool tool) {
+        assert trueSuccessor().usages().isEmpty() && falseSuccessor().usages().isEmpty();
+        // push similar nodes upwards through the if, thereby deduplicating them
+        do {
+            BeginNode trueSucc = trueSuccessor();
+            BeginNode falseSucc = falseSuccessor();
+            if (trueSucc.getClass() == BeginNode.class && falseSucc.getClass() == BeginNode.class && trueSucc.next() instanceof FixedWithNextNode && falseSucc.next() instanceof FixedWithNextNode) {
+                FixedWithNextNode trueNext = (FixedWithNextNode) trueSucc.next();
+                FixedWithNextNode falseNext = (FixedWithNextNode) falseSucc.next();
+                NodeClass nodeClass = trueNext.getNodeClass();
+                if (trueNext.getClass() == falseNext.getClass()) {
+                    if (nodeClass.inputsEqual(trueNext, falseNext) && nodeClass.valueEqual(trueNext, falseNext)) {
+                        falseNext.replaceAtUsages(trueNext);
+                        graph().removeFixed(falseNext);
+                        FixedNode next = trueNext.next();
+                        trueNext.setNext(null);
+                        trueNext.replaceAtPredecessor(next);
+                        graph().addBeforeFixed(this, trueNext);
+                        for (Node usage : trueNext.usages().snapshot()) {
+                            if (usage.getNodeClass().valueNumberable() && !usage.getNodeClass().isLeafNode()) {
+                                Node newNode = graph().findDuplicate(usage);
+                                if (newNode != null) {
+                                    usage.replaceAtUsages(newNode);
+                                    usage.safeDelete();
+                                }
+                            }
+                            if (usage.isAlive()) {
+                                tool.addToWorkList(usage);
+                            }
+                        }
+                        continue;
+                    }
+                }
+            }
+        } while (false);
+    }
+
     /**
      * Recognize a couple patterns that can be merged into an unsigned compare.
      *
@@ -255,7 +254,8 @@
      * @return true if a replacement was done.
      */
     private boolean checkForUnsignedCompare(SimplifierTool tool) {
-        if (condition() instanceof IntegerLessThanNode && trueSuccessor().usages().isEmpty() && falseSuccessor().usages().isEmpty()) {
+        assert trueSuccessor().usages().isEmpty() && falseSuccessor().usages().isEmpty();
+        if (condition() instanceof IntegerLessThanNode) {
             IntegerLessThanNode lessThan = (IntegerLessThanNode) condition();
             Constant y = lessThan.y().stamp().asConstant();
             if (y != null && y.asLong() == 0 && falseSuccessor().next() instanceof IfNode) {
@@ -478,6 +478,7 @@
      * @return true if a transformation was made, false otherwise
      */
     private boolean removeOrMaterializeIf(SimplifierTool tool) {
+        assert trueSuccessor().usages().isEmpty() && falseSuccessor().usages().isEmpty();
         if (trueSuccessor().next() instanceof AbstractEndNode && falseSuccessor().next() instanceof AbstractEndNode) {
             AbstractEndNode trueEnd = (AbstractEndNode) trueSuccessor().next();
             AbstractEndNode falseEnd = (AbstractEndNode) falseSuccessor().next();
@@ -621,6 +622,11 @@
      * @return true if a transformation was made, false otherwise
      */
     private boolean removeIntermediateMaterialization(SimplifierTool tool) {
+        if (!(predecessor() instanceof MergeNode) || predecessor() instanceof LoopBeginNode) {
+            return false;
+        }
+        MergeNode merge = (MergeNode) predecessor();
+
         if (!(condition() instanceof CompareNode)) {
             return false;
         }
@@ -630,16 +636,6 @@
             return false;
         }
 
-        if (!(predecessor() instanceof MergeNode)) {
-            return false;
-        }
-
-        if (predecessor() instanceof LoopBeginNode) {
-            return false;
-        }
-
-        MergeNode merge = (MergeNode) predecessor();
-
         // Only consider merges with a single usage that is both a phi and an operand of the
         // comparison
         NodeIterable<Node> mergeUsages = merge.usages();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/CompareNode.java	Wed May 28 20:36:10 2014 -0700
@@ -26,6 +26,8 @@
 import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.compiler.common.calc.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.*;
@@ -62,6 +64,17 @@
      */
     public abstract boolean unorderedIsTrue();
 
+    protected static final DebugHistogram histogram = Debug.createHistogram("histo");
+
+    static {
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+            @Override
+            public void run() {
+                new DebugHistogramAsciiPrinter(System.out).print(histogram);
+            }
+        });
+    }
+
     private LogicNode optimizeConditional(Constant constant, ConditionalNode conditionalNode, ConstantReflectionProvider constantReflection, Condition cond) {
         Constant trueConstant = conditionalNode.trueValue().asConstant();
         Constant falseConstant = conditionalNode.falseValue().asConstant();
@@ -105,38 +118,42 @@
             return result;
         }
         if (x().isConstant()) {
-            if (y() instanceof ConditionalNode) {
-                return optimizeConditional(x().asConstant(), (ConditionalNode) y(), tool.getConstantReflection(), condition().mirror());
-            } else if (y() instanceof NormalizeCompareNode) {
-                return optimizeNormalizeCmp(x().asConstant(), (NormalizeCompareNode) y(), true);
+            if ((result = canonicalizeSymmetricConstant(tool, x().asConstant(), y(), true)) != this) {
+                return result;
             }
         } else if (y().isConstant()) {
-            if (x() instanceof ConditionalNode) {
-                return optimizeConditional(y().asConstant(), (ConditionalNode) x(), tool.getConstantReflection(), condition());
-            } else if (x() instanceof NormalizeCompareNode) {
-                return optimizeNormalizeCmp(y().asConstant(), (NormalizeCompareNode) x(), false);
+            if ((result = canonicalizeSymmetricConstant(tool, y().asConstant(), x(), false)) != this) {
+                return result;
             }
-        }
-        if (x() instanceof ConvertNode && y() instanceof ConvertNode) {
+        } else if (x() instanceof ConvertNode && y() instanceof ConvertNode) {
             ConvertNode convertX = (ConvertNode) x();
             ConvertNode convertY = (ConvertNode) y();
             if (convertX.preservesOrder(condition()) && convertY.preservesOrder(condition()) && convertX.getInput().stamp().isCompatible(convertY.getInput().stamp())) {
-                setX(convertX.getInput());
-                setY(convertY.getInput());
+                return graph().unique(duplicateModified(convertX.getInput(), convertY.getInput()));
             }
-        } else if (x() instanceof ConvertNode && y().isConstant()) {
-            ConvertNode convertX = (ConvertNode) x();
-            ConstantNode newY = canonicalConvertConstant(tool, convertX, y().asConstant());
-            if (newY != null) {
-                setX(convertX.getInput());
-                setY(newY);
+
+        }
+        return this;
+    }
+
+    protected abstract CompareNode duplicateModified(ValueNode newX, ValueNode newY);
+
+    protected Node canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) {
+        if (nonConstant instanceof BinaryNode) {
+            if (nonConstant instanceof ConditionalNode) {
+                return optimizeConditional(constant, (ConditionalNode) nonConstant, tool.getConstantReflection(), mirrored ? condition().mirror() : condition());
+            } else if (nonConstant instanceof NormalizeCompareNode) {
+                return optimizeNormalizeCmp(constant, (NormalizeCompareNode) nonConstant, mirrored);
             }
-        } else if (y() instanceof ConvertNode && x().isConstant()) {
-            ConvertNode convertY = (ConvertNode) y();
-            ConstantNode newX = canonicalConvertConstant(tool, convertY, x().asConstant());
-            if (newX != null) {
-                setX(newX);
-                setY(convertY.getInput());
+        } else if (nonConstant instanceof ConvertNode) {
+            ConvertNode convert = (ConvertNode) nonConstant;
+            ConstantNode newConstant = canonicalConvertConstant(tool, convert, constant);
+            if (newConstant != null) {
+                if (mirrored) {
+                    return graph().unique(duplicateModified(newConstant, convert.getInput()));
+                } else {
+                    return graph().unique(duplicateModified(convert.getInput(), newConstant));
+                }
             }
         }
         return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatEqualsNode.java	Wed May 28 20:36:10 2014 -0700
@@ -68,4 +68,9 @@
         }
         return super.evaluate(constantReflection, forX, forY);
     }
+
+    @Override
+    protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) {
+        return new FloatEqualsNode(newX, newY);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/FloatLessThanNode.java	Wed May 28 20:36:10 2014 -0700
@@ -67,4 +67,9 @@
         }
         return super.evaluate(constantReflection, forX, forY);
     }
+
+    @Override
+    protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) {
+        return new FloatLessThanNode(newX, newY, unorderedIsTrue);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerBelowThanNode.java	Wed May 28 20:36:10 2014 -0700
@@ -86,4 +86,9 @@
         }
         return this;
     }
+
+    @Override
+    protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) {
+        return new IntegerBelowThanNode(newX, newY);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerEqualsNode.java	Wed May 28 20:36:10 2014 -0700
@@ -23,7 +23,7 @@
 package com.oracle.graal.nodes.calc;
 
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.meta.ProfilingInfo.*;
+import com.oracle.graal.api.meta.ProfilingInfo.TriState;
 import com.oracle.graal.compiler.common.calc.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.*;
@@ -72,6 +72,11 @@
     }
 
     @Override
+    protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) {
+        return new IntegerEqualsNode(newX, newY);
+    }
+
+    @Override
     public TriState evaluate(ConstantReflectionProvider constantReflection, ValueNode forX, ValueNode forY) {
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
             return TriState.TRUE;
@@ -82,62 +87,51 @@
     }
 
     @Override
-    public Node canonical(CanonicalizerTool tool) {
-        Node result = super.canonical(tool);
-        if (result != this) {
-            return result;
-        }
-
-        result = canonicalizeSymmetric(x(), y());
-        if (result != this) {
-            return result;
-        }
-
-        return canonicalizeSymmetric(y(), x());
-    }
-
-    private ValueNode canonicalizeSymmetric(ValueNode x, ValueNode y) {
-        if (y.isConstant() && y.asConstant().asLong() == 0) {
-            if (x instanceof AndNode) {
-                return graph().unique(new IntegerTestNode(((AndNode) x).x(), ((AndNode) x).y()));
-            } else if (x instanceof LeftShiftNode) {
-                LeftShiftNode shift = (LeftShiftNode) x;
-                if (shift.y().isConstant()) {
-                    int mask = shift.getShiftAmountMask();
-                    int amount = shift.y().asConstant().asInt() & mask;
-                    if (shift.x().getKind() == Kind.Int) {
-                        return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 >>> amount, graph())));
-                    } else {
-                        assert shift.x().getKind() == Kind.Long;
-                        return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L >>> amount, graph())));
+    protected Node canonicalizeSymmetricConstant(CanonicalizerTool tool, Constant constant, ValueNode nonConstant, boolean mirrored) {
+        if (constant.asLong() == 0) {
+            if (nonConstant instanceof AndNode) {
+                AndNode andNode = (AndNode) nonConstant;
+                return graph().unique(new IntegerTestNode(andNode.x(), andNode.y()));
+            } else if (nonConstant instanceof ShiftNode) {
+                if (nonConstant instanceof LeftShiftNode) {
+                    LeftShiftNode shift = (LeftShiftNode) nonConstant;
+                    if (shift.y().isConstant()) {
+                        int mask = shift.getShiftAmountMask();
+                        int amount = shift.y().asConstant().asInt() & mask;
+                        if (shift.x().getKind() == Kind.Int) {
+                            return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 >>> amount, graph())));
+                        } else {
+                            assert shift.x().getKind() == Kind.Long;
+                            return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L >>> amount, graph())));
+                        }
                     }
-                }
-            } else if (x instanceof RightShiftNode) {
-                RightShiftNode shift = (RightShiftNode) x;
-                if (shift.y().isConstant() && ((IntegerStamp) shift.x().stamp()).isPositive()) {
-                    int mask = shift.getShiftAmountMask();
-                    int amount = shift.y().asConstant().asInt() & mask;
-                    if (shift.x().getKind() == Kind.Int) {
-                        return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 << amount, graph())));
-                    } else {
-                        assert shift.x().getKind() == Kind.Long;
-                        return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L << amount, graph())));
+                } else if (nonConstant instanceof RightShiftNode) {
+                    RightShiftNode shift = (RightShiftNode) nonConstant;
+                    if (shift.y().isConstant() && ((IntegerStamp) shift.x().stamp()).isPositive()) {
+                        int mask = shift.getShiftAmountMask();
+                        int amount = shift.y().asConstant().asInt() & mask;
+                        if (shift.x().getKind() == Kind.Int) {
+                            return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 << amount, graph())));
+                        } else {
+                            assert shift.x().getKind() == Kind.Long;
+                            return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L << amount, graph())));
+                        }
                     }
-                }
-            } else if (x instanceof UnsignedRightShiftNode) {
-                UnsignedRightShiftNode shift = (UnsignedRightShiftNode) x;
-                if (shift.y().isConstant()) {
-                    int mask = shift.getShiftAmountMask();
-                    int amount = shift.y().asConstant().asInt() & mask;
-                    if (shift.x().getKind() == Kind.Int) {
-                        return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 << amount, graph())));
-                    } else {
-                        assert shift.x().getKind() == Kind.Long;
-                        return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L << amount, graph())));
+                } else if (nonConstant instanceof UnsignedRightShiftNode) {
+                    UnsignedRightShiftNode shift = (UnsignedRightShiftNode) nonConstant;
+                    if (shift.y().isConstant()) {
+                        int mask = shift.getShiftAmountMask();
+                        int amount = shift.y().asConstant().asInt() & mask;
+                        if (shift.x().getKind() == Kind.Int) {
+                            return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forInt(-1 << amount, graph())));
+                        } else {
+                            assert shift.x().getKind() == Kind.Long;
+                            return graph().unique(new IntegerTestNode(shift.x(), ConstantNode.forLong(-1L << amount, graph())));
+                        }
                     }
                 }
             }
         }
-        return this;
+        return super.canonicalizeSymmetricConstant(tool, constant, nonConstant, mirrored);
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/IntegerLessThanNode.java	Wed May 28 20:36:10 2014 -0700
@@ -101,4 +101,9 @@
         }
         return this;
     }
+
+    @Override
+    protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) {
+        return new IntegerLessThanNode(newX, newY);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/calc/ObjectEqualsNode.java	Wed May 28 20:36:10 2014 -0700
@@ -119,7 +119,7 @@
                 /*
                  * One of the two objects has identity, the other doesn't. In code, this looks like
                  * "Integer.valueOf(a) == new Integer(b)", which is always false.
-                 * 
+                 *
                  * In other words: an object created via valueOf can never be equal to one created
                  * by new in the same compilation unit.
                  */
@@ -138,4 +138,9 @@
             }
         }
     }
+
+    @Override
+    protected CompareNode duplicateModified(ValueNode newX, ValueNode newY) {
+        return new ObjectEqualsNode(newX, newY);
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/Block.java	Wed May 28 20:36:10 2014 -0700
@@ -186,6 +186,7 @@
     }
 
     public void setProbability(double probability) {
+        assert probability >= 0 && Double.isFinite(probability);
         this.probability = probability;
     }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/cfg/ControlFlowGraph.java	Wed May 28 20:36:10 2014 -0700
@@ -221,6 +221,9 @@
                     }
                 }
             }
+            if (probability > 1. / Double.MIN_NORMAL) {
+                probability = 1. / Double.MIN_NORMAL;
+            }
             block.setPredecessors(predecessors);
             block.setProbability(probability);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AbstractWriteNode.java	Wed May 28 20:36:10 2014 -0700
@@ -63,12 +63,12 @@
         return initialization;
     }
 
-    public AbstractWriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible) {
-        this(object, value, location, barrierType, compressible, false);
+    public AbstractWriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType) {
+        this(object, value, location, barrierType, false);
     }
 
-    public AbstractWriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) {
-        super(object, location, StampFactory.forVoid(), barrierType, compressible);
+    public AbstractWriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean initialization) {
+        super(object, location, StampFactory.forVoid(), barrierType);
         this.value = value;
         this.initialization = initialization;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FixedAccessNode.java	Wed May 28 20:36:10 2014 -0700
@@ -37,7 +37,6 @@
     @Input(InputType.Association) private ValueNode location;
     private boolean nullCheck;
     private BarrierType barrierType;
-    private boolean compressible;
 
     public ValueNode object() {
         return object;
@@ -65,20 +64,19 @@
     }
 
     public FixedAccessNode(ValueNode object, ValueNode location, Stamp stamp) {
-        this(object, location, stamp, null, BarrierType.NONE, false);
+        this(object, location, stamp, null, BarrierType.NONE);
     }
 
-    public FixedAccessNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType, boolean compressible) {
-        this(object, location, stamp, null, barrierType, compressible);
+    public FixedAccessNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType) {
+        this(object, location, stamp, null, barrierType);
     }
 
-    public FixedAccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean compressible) {
+    public FixedAccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType) {
         super(stamp);
         this.object = object;
         this.location = location;
         this.guard = guard;
         this.barrierType = barrierType;
-        this.compressible = compressible;
     }
 
     @Override
@@ -101,9 +99,4 @@
     public BarrierType getBarrierType() {
         return barrierType;
     }
-
-    @Override
-    public boolean isCompressible() {
-        return compressible;
-    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatableAccessNode.java	Wed May 28 20:36:10 2014 -0700
@@ -35,12 +35,12 @@
         super(object, location, stamp);
     }
 
-    public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean compressible) {
-        super(object, location, stamp, guard, barrierType, compressible);
+    public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType) {
+        super(object, location, stamp, guard, barrierType);
     }
 
-    public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType, boolean compressible) {
-        super(object, location, stamp, barrierType, compressible);
+    public FloatableAccessNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType) {
+        super(object, location, stamp, barrierType);
     }
 
     public abstract FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingAccessNode.java	Wed May 28 20:36:10 2014 -0700
@@ -32,7 +32,6 @@
     @Input private ValueNode object;
     @Input(InputType.Association) private LocationNode location;
     private BarrierType barrierType;
-    private boolean compressible;
 
     public ValueNode object() {
         return object;
@@ -56,12 +55,11 @@
         this.location = location;
     }
 
-    public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean compressible) {
+    public FloatingAccessNode(ValueNode object, LocationNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType) {
         super(stamp, guard);
         this.object = object;
         this.location = location;
         this.barrierType = barrierType;
-        this.compressible = compressible;
     }
 
     @Override
@@ -69,11 +67,6 @@
         return barrierType;
     }
 
-    @Override
-    public boolean isCompressible() {
-        return compressible;
-    }
-
     public boolean canNullCheck() {
         return true;
     }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/FloatingReadNode.java	Wed May 28 20:36:10 2014 -0700
@@ -38,15 +38,15 @@
     @Input(InputType.Memory) private MemoryNode lastLocationAccess;
 
     public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp) {
-        this(object, location, lastLocationAccess, stamp, null, BarrierType.NONE, false);
+        this(object, location, lastLocationAccess, stamp, null, BarrierType.NONE);
     }
 
     public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard) {
-        this(object, location, lastLocationAccess, stamp, guard, BarrierType.NONE, false);
+        this(object, location, lastLocationAccess, stamp, guard, BarrierType.NONE);
     }
 
-    public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean compressible) {
-        super(object, location, stamp, guard, barrierType, compressible);
+    public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard, BarrierType barrierType) {
+        super(object, location, stamp, guard, barrierType);
         this.lastLocationAccess = lastLocationAccess;
     }
 
@@ -69,14 +69,14 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) {
-            return graph().unique(new FloatingReadNode(((PiNode) object()).getOriginalNode(), location(), getLastLocationAccess(), stamp(), getGuard(), getBarrierType(), isCompressible()));
+            return graph().unique(new FloatingReadNode(((PiNode) object()).getOriginalNode(), location(), getLastLocationAccess(), stamp(), getGuard(), getBarrierType()));
         }
-        return ReadNode.canonicalizeRead(this, location(), object(), tool, isCompressible());
+        return ReadNode.canonicalizeRead(this, location(), object(), tool);
     }
 
     @Override
     public FixedAccessNode asFixedNode() {
-        return graph().add(new ReadNode(object(), accessLocation(), stamp(), getGuard(), getBarrierType(), isCompressible()));
+        return graph().add(new ReadNode(object(), accessLocation(), stamp(), getGuard(), getBarrierType()));
     }
 
     @Override
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java	Wed May 28 20:36:10 2014 -0700
@@ -32,8 +32,11 @@
  */
 public final class JavaReadNode extends FixedAccessNode implements Lowerable, GuardingNode {
 
+    private final boolean compressible;
+
     public JavaReadNode(ValueNode object, LocationNode location, BarrierType barrierType, boolean compressible) {
-        super(object, location, StampFactory.forKind(location.getValueKind()), barrierType, compressible);
+        super(object, location, StampFactory.forKind(location.getValueKind()), barrierType);
+        this.compressible = compressible;
     }
 
     public void lower(LoweringTool tool) {
@@ -43,4 +46,8 @@
     public boolean canNullCheck() {
         return true;
     }
+
+    public boolean isCompressible() {
+        return compressible;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java	Wed May 28 20:36:10 2014 -0700
@@ -31,8 +31,11 @@
  */
 public final class JavaWriteNode extends AbstractWriteNode implements Lowerable, StateSplit, MemoryAccess, MemoryCheckpoint.Single {
 
+    private final boolean compressible;
+
     public JavaWriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) {
-        super(object, value, location, barrierType, compressible, initialization);
+        super(object, value, location, barrierType, initialization);
+        this.compressible = compressible;
     }
 
     public void lower(LoweringTool tool) {
@@ -42,4 +45,8 @@
     public boolean canNullCheck() {
         return true;
     }
+
+    public boolean isCompressible() {
+        return compressible;
+    }
 }
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ReadNode.java	Wed May 28 20:36:10 2014 -0700
@@ -36,21 +36,21 @@
  */
 public final class ReadNode extends FloatableAccessNode implements LIRLowerable, Canonicalizable, PiPushable, Virtualizable, GuardingNode {
 
-    public ReadNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType, boolean compressible) {
-        super(object, location, stamp, barrierType, compressible);
+    public ReadNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType) {
+        super(object, location, stamp, barrierType);
     }
 
-    public ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean compressible) {
-        super(object, location, stamp, guard, barrierType, compressible);
+    public ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType) {
+        super(object, location, stamp, guard, barrierType);
     }
 
-    private ReadNode(ValueNode object, ValueNode location, ValueNode guard, BarrierType barrierType, boolean compressible) {
+    private ReadNode(ValueNode object, ValueNode location, ValueNode guard, BarrierType barrierType) {
         /*
          * Used by node intrinsics. Really, you can trust me on that! Since the initial value for
          * location is a parameter, i.e., a ParameterNode, the constructor cannot use the declared
          * type LocationNode.
          */
-        super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, barrierType, compressible);
+        super(object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, barrierType);
     }
 
     @Override
@@ -63,17 +63,17 @@
     @Override
     public Node canonical(CanonicalizerTool tool) {
         if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) {
-            ReadNode readNode = graph().add(new ReadNode(((PiNode) object()).getOriginalNode(), location(), stamp(), getGuard(), getBarrierType(), isCompressible()));
+            ReadNode readNode = graph().add(new ReadNode(((PiNode) object()).getOriginalNode(), location(), stamp(), getGuard(), getBarrierType()));
             readNode.setNullCheck(getNullCheck());
             readNode.setStateBefore(stateBefore());
             return readNode;
         }
-        return canonicalizeRead(this, location(), object(), tool, isCompressible());
+        return canonicalizeRead(this, location(), object(), tool);
     }
 
     @Override
     public FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess) {
-        return graph().unique(new FloatingReadNode(object(), location(), lastLocationAccess, stamp(), getGuard(), getBarrierType(), isCompressible()));
+        return graph().unique(new FloatingReadNode(object(), location(), lastLocationAccess, stamp(), getGuard(), getBarrierType()));
     }
 
     @Override
@@ -81,7 +81,7 @@
         return (getNullCheck() && type == InputType.Guard) ? true : super.isAllowedUsageType(type);
     }
 
-    public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool, boolean compressible) {
+    public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool) {
         MetaAccessProvider metaAccess = tool.getMetaAccess();
         if (read.usages().isEmpty()) {
             GuardingNode guard = ((Access) read).getGuard();
@@ -94,7 +94,7 @@
             }
         }
         if (tool.canonicalizeReads()) {
-            if (metaAccess != null && object != null && object.isConstant() && !compressible) {
+            if (metaAccess != null && object != null && object.isConstant()) {
                 if ((location.getLocationIdentity() == LocationIdentity.FINAL_LOCATION || location.getLocationIdentity() == LocationIdentity.ARRAY_LENGTH_LOCATION) &&
                                 location instanceof ConstantLocationNode) {
                     long displacement = ((ConstantLocationNode) location).getDisplacement();
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java	Wed May 28 20:36:10 2014 -0700
@@ -34,12 +34,12 @@
  */
 public final class WriteNode extends AbstractWriteNode implements LIRLowerable, Simplifiable, Virtualizable {
 
-    public WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible) {
-        super(object, value, location, barrierType, compressible);
+    public WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType) {
+        super(object, value, location, barrierType);
     }
 
-    public WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) {
-        super(object, value, location, barrierType, compressible, initialization);
+    public WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean initialization) {
+        super(object, value, location, barrierType, initialization);
     }
 
     @Override
@@ -48,7 +48,7 @@
         // It's possible a constant was forced for other usages so inspect the value directly and
         // use a constant if it can be directly stored.
         Value v;
-        if (value().isConstant() && gen.getLIRGeneratorTool().canStoreConstant(value().asConstant(), isCompressible())) {
+        if (value().isConstant() && gen.getLIRGeneratorTool().canStoreConstant(value().asConstant())) {
             v = value().asConstant();
         } else {
             v = gen.operand(value());
@@ -65,7 +65,7 @@
     }
 
     @NodeIntrinsic
-    public static native void writeMemory(Object object, Object value, Location location, @ConstantNodeParameter BarrierType barrierType, @ConstantNodeParameter boolean compressible);
+    public static native void writeMemory(Object object, Object value, Location location, @ConstantNodeParameter BarrierType barrierType);
 
     @Override
     public void virtualize(VirtualizerTool tool) {
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java	Wed May 28 20:36:10 2014 -0700
@@ -40,8 +40,8 @@
     @Input private ValueNode newValue;
     @Input(InputType.State) private FrameState stateAfter;
 
-    public LoweredAtomicReadAndWriteNode(ValueNode object, LocationNode location, ValueNode newValue, BarrierType barrierType, boolean compressible) {
-        super(object, location, newValue.stamp().unrestricted(), barrierType, compressible);
+    public LoweredAtomicReadAndWriteNode(ValueNode object, LocationNode location, ValueNode newValue, BarrierType barrierType) {
+        super(object, location, newValue.stamp().unrestricted(), barrierType);
         this.newValue = newValue;
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java	Wed May 28 20:36:10 2014 -0700
@@ -61,8 +61,8 @@
         return newValue;
     }
 
-    public LoweredCompareAndSwapNode(ValueNode object, LocationNode location, ValueNode expectedValue, ValueNode newValue, BarrierType barrierType, boolean compressible) {
-        super(object, location, StampFactory.forKind(Kind.Boolean.getStackKind()), barrierType, compressible);
+    public LoweredCompareAndSwapNode(ValueNode object, LocationNode location, ValueNode expectedValue, ValueNode newValue, BarrierType barrierType) {
+        super(object, location, StampFactory.forKind(Kind.Boolean.getStackKind()), barrierType);
         assert expectedValue.getKind() == newValue.getKind();
         this.expectedValue = expectedValue;
         this.newValue = newValue;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java	Wed May 28 20:36:10 2014 -0700
@@ -42,6 +42,8 @@
     private ResolvedJavaMethod targetMethod;
     private InvokeKind invokeKind;
 
+    private transient Stamp lastCanonicalizedReceiverStamp;
+
     /**
      * @param arguments
      */
@@ -138,12 +140,17 @@
             }
 
             // check if the type of the receiver can narrow the result
-            ValueNode receiver = receiver();
-            ResolvedJavaType type = StampTool.typeOrNull(receiver);
+            Stamp receiverStamp = receiver().stamp();
+            if (receiverStamp.equals(lastCanonicalizedReceiverStamp)) {
+                return this;
+            }
+            lastCanonicalizedReceiverStamp = receiverStamp;
+
+            ResolvedJavaType type = StampTool.typeOrNull(receiverStamp);
             if (type != null && (invoke().stateAfter() != null || invoke().stateDuring() != null)) {
                 // either the holder class is exact, or the receiver object has an exact type
                 ResolvedJavaMethod resolvedMethod = type.resolveMethod(targetMethod, invoke().getContextType());
-                if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver))) {
+                if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiverStamp))) {
                     invokeKind = InvokeKind.Special;
                     targetMethod = resolvedMethod;
                     return this;
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java	Wed May 28 20:36:10 2014 -0700
@@ -25,11 +25,12 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.api.runtime.*;
 
 /**
  * Interface for service providers that register replacements with the compiler.
  */
-public interface ReplacementsProvider {
+public interface ReplacementsProvider extends Service {
 
     void registerReplacements(MetaAccessProvider metaAccess, LoweringProvider lowerer, SnippetReflectionProvider snippetReflection, Replacements replacements, TargetDescription target);
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/CanonicalizerPhase.java	Wed May 28 20:36:10 2014 -0700
@@ -137,9 +137,9 @@
         protected void run(StructuredGraph graph) {
             boolean wholeGraph = newNodesMark == null || newNodesMark.isStart();
             if (initWorkingSet == null) {
-                workList = graph.createNodeWorkList(wholeGraph, MAX_ITERATION_PER_NODE);
+                workList = graph.createIterativeNodeWorkList(wholeGraph, MAX_ITERATION_PER_NODE);
             } else {
-                workList = graph.createNodeWorkList(false, MAX_ITERATION_PER_NODE);
+                workList = graph.createIterativeNodeWorkList(false, MAX_ITERATION_PER_NODE);
                 workList.addAll(initWorkingSet);
             }
             if (!wholeGraph) {
@@ -154,7 +154,7 @@
 
                 @Override
                 public void nodeChanged(Node node) {
-                    workList.addAgain(node);
+                    workList.add(node);
                 }
             };
             graph.trackInputChange(nodeChangedListener);
@@ -336,7 +336,7 @@
                 if (node.inferStamp()) {
                     METRIC_STAMP_CHANGED.increment();
                     for (Node usage : node.usages()) {
-                        workList.addAgain(usage);
+                        workList.add(usage);
                     }
                     return true;
                 }
@@ -373,7 +373,7 @@
 
             @Override
             public void addToWorkList(Node node) {
-                workList.addAgain(node);
+                workList.add(node);
             }
 
             @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Wed May 28 20:36:10 2014 -0700
@@ -145,8 +145,7 @@
             } else {
                 GuardNode newGuard = graph.unique(new GuardNode(condition, guardAnchor, deoptReason, action, negated, Constant.NULL_OBJECT));
                 if (OptEliminateGuards.getValue()) {
-                    activeGuards.grow();
-                    activeGuards.mark(newGuard);
+                    activeGuards.markAndGrow(newGuard);
                 }
                 return newGuard;
             }
@@ -283,7 +282,7 @@
 
             if (parentAnchor == null && OptEliminateGuards.getValue()) {
                 for (GuardNode guard : anchor.asNode().usages().filter(GuardNode.class)) {
-                    if (activeGuards.contains(guard)) {
+                    if (activeGuards.isMarkedAndGrow(guard)) {
                         activeGuards.clear(guard);
                     }
                 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AbstractInlineInfo.java	Wed May 28 20:36:10 2014 -0700
@@ -22,13 +22,13 @@
  */
 package com.oracle.graal.phases.common.inlining.info;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.Assumptions;
 import com.oracle.graal.api.meta.ResolvedJavaMethod;
-import com.oracle.graal.nodes.FixedWithNextNode;
-import com.oracle.graal.nodes.Invoke;
-import com.oracle.graal.nodes.StructuredGraph;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.common.inlining.InliningUtil;
-
 import com.oracle.graal.phases.common.inlining.info.elem.Inlineable;
 import com.oracle.graal.phases.common.inlining.info.elem.InlineableMacroNode;
 import com.oracle.graal.phases.common.inlining.info.elem.InlineableGraph;
@@ -51,18 +51,33 @@
         return invoke;
     }
 
-    protected static void inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, Assumptions assumptions, boolean receiverNullCheck) {
+    protected static Collection<Node> inline(Invoke invoke, ResolvedJavaMethod concrete, Inlineable inlineable, Assumptions assumptions, boolean receiverNullCheck) {
+        Collection<Node> parameterUsages = new ArrayList<>();
         if (inlineable instanceof InlineableGraph) {
             StructuredGraph calleeGraph = ((InlineableGraph) inlineable).getGraph();
-            InliningUtil.inline(invoke, calleeGraph, receiverNullCheck);
+            Map<Node, Node> duplicateMap = InliningUtil.inline(invoke, calleeGraph, receiverNullCheck);
+            getInlinedParameterUsages(parameterUsages, calleeGraph, duplicateMap);
         } else {
             assert inlineable instanceof InlineableMacroNode;
 
             Class<? extends FixedWithNextNode> macroNodeClass = ((InlineableMacroNode) inlineable).getMacroNodeClass();
-            InliningUtil.inlineMacroNode(invoke, concrete, macroNodeClass);
+            FixedWithNextNode macroNode = InliningUtil.inlineMacroNode(invoke, concrete, macroNodeClass);
+            parameterUsages.add(macroNode);
         }
 
         InliningUtil.InlinedBytecodes.add(concrete.getCodeSize());
         assumptions.recordMethodContents(concrete);
+        return parameterUsages;
+    }
+
+    public static void getInlinedParameterUsages(Collection<Node> parameterUsages, StructuredGraph calleeGraph, Map<Node, Node> duplicateMap) {
+        for (ParameterNode parameter : calleeGraph.getNodes(ParameterNode.class)) {
+            for (Node usage : parameter.usages()) {
+                Node node = duplicateMap.get(usage);
+                if (node != null && node.isAlive()) {
+                    parameterUsages.add(node);
+                }
+            }
+        }
     }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/AssumptionInlineInfo.java	Wed May 28 20:36:10 2014 -0700
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.phases.common.inlining.info;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.Assumptions;
 import com.oracle.graal.api.meta.MetaAccessProvider;
 import com.oracle.graal.api.meta.MetaUtil;
@@ -30,6 +32,7 @@
 import com.oracle.graal.phases.common.inlining.InliningUtil;
 import com.oracle.graal.phases.util.Providers;
 import com.oracle.graal.api.code.Assumptions.Assumption;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 
 /**
@@ -46,9 +49,9 @@
     }
 
     @Override
-    public void inline(Providers providers, Assumptions assumptions) {
+    public Collection<Node> inline(Providers providers, Assumptions assumptions) {
         assumptions.record(takenAssumption);
-        super.inline(providers, assumptions);
+        return super.inline(providers, assumptions);
     }
 
     @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/ExactInlineInfo.java	Wed May 28 20:36:10 2014 -0700
@@ -22,10 +22,13 @@
  */
 package com.oracle.graal.phases.common.inlining.info;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.Assumptions;
 import com.oracle.graal.api.meta.MetaAccessProvider;
 import com.oracle.graal.api.meta.MetaUtil;
 import com.oracle.graal.api.meta.ResolvedJavaMethod;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.Invoke;
 import com.oracle.graal.phases.common.inlining.info.elem.Inlineable;
 import com.oracle.graal.phases.util.Providers;
@@ -51,8 +54,8 @@
     }
 
     @Override
-    public void inline(Providers providers, Assumptions assumptions) {
-        inline(invoke, concrete, inlineableElement, assumptions, !suppressNullCheck);
+    public Collection<Node> inline(Providers providers, Assumptions assumptions) {
+        return inline(invoke, concrete, inlineableElement, assumptions, !suppressNullCheck);
     }
 
     @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/InlineInfo.java	Wed May 28 20:36:10 2014 -0700
@@ -22,9 +22,12 @@
  */
 package com.oracle.graal.phases.common.inlining.info;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.Assumptions;
 import com.oracle.graal.api.meta.MetaAccessProvider;
 import com.oracle.graal.api.meta.ResolvedJavaMethod;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.Invoke;
 import com.oracle.graal.nodes.StructuredGraph;
 import com.oracle.graal.phases.common.inlining.info.elem.Inlineable;
@@ -68,8 +71,10 @@
      * Performs the inlining described by this object and returns the node that represents the
      * return value of the inlined method (or null for void methods and methods that have no
      * non-exceptional exit).
+     * 
+     * @return a collection of nodes that need to be canonicalized after the inlining
      */
-    void inline(Providers providers, Assumptions assumptions);
+    Collection<Node> inline(Providers providers, Assumptions assumptions);
 
     /**
      * Try to make the call static bindable to avoid interface and virtual method calls.
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/MultiTypeGuardInlineInfo.java	Wed May 28 20:36:10 2014 -0700
@@ -132,11 +132,11 @@
     }
 
     @Override
-    public void inline(Providers providers, Assumptions assumptions) {
+    public Collection<Node> inline(Providers providers, Assumptions assumptions) {
         if (hasSingleMethod()) {
-            inlineSingleMethod(graph(), providers.getMetaAccess(), assumptions);
+            return inlineSingleMethod(graph(), providers.getMetaAccess(), assumptions);
         } else {
-            inlineMultipleMethods(graph(), providers, assumptions);
+            return inlineMultipleMethods(graph(), providers, assumptions);
         }
     }
 
@@ -157,7 +157,7 @@
         return notRecordedTypeProbability > 0;
     }
 
-    private void inlineMultipleMethods(StructuredGraph graph, Providers providers, Assumptions assumptions) {
+    private Collection<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers, Assumptions assumptions) {
         int numberOfMethods = concretes.size();
         FixedNode continuation = invoke.next();
 
@@ -222,6 +222,8 @@
 
         ArrayList<GuardedValueNode> replacementNodes = new ArrayList<>();
 
+        Collection<Node> parameterUsages = new ArrayList<>();
+
         // do the actual inlining for every invoke
         for (int i = 0; i < numberOfMethods; i++) {
             BeginNode node = successors[i];
@@ -239,7 +241,7 @@
             GuardedValueNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, node, commonType, receiver, exact);
             invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver);
 
-            inline(invokeForInlining, methodAt(i), inlineableElementAt(i), assumptions, false);
+            parameterUsages.addAll(inline(invokeForInlining, methodAt(i), inlineableElementAt(i), assumptions, false));
 
             replacementNodes.add(anchoredReceiver);
         }
@@ -272,6 +274,7 @@
                 TailDuplicationPhase.tailDuplicate(returnMerge, TailDuplicationPhase.TRUE_DECISION, replacementNodes, phaseContext, canonicalizer);
             }
         }
+        return parameterUsages;
     }
 
     private int getTypeCount(int concreteMethodIndex) {
@@ -307,7 +310,7 @@
         return result;
     }
 
-    private void inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions) {
+    private Collection<Node> inlineSingleMethod(StructuredGraph graph, MetaAccessProvider metaAccess, Assumptions assumptions) {
         assert concretes.size() == 1 && inlineableElements.length == 1 && ptypes.size() > 1 && !shouldFallbackToInvoke() && notRecordedTypeProbability == 0;
 
         BeginNode calleeEntryNode = graph.add(new BeginNode());
@@ -318,7 +321,7 @@
 
         calleeEntryNode.setNext(invoke.asNode());
 
-        inline(invoke, methodAt(0), inlineableElementAt(0), assumptions, false);
+        return inline(invoke, methodAt(0), inlineableElementAt(0), assumptions, false);
     }
 
     private boolean createDispatchOnTypeBeforeInvoke(StructuredGraph graph, BeginNode[] successors, boolean invokeIsOnlySuccessor, MetaAccessProvider metaAccess) {
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/TypeGuardInlineInfo.java	Wed May 28 20:36:10 2014 -0700
@@ -22,9 +22,12 @@
  */
 package com.oracle.graal.phases.common.inlining.info;
 
+import java.util.*;
+
 import com.oracle.graal.api.code.Assumptions;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.calc.Condition;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.CompareNode;
 import com.oracle.graal.nodes.extended.LoadHubNode;
@@ -87,9 +90,9 @@
     }
 
     @Override
-    public void inline(Providers providers, Assumptions assumptions) {
+    public Collection<Node> inline(Providers providers, Assumptions assumptions) {
         createGuard(graph(), providers.getMetaAccess());
-        inline(invoke, concrete, inlineableElement, assumptions, false);
+        return inline(invoke, concrete, inlineableElement, assumptions, false);
     }
 
     @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Wed May 28 20:36:10 2014 -0700
@@ -22,11 +22,13 @@
  */
 package com.oracle.graal.phases.common.inlining.info.elem;
 
+import java.util.*;
+
 import com.oracle.graal.api.meta.Constant;
 import com.oracle.graal.api.meta.ResolvedJavaMethod;
 import com.oracle.graal.compiler.common.type.Stamp;
 import com.oracle.graal.debug.Debug;
-import com.oracle.graal.graph.NodeInputList;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.phases.common.CanonicalizerPhase;
 import com.oracle.graal.phases.common.DeadCodeEliminationPhase;
@@ -71,31 +73,34 @@
 
             boolean callerHasMoreInformationAboutArguments = false;
             NodeInputList<ValueNode> args = invoke.callTarget().arguments();
+            ArrayList<Node> parameterUsages = new ArrayList<>();
             for (ParameterNode param : newGraph.getNodes(ParameterNode.class).snapshot()) {
                 ValueNode arg = args.get(param.index());
                 if (arg.isConstant()) {
                     Constant constant = arg.asConstant();
                     newGraph.replaceFloating(param, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph));
                     callerHasMoreInformationAboutArguments = true;
+                    param.usages().snapshotTo(parameterUsages);
                 } else {
                     Stamp joinedStamp = param.stamp().join(arg.stamp());
                     if (joinedStamp != null && !joinedStamp.equals(param.stamp())) {
                         param.setStamp(joinedStamp);
                         callerHasMoreInformationAboutArguments = true;
+                        param.usages().snapshotTo(parameterUsages);
                     }
                 }
             }
 
-            if (!callerHasMoreInformationAboutArguments) {
+            if (callerHasMoreInformationAboutArguments) {
+                if (OptCanonicalizer.getValue()) {
+                    canonicalizer.applyIncremental(newGraph, context, parameterUsages);
+                }
+            } else {
                 // TODO (chaeubl): if args are not more concrete, inlining should be avoided
                 // in most cases or we could at least use the previous graph size + invoke
                 // probability to check the inlining
             }
 
-            if (OptCanonicalizer.getValue()) {
-                canonicalizer.apply(newGraph, context);
-            }
-
             return newGraph;
         } catch (Throwable e) {
             throw Debug.handle(e);
@@ -117,12 +122,10 @@
      * profiling info is mature, the resulting graph is cached.
      */
     private static StructuredGraph parseBytecodes(StructuredGraph newGraph, HighTierContext context, CanonicalizerPhase canonicalizer) {
-        final boolean hasMatureProfilingInfo = newGraph.method().getProfilingInfo().isMature();
-
         if (context.getGraphBuilderSuite() != null) {
             context.getGraphBuilderSuite().apply(newGraph, context);
         }
-        assert newGraph.start().next() != null : "graph needs to be populated during PhasePosition.AFTER_PARSING";
+        assert newGraph.start().next() != null : "graph needs to be populated the GraphBuilderSuite";
 
         new DeadCodeEliminationPhase().apply(newGraph);
 
@@ -130,7 +133,7 @@
             canonicalizer.apply(newGraph, context);
         }
 
-        if (hasMatureProfilingInfo && context.getGraphCache() != null) {
+        if (context.getGraphCache() != null) {
             context.getGraphCache().put(newGraph.method(), newGraph.copy());
         }
         return newGraph;
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java	Wed May 28 20:36:10 2014 -0700
@@ -47,9 +47,7 @@
 import com.oracle.graal.phases.tiers.HighTierContext;
 import com.oracle.graal.phases.util.Providers;
 
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 import java.util.function.ToDoubleFunction;
 
 import static com.oracle.graal.compiler.common.GraalOptions.*;
@@ -340,19 +338,21 @@
 
     private void doInline(CallsiteHolder callerCallsiteHolder, MethodInvocation calleeInvocation, Assumptions callerAssumptions) {
         StructuredGraph callerGraph = callerCallsiteHolder.graph();
-        Graph.Mark markBeforeInlining = callerGraph.getMark();
         InlineInfo calleeInfo = calleeInvocation.callee();
         try {
             try (Debug.Scope scope = Debug.scope("doInline", callerGraph)) {
-                List<Node> invokeUsages = calleeInfo.invoke().asNode().usages().snapshot();
-                calleeInfo.inline(new Providers(context), callerAssumptions);
+                Set<Node> canonicalizedNodes = new HashSet<>();
+                calleeInfo.invoke().asNode().usages().snapshotTo(canonicalizedNodes);
+                Collection<Node> parameterUsages = calleeInfo.inline(new Providers(context), callerAssumptions);
+                canonicalizedNodes.addAll(parameterUsages);
                 callerAssumptions.record(calleeInvocation.assumptions());
                 metricInliningRuns.increment();
                 Debug.dump(callerGraph, "after %s", calleeInfo);
 
                 if (OptCanonicalizer.getValue()) {
                     Graph.Mark markBeforeCanonicalization = callerGraph.getMark();
-                    canonicalizer.applyIncremental(callerGraph, context, invokeUsages, markBeforeInlining);
+
+                    canonicalizer.applyIncremental(callerGraph, context, canonicalizedNodes);
 
                     // process invokes that are possibly created during canonicalization
                     for (Node newNode : callerGraph.getNewNodes(markBeforeCanonicalization)) {
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Wed May 28 20:36:10 2014 -0700
@@ -113,7 +113,7 @@
         ConstantLocationNode location = createFieldLocation(graph, field, false);
         assert location != null : "Field that is loaded must not be eliminated";
 
-        ReadNode memoryRead = graph.add(new ReadNode(object, location, loadStamp, fieldLoadBarrierType(field), false));
+        ReadNode memoryRead = graph.add(new ReadNode(object, location, loadStamp, fieldLoadBarrierType(field)));
         ValueNode readValue = implicitLoadConvert(graph, field.getKind(), memoryRead);
         loadField.replaceAtUsages(readValue);
         graph.replaceFixed(loadField, memoryRead);
@@ -141,7 +141,7 @@
             graph.removeFixed(storeField);
             return;
         }
-        WriteNode memoryWrite = graph.add(new WriteNode(object, value, location, fieldStoreBarrierType(storeField.field()), false));
+        WriteNode memoryWrite = graph.add(new WriteNode(object, value, location, fieldStoreBarrierType(storeField.field())));
         memoryWrite.setStateAfter(storeField.stateAfter());
         graph.replaceFixedWithFixed(storeField, memoryWrite);
         memoryWrite.setGuard(createNullCheck(object, memoryWrite, tool));
@@ -160,7 +160,7 @@
         LocationNode location = createArrayLocation(graph, elementKind, loadIndexed.index(), false);
         Stamp loadStamp = loadStamp(loadIndexed.stamp(), elementKind, true);
 
-        ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), location, loadStamp, BarrierType.NONE, false));
+        ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), location, loadStamp, BarrierType.NONE));
         ValueNode readValue = implicitLoadConvert(graph, elementKind, memoryRead);
 
         memoryRead.setGuard(createBoundsCheck(loadIndexed, tool));
@@ -197,7 +197,7 @@
             }
         }
 
-        WriteNode memoryWrite = graph.add(new WriteNode(array, implicitStoreConvert(graph, elementKind, value), location, arrayStoreBarrierType(storeIndexed.elementKind()), false));
+        WriteNode memoryWrite = graph.add(new WriteNode(array, implicitStoreConvert(graph, elementKind, value), location, arrayStoreBarrierType(storeIndexed.elementKind())));
         memoryWrite.setGuard(boundsCheck);
         memoryWrite.setStateAfter(storeIndexed.stateAfter());
         graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
@@ -213,7 +213,7 @@
         ValueNode array = arrayLengthNode.array();
         ConstantLocationNode location = ConstantLocationNode.create(ARRAY_LENGTH_LOCATION, Kind.Int, arrayLengthOffset(), graph);
 
-        ReadNode arrayLengthRead = graph.add(new ReadNode(array, location, StampFactory.positiveInt(), BarrierType.NONE, false));
+        ReadNode arrayLengthRead = graph.add(new ReadNode(array, location, StampFactory.positiveInt(), BarrierType.NONE));
         arrayLengthRead.setGuard(createNullCheck(array, arrayLengthNode, tool));
         graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead);
     }
@@ -235,7 +235,7 @@
         ValueNode expectedValue = implicitStoreConvert(graph, valueKind, cas.expected());
         ValueNode newValue = implicitStoreConvert(graph, valueKind, cas.newValue());
 
-        LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, expectedValue, newValue, compareAndSwapBarrierType(cas), false));
+        LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, expectedValue, newValue, compareAndSwapBarrierType(cas)));
         atomicNode.setStateAfter(cas.stateAfter());
         graph.replaceFixedWithFixed(cas, atomicNode);
     }
@@ -247,7 +247,7 @@
 
         ValueNode newValue = implicitStoreConvert(graph, valueKind, n.newValue());
 
-        LoweredAtomicReadAndWriteNode memoryRead = graph.add(new LoweredAtomicReadAndWriteNode(n.object(), location, newValue, atomicReadAndWriteBarrierType(n), false));
+        LoweredAtomicReadAndWriteNode memoryRead = graph.add(new LoweredAtomicReadAndWriteNode(n.object(), location, newValue, atomicReadAndWriteBarrierType(n)));
         memoryRead.setStateAfter(n.stateAfter());
 
         ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead);
@@ -277,7 +277,7 @@
         Kind readKind = load.accessKind();
         LocationNode location = createLocation(load);
         Stamp loadStamp = loadStamp(load.stamp(), readKind, compressible);
-        ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, loadStamp, guard, BarrierType.NONE, false));
+        ReadNode memoryRead = graph.add(new ReadNode(load.object(), location, loadStamp, guard, BarrierType.NONE));
         ValueNode readValue = implicitLoadConvert(graph, readKind, memoryRead, compressible);
         load.replaceAtUsages(readValue);
         return memoryRead;
@@ -290,7 +290,7 @@
         boolean compressible = store.value().getKind() == Kind.Object;
         Kind valueKind = store.accessKind();
         ValueNode value = implicitStoreConvert(graph, valueKind, store.value(), compressible);
-        WriteNode write = graph.add(new WriteNode(object, value, location, unsafeStoreBarrierType(store), false));
+        WriteNode write = graph.add(new WriteNode(object, value, location, unsafeStoreBarrierType(store)));
         write.setStateAfter(store.stateAfter());
         graph.replaceFixedWithFixed(store, write);
     }
@@ -300,7 +300,7 @@
         Kind valueKind = read.location().getValueKind();
         Stamp loadStamp = loadStamp(read.stamp(), valueKind, read.isCompressible());
 
-        ReadNode memoryRead = graph.add(new ReadNode(read.object(), read.location(), loadStamp, read.getBarrierType(), false));
+        ReadNode memoryRead = graph.add(new ReadNode(read.object(), read.location(), loadStamp, read.getBarrierType()));
         ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead, read.isCompressible());
         memoryRead.setGuard(read.getGuard());
         read.replaceAtUsages(readValue);
@@ -312,7 +312,7 @@
         Kind valueKind = write.location().getValueKind();
         ValueNode value = implicitStoreConvert(graph, valueKind, write.value(), write.isCompressible());
 
-        WriteNode memoryWrite = graph.add(new WriteNode(write.object(), value, write.location(), write.getBarrierType(), false, write.isInitialization()));
+        WriteNode memoryWrite = graph.add(new WriteNode(write.object(), value, write.location(), write.getBarrierType(), write.isInitialization()));
         memoryWrite.setStateAfter(write.stateAfter());
         graph.replaceFixedWithFixed(write, memoryWrite);
         memoryWrite.setGuard(write.getGuard());
@@ -368,7 +368,7 @@
                             barrierType = arrayInitializationBarrier(entryKind);
                         }
                         if (location != null) {
-                            WriteNode write = new WriteNode(newObject, implicitStoreConvert(graph, entryKind, value), location, barrierType, false);
+                            WriteNode write = new WriteNode(newObject, implicitStoreConvert(graph, entryKind, value), location, barrierType);
                             graph.addAfterFixed(newObject, graph.add(write));
                         }
                     }
@@ -400,7 +400,7 @@
                                 barrierType = BarrierType.PRECISE;
                             }
                             if (location != null) {
-                                WriteNode write = new WriteNode(newObject, implicitStoreConvert(graph, Kind.Object, allocValue), location, barrierType, false);
+                                WriteNode write = new WriteNode(newObject, implicitStoreConvert(graph, Kind.Object, allocValue), location, barrierType);
                                 graph.addBeforeFixed(commit, graph.add(write));
                             }
                         }
@@ -625,7 +625,7 @@
         ValueNode arrayLength = readArrayLength(n.graph(), array, tool.getConstantReflection());
         if (arrayLength == null) {
             Stamp stamp = StampFactory.positiveInt();
-            ReadNode readArrayLength = graph.add(new ReadNode(array, ConstantLocationNode.create(ARRAY_LENGTH_LOCATION, Kind.Int, arrayLengthOffset(), graph), stamp, BarrierType.NONE, false));
+            ReadNode readArrayLength = graph.add(new ReadNode(array, ConstantLocationNode.create(ARRAY_LENGTH_LOCATION, Kind.Int, arrayLengthOffset(), graph), stamp, BarrierType.NONE));
             graph.addBeforeFixed(n, readArrayLength);
             readArrayLength.setGuard(createNullCheck(array, readArrayLength, tool));
             arrayLength = readArrayLength;
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Wed May 28 20:36:10 2014 -0700
@@ -27,6 +27,7 @@
 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.replacements.SnippetTemplate.AbstractTemplates.*;
 import static java.util.FormattableFlags.*;
 
 import java.io.*;
@@ -418,13 +419,14 @@
     private static final DebugMetric SnippetTemplates = Debug.metric("SnippetTemplateCount");
 
     private static final String MAX_TEMPLATES_PER_SNIPPET_PROPERTY_NAME = "graal.maxTemplatesPerSnippet";
-    private static final boolean UseSnippetTemplateCache = Boolean.parseBoolean(System.getProperty("graal.useSnippetTemplateCache", "true"));
     private static final int MaxTemplatesPerSnippet = Integer.getInteger(MAX_TEMPLATES_PER_SNIPPET_PROPERTY_NAME, 50);
 
     /**
      * Base class for snippet classes. It provides a cache for {@link SnippetTemplate}s.
      */
-    public abstract static class AbstractTemplates implements SnippetTemplateCache {
+    public abstract static class AbstractTemplates implements com.oracle.graal.api.replacements.SnippetTemplateCache {
+
+        static final boolean UseSnippetTemplateCache = Boolean.parseBoolean(System.getProperty("graal.useSnippetTemplateCache", "true"));
 
         protected final Providers providers;
         protected final SnippetReflectionProvider snippetReflection;
@@ -891,7 +893,6 @@
      * lowered and the stamp of the snippet's return value.
      */
     public interface UsageReplacer {
-
         /**
          * Replaces all usages of {@code oldNode} with direct or indirect usages of {@code newNode}.
          */
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Wed May 28 20:36:10 2014 -0700
@@ -213,7 +213,7 @@
     }
 
     private static CompilationResultBuilderFactory getOptimizedCallTargetInstrumentationFactory(String arch, ResolvedJavaMethod method) {
-        for (OptimizedCallTargetInstrumentationFactory factory : ServiceLoader.loadInstalled(OptimizedCallTargetInstrumentationFactory.class)) {
+        for (OptimizedCallTargetInstrumentationFactory factory : Services.load(OptimizedCallTargetInstrumentationFactory.class)) {
             if (factory.getArchitecture().equals(arch)) {
                 factory.setInstrumentedMethod(method);
                 return factory;
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetInstrumentationFactory.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetInstrumentationFactory.java	Wed May 28 20:36:10 2014 -0700
@@ -23,13 +23,14 @@
 package com.oracle.graal.truffle;
 
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
 import com.oracle.graal.lir.asm.*;
 
 /**
  * A service for creating a specialized {@link CompilationResultBuilder} used to inject code into
  * {@link OptimizedCallTarget#call(Object[])}.
  */
-public interface OptimizedCallTargetInstrumentationFactory extends CompilationResultBuilderFactory {
+public interface OptimizedCallTargetInstrumentationFactory extends CompilationResultBuilderFactory, Service {
 
     /**
      * Gets the architecture supported by this factory.
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java	Wed May 28 20:36:10 2014 -0700
@@ -34,7 +34,6 @@
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
 import com.oracle.graal.debug.internal.*;
-import com.oracle.graal.graph.Graph.Mark;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.Node;
 import com.oracle.graal.graph.spi.*;
@@ -49,6 +48,7 @@
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.common.CanonicalizerPhase.CustomCanonicalizer;
 import com.oracle.graal.phases.common.inlining.*;
+import com.oracle.graal.phases.common.inlining.info.*;
 import com.oracle.graal.phases.tiers.*;
 import com.oracle.graal.phases.util.*;
 import com.oracle.graal.truffle.nodes.asserts.*;
@@ -210,11 +210,10 @@
                             try (Indent indent = Debug.logAndIndent("inline graph %s", methodCallTargetNode.targetMethod())) {
 
                                 int nodeCountBefore = graph.getNodeCount();
-                                Mark mark = graph.getMark();
                                 if (TraceTruffleExpansion.getValue()) {
                                     expansionLogger.preExpand(methodCallTargetNode, inlineGraph);
                                 }
-                                List<Node> invokeUsages = methodCallTargetNode.invoke().asNode().usages().snapshot();
+                                List<Node> canonicalizedNodes = methodCallTargetNode.invoke().asNode().usages().snapshot();
                                 Map<Node, Node> inlined = InliningUtil.inline(methodCallTargetNode.invoke(), inlineGraph, false);
                                 if (TraceTruffleExpansion.getValue()) {
                                     expansionLogger.postExpand(inlined);
@@ -223,7 +222,8 @@
                                     int nodeCountAfter = graph.getNodeCount();
                                     Debug.dump(graph, "After inlining %s %+d (%d)", methodCallTargetNode.targetMethod().toString(), nodeCountAfter - nodeCountBefore, nodeCountAfter);
                                 }
-                                canonicalizer.applyIncremental(graph, phaseContext, invokeUsages, mark);
+                                AbstractInlineInfo.getInlinedParameterUsages(canonicalizedNodes, inlineGraph, inlined);
+                                canonicalizer.applyIncremental(graph, phaseContext, canonicalizedNodes);
 
                                 changed = true;
                             }
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed May 28 20:33:49 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java	Wed May 28 20:36:10 2014 -0700
@@ -36,6 +36,7 @@
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.debug.DebugMemUseTracker.Closeable;
 import com.oracle.graal.debug.internal.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.lir.asm.*;
@@ -102,6 +103,10 @@
     public static final DebugTimer CompilationTime = Debug.timer("CompilationTime");
     public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation");
 
+    public static final DebugMemUseTracker PartialEvaluationMemUse = Debug.memUseTracker("TrufflePartialEvaluationMemUse");
+    public static final DebugMemUseTracker CompilationMemUse = Debug.memUseTracker("TruffleCompilationMemUse");
+    public static final DebugMemUseTracker CodeInstallationMemUse = Debug.memUseTracker("TruffleCodeInstallationMemUse");
+
     public void compileMethodImpl(final OptimizedCallTarget compilable) {
         final StructuredGraph graph;
 
@@ -111,7 +116,7 @@
 
         long timeCompilationStarted = System.nanoTime();
         Assumptions assumptions = new Assumptions(true);
-        try (TimerCloseable a = PartialEvaluationTime.start()) {
+        try (TimerCloseable a = PartialEvaluationTime.start(); Closeable c = PartialEvaluationMemUse.start()) {
             graph = partialEvaluator.createGraph(compilable, assumptions);
         }
 
@@ -156,7 +161,7 @@
         }
 
         CompilationResult result = null;
-        try (TimerCloseable a = CompilationTime.start(); Scope s = Debug.scope("TruffleGraal.GraalCompiler", graph, providers.getCodeCache())) {
+        try (TimerCloseable a = CompilationTime.start(); Scope s = Debug.scope("TruffleGraal.GraalCompiler", graph, providers.getCodeCache()); Closeable c = CompilationMemUse.start()) {
             CodeCacheProvider codeCache = providers.getCodeCache();
             CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false);
             CompilationResult compilationResult = new CompilationResult(name);
@@ -183,7 +188,7 @@
         result.setAssumptions(newAssumptions);
 
         InstalledCode installedCode;
-        try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start()) {
+        try (Scope s = Debug.scope("CodeInstall", providers.getCodeCache()); TimerCloseable a = CodeInstallationTime.start(); Closeable c = CodeInstallationMemUse.start()) {
             installedCode = providers.getCodeCache().addMethod(graph.method(), result, speculationLog, predefinedInstalledCode);
         } catch (Throwable e) {
             throw Debug.handle(e);
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Wed May 28 20:33:49 2014 -0700
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Wed May 28 20:36:10 2014 -0700
@@ -267,14 +267,16 @@
   return cp->name_and_type_ref_index_at(index);
 C2V_END
 
-C2V_VMENTRY(jlong, lookupNameRefInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jobject, lookupNameRefInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
-  return (jlong) (address) cp->name_ref_at(index);
+  Handle sym = java_lang_String::create_from_symbol(cp->name_ref_at(index), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, sym());
 C2V_END
 
-C2V_VMENTRY(jlong, lookupSignatureRefInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
+C2V_VMENTRY(jobject, lookupSignatureRefInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
   constantPoolHandle cp = (ConstantPool*) metaspace_constant_pool;
-  return (jlong) (address) cp->signature_ref_at(index);
+  Handle sym = java_lang_String::create_from_symbol(cp->signature_ref_at(index), CHECK_NULL);
+  return JNIHandles::make_local(THREAD, sym());
 C2V_END
 
 C2V_VMENTRY(jint, lookupKlassRefIndexInPool, (JNIEnv*, jobject, jlong metaspace_constant_pool, jint index))
@@ -729,6 +731,11 @@
   return tty->time_stamp().milliseconds();
 C2V_END
 
+C2V_VMENTRY(jobject, getSymbol, (JNIEnv*, jobject, jlong metaspaceSymbol))
+  Handle sym = java_lang_String::create_from_symbol((Symbol*)(address)metaspaceSymbol, CHECK_NULL);
+  return JNIHandles::make_local(THREAD, sym());
+C2V_END
+
 bool matches(jlongArray methods, Method* method) {
   typeArrayOop methods_oop = (typeArrayOop) JNIHandles::resolve(methods);
 
@@ -999,7 +1006,6 @@
 #define METASPACE_METHOD      "J"
 #define METASPACE_METHOD_DATA "J"
 #define METASPACE_CONSTANT_POOL "J"
-#define METASPACE_SYMBOL      "J"
 
 JNINativeMethod CompilerToVM_methods[] = {
   {CC"getBytecode",                                  CC"("METASPACE_METHOD")[B",                                               FN_PTR(getBytecode)},
@@ -1016,9 +1022,9 @@
   {CC"lookupType",                                   CC"("STRING CLASS"Z)"METASPACE_KLASS,                                     FN_PTR(lookupType)},
   {CC"resolveConstantInPool",                        CC"("METASPACE_CONSTANT_POOL"I)"OBJECT,                                   FN_PTR(resolveConstantInPool)},
   {CC"resolvePossiblyCachedConstantInPool",          CC"("METASPACE_CONSTANT_POOL"I)"OBJECT,                                   FN_PTR(resolvePossiblyCachedConstantInPool)},
-  {CC"lookupNameRefInPool",                          CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_SYMBOL,                         FN_PTR(lookupNameRefInPool)},
+  {CC"lookupNameRefInPool",                          CC"("METASPACE_CONSTANT_POOL"I)"STRING,                                   FN_PTR(lookupNameRefInPool)},
   {CC"lookupNameAndTypeRefIndexInPool",              CC"("METASPACE_CONSTANT_POOL"I)I",                                        FN_PTR(lookupNameAndTypeRefIndexInPool)},
-  {CC"lookupSignatureRefInPool",                     CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_SYMBOL,                         FN_PTR(lookupSignatureRefInPool)},
+  {CC"lookupSignatureRefInPool",                     CC"("METASPACE_CONSTANT_POOL"I)"STRING,                                   FN_PTR(lookupSignatureRefInPool)},
   {CC"lookupKlassRefIndexInPool",                    CC"("METASPACE_CONSTANT_POOL"I)I",                                        FN_PTR(lookupKlassRefIndexInPool)},
   {CC"constantPoolKlassAt",                          CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_KLASS,                          FN_PTR(constantPoolKlassAt)},
   {CC"lookupKlassInPool",                            CC"("METASPACE_CONSTANT_POOL"I)"METASPACE_KLASS,                          FN_PTR(lookupKlassInPool)},
@@ -1052,6 +1058,7 @@
   {CC"allocateCompileId",                            CC"("METASPACE_METHOD"I)I",                                               FN_PTR(allocateCompileId)},
   {CC"isMature",                                     CC"("METASPACE_METHOD_DATA")Z",                                           FN_PTR(isMature)},
   {CC"hasCompiledCodeForOSR",                        CC"("METASPACE_METHOD"II)Z",                                              FN_PTR(hasCompiledCodeForOSR)},
+  {CC"getSymbol",                                    CC"(J)"STRING,                                                            FN_PTR(getSymbol)},
   {CC"getTimeStamp",                                 CC"()J",                                                                  FN_PTR(getTimeStamp)},
   {CC"getNextStackFrame",                            CC"("HS_STACK_FRAME_REF "[JI)"HS_STACK_FRAME_REF,                         FN_PTR(getNextStackFrame)},
   {CC"materializeVirtualObjects",                    CC"("HS_STACK_FRAME_REF"Z)V",                                             FN_PTR(materializeVirtualObjects)},