changeset 14571:24431a9b878c

Merge with 5e04917e66165ef93fe7b61030c4d89a08b3d53c
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Mon, 17 Mar 2014 12:40:35 -0700
parents c828417b7037 (current diff) 5e04917e6616 (diff)
children 1d35a2b84553
files graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java
diffstat 122 files changed, 1716 insertions(+), 1075 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG.md	Mon Mar 17 12:39:25 2014 -0700
+++ b/CHANGELOG.md	Mon Mar 17 12:40:35 2014 -0700
@@ -7,7 +7,16 @@
 * Made graph caching compilation-local.
 
 ### Truffle
-* ...
+* New API TruffleRuntime#createCallNode to create call nodes and to give the runtime system control over its implementation.
+* New API RootNode#getCachedCallNodes to get a weak set of CallNodes that have registered to call the RootNode.
+* New API to split the AST of a call-site context sensitively. CallNode#split, CallNode#isSplittable, CallNode#getSplitCallTarget, CallNode#getCurrentCallTarget, RootNode#isSplittable, RootNode#split.
+* New API to inline a call-site into the call-graph. CallNode#isInlinable, CallNode#inline, CallNode#isInlined.
+* New API for the runtime environment to register CallTargets as caller to the RootNode. CallNode#registerCallTarget.
+* Improved API for counting nodes in Truffle ASTS. NodeUtil#countNodes can be used with a NodeFilter filter Nodes.
+* New API to declare the cost of a Node for use in runtime environment specific heuristics. See NodeCost, Node#getCost() and NodeInfo#cost().
+* Removed old API for NodeInfo#Kind and NodeInfo#kind(). As a replacement the new Node cost API can be used.
+
+
 
 ## Version 0.1
 5-Feb-2014, [Repository Revision](http://hg.openjdk.java.net/graal/graal/rev/b124e22eb772)
--- a/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.amd64/src/com/oracle/graal/amd64/AMD64.java	Mon Mar 17 12:40:35 2014 -0700
@@ -146,7 +146,6 @@
                 case Short:
                 case Int:
                 case Long:
-                case NarrowOop:
                 case Object:
                     return true;
             }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/Architecture.java	Mon Mar 17 12:40:35 2014 -0700
@@ -198,8 +198,6 @@
                 return 8;
             case Object:
                 return wordSize;
-            case NarrowOop:
-                return wordSize / 2;
             default:
                 return 0;
         }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CalleeSaveLayout.java	Mon Mar 17 12:40:35 2014 -0700
@@ -71,7 +71,7 @@
      *            CSA
      * @param registers the registers that can be saved in the CSA
      */
-    public CalleeSaveLayout(Architecture architecture, int frameOffsetToCSA, int size, int slotSize, Register... registers) {
+    public CalleeSaveLayout(TargetDescription target, int frameOffsetToCSA, int size, int slotSize, Register... registers) {
         this.frameOffsetToCSA = frameOffsetToCSA;
         assert slotSize == 0 || CodeUtil.isPowerOf2(slotSize);
         this.slotSize = slotSize;
@@ -88,8 +88,8 @@
             if (offset > maxOffset) {
                 maxOffset = offset;
             }
-            PlatformKind kind = architecture.getLargestStorableKind(reg.getRegisterCategory());
-            offset += architecture.getSizeInBytes(kind);
+            PlatformKind kind = target.arch.getLargestStorableKind(reg.getRegisterCategory());
+            offset += target.getSizeInBytes(kind);
         }
         if (size == -1) {
             this.size = offset;
@@ -106,8 +106,8 @@
             int index = offset / slotSize;
             regNumToIndex[reg.number] = index;
             indexToReg[index] = reg;
-            PlatformKind kind = architecture.getLargestStorableKind(reg.getRegisterCategory());
-            offset += architecture.getSizeInBytes(kind);
+            PlatformKind kind = target.arch.getLargestStorableKind(reg.getRegisterCategory());
+            offset += target.getSizeInBytes(kind);
         }
     }
 
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Mon Mar 17 12:40:35 2014 -0700
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.api.code;
 
+import com.oracle.graal.api.code.CompilationResult.Data;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.meta.*;
 
@@ -85,6 +86,11 @@
     boolean needsDataPatch(Constant constant);
 
     /**
+     * Create a {@link Data} item for a {@link Constant}, that can be used in a {@link DataPatch}.
+     */
+    Data createDataItem(Constant constant, int alignment);
+
+    /**
      * Gets a description of the target architecture.
      */
     TargetDescription getTarget();
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeUtil.java	Mon Mar 17 12:40:35 2014 -0700
@@ -281,6 +281,17 @@
         }
     }
 
+    public static class NumberedRefMapFormatter implements RefMapFormatter {
+
+        public String formatStackSlot(int frameRefMapIndex) {
+            return "s" + frameRefMapIndex;
+        }
+
+        public String formatRegister(int regRefMapIndex) {
+            return "r" + regRefMapIndex;
+        }
+    }
+
     /**
      * Appends a formatted debug info to a {@link StringBuilder}.
      * 
@@ -288,7 +299,11 @@
      * @param info the debug info to format and append to {@code sb}
      * @return the value of {@code sb}
      */
-    public static StringBuilder append(StringBuilder sb, DebugInfo info, RefMapFormatter formatter) {
+    public static StringBuilder append(StringBuilder sb, DebugInfo info, RefMapFormatter formatterArg) {
+        RefMapFormatter formatter = formatterArg;
+        if (formatter == null) {
+            formatter = new NumberedRefMapFormatter();
+        }
         String nl = NEW_LINE;
         ReferenceMap refMap = info.getReferenceMap();
         if (refMap != null && refMap.hasRegisterRefMap()) {
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Mon Mar 17 12:40:35 2014 -0700
@@ -28,6 +28,7 @@
 import java.nio.*;
 import java.util.*;
 
+import com.oracle.graal.api.code.CodeUtil.*;
 import com.oracle.graal.api.meta.*;
 
 /**
@@ -152,66 +153,64 @@
             return alignment;
         }
 
-        public abstract int getSize(Architecture arch);
+        public abstract int getSize(TargetDescription target);
 
-        public abstract void emit(Architecture arch, ByteBuffer buffer);
+        public abstract Kind getKind();
+
+        public abstract void emit(TargetDescription target, ByteBuffer buffer);
     }
 
-    public static final class ConstantData extends Data {
+    /**
+     * Represents a Java primitive value used in a {@link DataPatch}. This implementation uses
+     * {@link Kind#getByteCount()} bytes to encode each value.
+     */
+    public static final class PrimitiveData extends Data {
 
         public final Constant constant;
 
-        public ConstantData(Constant constant, int alignment) {
+        public PrimitiveData(Constant constant, int alignment) {
             super(alignment);
+            assert constant.getKind().isPrimitive();
             this.constant = constant;
         }
 
         @Override
-        public int getSize(Architecture arch) {
-            return arch.getSizeInBytes(constant.getPlatformKind());
+        public int getSize(TargetDescription target) {
+            return constant.getKind().getByteCount();
+        }
+
+        @Override
+        public Kind getKind() {
+            return constant.getKind();
         }
 
         @Override
-        public void emit(Architecture arch, ByteBuffer buffer) {
+        public void emit(TargetDescription target, ByteBuffer buffer) {
             switch (constant.getKind()) {
                 case Boolean:
-                    assert getSize(arch) == 1;
                     buffer.put(constant.asBoolean() ? (byte) 1 : (byte) 0);
                     break;
                 case Byte:
-                    assert getSize(arch) == 1;
                     buffer.put((byte) constant.asInt());
                     break;
                 case Char:
-                    assert getSize(arch) == 2;
                     buffer.putChar((char) constant.asInt());
                     break;
                 case Short:
-                    assert getSize(arch) == 2;
                     buffer.putShort((short) constant.asInt());
                     break;
                 case Int:
-                    assert getSize(arch) == 4;
                     buffer.putInt(constant.asInt());
                     break;
                 case Long:
-                    assert getSize(arch) == 8;
                     buffer.putLong(constant.asLong());
                     break;
                 case Float:
-                    assert getSize(arch) == 4;
                     buffer.putFloat(constant.asFloat());
                     break;
                 case Double:
-                    assert getSize(arch) == 8;
                     buffer.putDouble(constant.asDouble());
                     break;
-                case Object:
-                    // placeholder for oop value
-                    for (int i = 0; i < getSize(arch); i++) {
-                        buffer.put((byte) 0);
-                    }
-                    break;
             }
         }
 
@@ -219,6 +218,24 @@
         public String toString() {
             return constant.toString();
         }
+
+        @Override
+        public int hashCode() {
+            return constant.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof PrimitiveData) {
+                PrimitiveData other = (PrimitiveData) obj;
+                return constant.equals(other.constant);
+            } else {
+                return false;
+            }
+        }
     }
 
     public static final class RawData extends Data {
@@ -231,12 +248,17 @@
         }
 
         @Override
-        public int getSize(Architecture arch) {
+        public int getSize(TargetDescription target) {
             return data.length;
         }
 
         @Override
-        public void emit(Architecture arch, ByteBuffer buffer) {
+        public Kind getKind() {
+            return Kind.Illegal;
+        }
+
+        @Override
+        public void emit(TargetDescription target, ByteBuffer buffer) {
             buffer.put(data);
         }
 
@@ -250,6 +272,24 @@
             }
             return ret.toString();
         }
+
+        @Override
+        public int hashCode() {
+            return Arrays.hashCode(data);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof RawData) {
+                RawData other = (RawData) obj;
+                return Arrays.equals(data, other.data);
+            } else {
+                return false;
+            }
+        }
     }
 
     /**
@@ -260,53 +300,18 @@
     public static final class DataPatch extends Site {
 
         private static final long serialVersionUID = 5771730331604867476L;
-        public Data externalData;
-        public Constant inlineData;
-
-        DataPatch(int pcOffset, Data externalData) {
-            this(pcOffset, externalData, null);
-        }
-
-        DataPatch(int pcOffset, Constant inlineData) {
-            this(pcOffset, null, inlineData);
-        }
-
-        private DataPatch(int pcOffset, Data externalData, Constant inlineData) {
-            super(pcOffset);
-            assert (externalData == null) != (inlineData == null) : "data patch can not be both external and inlined";
-            this.externalData = externalData;
-            this.inlineData = inlineData;
-        }
+        public Data data;
+        public boolean inline;
 
-        public Constant getConstant() {
-            if (inlineData != null) {
-                return inlineData;
-            } else if (externalData instanceof ConstantData) {
-                return ((ConstantData) externalData).constant;
-            } else {
-                return null;
-            }
-        }
-
-        public int getAlignment() {
-            if (externalData instanceof ConstantData) {
-                return ((ConstantData) externalData).getAlignment();
-            } else {
-                return 0;
-            }
-        }
-
-        public String getDataString() {
-            if (inlineData != null) {
-                return inlineData.toString();
-            } else {
-                return externalData.toString();
-            }
+        public DataPatch(int pcOffset, Data data, boolean inline) {
+            super(pcOffset);
+            this.data = data;
+            this.inline = inline;
         }
 
         @Override
         public String toString() {
-            return String.format("%d[<data patch referring to data %s>]", pcOffset, getDataString());
+            return String.format("%d[<data patch referring to %s data %s>]", pcOffset, inline ? "inline" : "external", data.toString());
         }
     }
 
@@ -538,18 +543,18 @@
      */
     public void recordDataReference(int codePos, Data data) {
         assert codePos >= 0 && data != null;
-        dataReferences.add(new DataPatch(codePos, data));
+        dataReferences.add(new DataPatch(codePos, data, false));
     }
 
     /**
      * Records a reference to an inlined constant in the code section (e.g. to load a constant oop).
      * 
      * @param codePos the position in the code where the inlined constant occurs
-     * @param constant the constant that is referenced
+     * @param data the data that is referenced
      */
-    public void recordInlineData(int codePos, Constant constant) {
-        assert codePos >= 0 && constant != null;
-        dataReferences.add(new DataPatch(codePos, constant));
+    public void recordInlineData(int codePos, Data data) {
+        assert codePos >= 0 && data != null;
+        dataReferences.add(new DataPatch(codePos, data, true));
     }
 
     /**
@@ -691,14 +696,15 @@
         if (info != null) {
             ReferenceMap refMap = info.getReferenceMap();
             if (refMap != null) {
+                RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter();
                 if (refMap.hasFrameRefMap()) {
                     sb.append(" stackMap[");
-                    refMap.appendFrameMap(sb, null);
+                    refMap.appendFrameMap(sb, formatter);
                     sb.append(']');
                 }
                 if (refMap.hasRegisterRefMap()) {
                     sb.append(" registerMap[");
-                    refMap.appendRegisterMap(sb, null);
+                    refMap.appendRegisterMap(sb, formatter);
                     sb.append(']');
                 }
             }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ReferenceMap.java	Mon Mar 17 12:40:35 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,123 +22,20 @@
  */
 package com.oracle.graal.api.code;
 
-import java.io.*;
-import java.util.*;
-
 import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
-
-public class ReferenceMap implements Serializable {
-
-    private static final long serialVersionUID = -1052183095979496819L;
-
-    /**
-     * Contains 2 bits per register.
-     * <ul>
-     * <li>bit0 = 0: contains no references</li>
-     * <li>bit0 = 1, bit1 = 0: contains a wide oop</li>
-     * <li>bit0 = 1, bit1 = 1: contains a narrow oop</li>
-     * </ul>
-     */
-    private final BitSet registerRefMap;
-
-    /**
-     * Contains 3 bits per stack slot.
-     * <ul>
-     * <li>bit0 = 0: contains no references</li>
-     * <li>bit0 = 1, bit1+2 = 0: contains a wide oop</li>
-     * <li>bit0 = 1, bit1 = 1: contains a narrow oop in the lower half</li>
-     * <li>bit0 = 1, bit2 = 1: contains a narrow oop in the upper half</li>
-     * </ul>
-     */
-    private final BitSet frameRefMap;
+import com.oracle.graal.api.meta.*;
 
-    public ReferenceMap(int registerCount, int frameSlotCount) {
-        if (registerCount > 0) {
-            this.registerRefMap = new BitSet(registerCount * 2);
-        } else {
-            this.registerRefMap = null;
-        }
-        this.frameRefMap = new BitSet(frameSlotCount * 3);
-    }
+public interface ReferenceMap {
 
-    public void setRegister(int idx, boolean narrow) {
-        registerRefMap.set(2 * idx);
-        if (narrow) {
-            registerRefMap.set(2 * idx + 1);
-        }
-    }
+    void setRegister(int idx, PlatformKind kind);
 
-    public void setStackSlot(int idx, boolean narrow1, boolean narrow2) {
-        frameRefMap.set(3 * idx);
-        if (narrow1) {
-            frameRefMap.set(3 * idx + 1);
-        }
-        if (narrow2) {
-            frameRefMap.set(3 * idx + 2);
-        }
-    }
-
-    public boolean hasRegisterRefMap() {
-        return registerRefMap != null && registerRefMap.size() > 0;
-    }
+    void setStackSlot(int offset, PlatformKind kind);
 
-    public boolean hasFrameRefMap() {
-        return frameRefMap != null && frameRefMap.size() > 0;
-    }
-
-    public interface Iterator {
-        void register(int idx, boolean narrow);
-
-        void stackSlot(int idx, boolean narrow1, boolean narrow2);
-    }
+    boolean hasRegisterRefMap();
 
-    public void iterate(Iterator iterator) {
-        if (hasRegisterRefMap()) {
-            for (int i = 0; i < registerRefMap.size() / 2; i++) {
-                if (registerRefMap.get(2 * i)) {
-                    iterator.register(i, registerRefMap.get(2 * i + 1));
-                }
-            }
-        }
-        if (hasFrameRefMap()) {
-            for (int i = 0; i < frameRefMap.size() / 3; i++) {
-                if (frameRefMap.get(3 * i)) {
-                    iterator.stackSlot(i, frameRefMap.get(3 * i + 1), frameRefMap.get(3 * i + 2));
-                }
-            }
-        }
-    }
-
-    private static class NumberedRefMapFormatter implements RefMapFormatter {
+    boolean hasFrameRefMap();
 
-        public String formatStackSlot(int frameRefMapIndex) {
-            return "s" + frameRefMapIndex;
-        }
-
-        public String formatRegister(int regRefMapIndex) {
-            return "r" + regRefMapIndex;
-        }
-    }
-
-    public void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg) {
-        RefMapFormatter formatter = formatterArg;
-        if (formatter == null) {
-            formatter = new NumberedRefMapFormatter();
-        }
+    void appendRegisterMap(StringBuilder sb, RefMapFormatter formatterArg);
 
-        for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 2)) {
-            sb.append(' ').append(formatter.formatRegister(reg / 2));
-        }
-    }
-
-    public void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg) {
-        RefMapFormatter formatter = formatterArg;
-        if (formatter == null) {
-            formatter = new NumberedRefMapFormatter();
-        }
-
-        for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 3)) {
-            sb.append(' ').append(formatter.formatStackSlot(slot / 3));
-        }
-    }
+    void appendFrameMap(StringBuilder sb, RefMapFormatter formatterArg);
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/TargetDescription.java	Mon Mar 17 12:40:35 2014 -0700
@@ -28,7 +28,7 @@
  * Represents the target machine for a compiler, including the CPU architecture, the size of
  * pointers and references, alignment of stacks, caches, etc.
  */
-public class TargetDescription {
+public abstract class TargetDescription {
 
     public final Architecture arch;
 
@@ -81,4 +81,10 @@
         this.implicitNullCheckLimit = implicitNullCheckLimit;
         this.inlineObjects = inlineObjects;
     }
+
+    public int getSizeInBytes(PlatformKind kind) {
+        return arch.getSizeInBytes(kind);
+    }
+
+    public abstract ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount);
 }
--- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java	Mon Mar 17 12:40:35 2014 -0700
@@ -77,22 +77,6 @@
         }
     }
 
-    /**
-     * @see ResolvedJavaMethod#getCompiledCodeSize()
-     */
-    @Test
-    public void getCompiledCodeSizeTest() {
-        for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
-            ResolvedJavaMethod m = e.getValue();
-            int size = m.getCompiledCodeSize();
-            if (isAbstract(m.getModifiers())) {
-                assertTrue(size == 0);
-            } else {
-                assertTrue(size >= 0);
-            }
-        }
-    }
-
     @Test
     public void getModifiersTest() {
         for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Mon Mar 17 12:40:35 2014 -0700
@@ -159,7 +159,6 @@
             case Double:
                 return asDouble();
             case Object:
-            case NarrowOop:
                 return object;
             case Illegal:
                 return this;
@@ -172,7 +171,7 @@
         if (!ignoreKind && getKind() != other.getKind()) {
             return false;
         }
-        if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) {
+        if (getKind() == Kind.Object) {
             return object == other.object;
         }
         return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation();
@@ -235,12 +234,12 @@
 
     /**
      * Returns the object reference this constant represents. The constant must have kind
-     * {@link Kind#Object} or {@link Kind#NarrowOop}.
+     * {@link Kind#Object}.
      * 
      * @return the constant value
      */
     public Object asObject() {
-        assert getKind() == Kind.Object || getKind() == Kind.NarrowOop;
+        assert getKind() == Kind.Object;
         return object;
     }
 
@@ -250,7 +249,7 @@
      * @return null if this constant is not primitive or has no annotation
      */
     public Object getPrimitiveAnnotation() {
-        return getKind() == Kind.Object || getKind() == Kind.NarrowOop ? null : object;
+        return getKind() == Kind.Object ? null : object;
     }
 
     /**
@@ -260,7 +259,7 @@
      */
     @Override
     public int hashCode() {
-        if (getKind() == Kind.Object || getKind() == Kind.NarrowOop) {
+        if (getKind() == Kind.Object) {
             return System.identityHashCode(object);
         }
         return (int) primitive * getKind().ordinal();
@@ -394,16 +393,6 @@
     }
 
     /**
-     * Creates a boxed narrow oop constant.
-     * 
-     * @param o the object value to box
-     * @return a boxed copy of {@code value}
-     */
-    public static Constant forNarrowOop(Object o) {
-        return new Constant(Kind.NarrowOop, o, 0L);
-    }
-
-    /**
      * Creates an annotated int or long constant. An annotation enables a client to associate some
      * extra semantic or debugging information with a primitive. An annotated primitive constant is
      * never {@linkplain #equals(Object) equal} to a non-annotated constant.
@@ -463,8 +452,6 @@
                 return forDouble((Double) value);
             case Object:
                 return forObject(value);
-            case NarrowOop:
-                return forNarrowOop(value);
             default:
                 throw new RuntimeException("cannot create Constant for boxed " + kind + " value");
         }
@@ -497,8 +484,6 @@
                 return LONG_0;
             case Object:
                 return NULL_OBJECT;
-            case NarrowOop:
-                return forNarrowOop(null);
             default:
                 throw new IllegalArgumentException(kind.toString());
         }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/DefaultProfilingInfo.java	Mon Mar 17 12:40:35 2014 -0700
@@ -99,4 +99,12 @@
     public void setMature() {
         // Do nothing
     }
+
+    public boolean setCompilerIRSize(Class<?> irType, int nodeCount) {
+        return false;
+    }
+
+    public int getCompilerIRSize(Class<?> irType) {
+        return -1;
+    }
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java	Mon Mar 17 12:40:35 2014 -0700
@@ -57,9 +57,6 @@
     /** The Object kind, also used for arrays. */
     Object('a', "Object", false, null, null),
 
-    /** The narrow oop kind. */
-    NarrowOop('n', "NarrowOop", false, null, null),
-
     /** The void float kind. */
     Void('v', "void", false, java.lang.Void.TYPE, java.lang.Void.class),
 
@@ -149,10 +146,10 @@
     /**
      * Checks whether this represent an Object of some sort.
      * 
-     * @return {@code true} if this is {@link #Object} or {@link #NarrowOop}.
+     * @return {@code true} if this is {@link #Object}.
      */
     public boolean isObject() {
-        return this == Kind.Object || this == Kind.NarrowOop;
+        return this == Kind.Object;
     }
 
     /**
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ProfilingInfo.java	Mon Mar 17 12:40:35 2014 -0700
@@ -114,6 +114,25 @@
     int getDeoptimizationCount(DeoptimizationReason reason);
 
     /**
+     * Records the size of the compiler intermediate representation (IR) associated with this
+     * method.
+     * 
+     * @param irType the IR type for which the size is being recorded
+     * @param irSize the IR size to be recorded. The unit depends on the IR.
+     * @return whether recording this information for {@code irType} is supported
+     */
+    boolean setCompilerIRSize(Class<?> irType, int irSize);
+
+    /**
+     * Gets the size of the compiler intermediate representation (IR) associated with this method
+     * last recorded by {@link #setCompilerIRSize(Class, int)}.
+     * 
+     * @param irType the IR type for which the size is being requested
+     * @return the requested IR size or -1 if it is unavailable for {@code irType}
+     */
+    int getCompilerIRSize(Class<?> irType);
+
+    /**
      * Returns true if the profiling information can be assumed as sufficiently accurate.
      * 
      * @return true if the profiling information was recorded often enough mature enough, false
@@ -124,6 +143,5 @@
     /**
      * Force data to be treated as mature if possible.
      */
-
     void setMature();
 }
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/ResolvedJavaMethod.java	Mon Mar 17 12:40:35 2014 -0700
@@ -24,7 +24,6 @@
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
-import java.util.*;
 
 /**
  * Represents a resolved Java method. Methods, like fields and types, are resolved through
@@ -54,13 +53,6 @@
     int getCodeSize();
 
     /**
-     * Returns the size of the compiled machine code of this method.
-     * 
-     * @return the size of the compiled machine code in bytes, or 0 if no compiled code exists.
-     */
-    int getCompiledCodeSize();
-
-    /**
      * Returns the {@link ResolvedJavaType} object representing the class or interface that declares
      * this method.
      */
@@ -144,12 +136,6 @@
     void reprofile();
 
     /**
-     * Returns a map that the compiler can use to store objects that should survive the current
-     * compilation.
-     */
-    Map<Object, Object> getCompilerStorage();
-
-    /**
      * Returns the constant pool of this method.
      */
     ConstantPool getConstantPool();
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Mar 17 12:40:35 2014 -0700
@@ -27,7 +27,7 @@
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.ConstantData;
+import com.oracle.graal.api.code.CompilationResult.PrimitiveData;
 import com.oracle.graal.api.code.CompilationResult.RawData;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
@@ -59,7 +59,7 @@
             public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
                 AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig);
                 Register ret = registerConfig.getReturnRegister(Kind.Double);
-                compResult.recordDataReference(asm.position(), new ConstantData(Constant.forDouble(84.72), 8));
+                compResult.recordDataReference(asm.position(), new PrimitiveData(Constant.forDouble(84.72), 8));
                 asm.movdbl(ret, asm.getPlaceholder());
                 asm.ret(0);
                 return asm.close(true);
--- a/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.asm.amd64/src/com/oracle/graal/asm/amd64/AMD64MacroAssembler.java	Mon Mar 17 12:40:35 2014 -0700
@@ -261,7 +261,7 @@
     private AMD64Address trigPrologue(Register value) {
         assert value.getRegisterCategory() == AMD64.XMM;
         AMD64Address tmp = new AMD64Address(AMD64.rsp);
-        subq(AMD64.rsp, target.arch.getSizeInBytes(Kind.Double));
+        subq(AMD64.rsp, target.getSizeInBytes(Kind.Double));
         movdbl(tmp, value);
         fldd(tmp);
         return tmp;
@@ -271,7 +271,7 @@
         assert dest.getRegisterCategory() == AMD64.XMM;
         fstpd(tmp);
         movdbl(dest, tmp);
-        addq(AMD64.rsp, target.arch.getSizeInBytes(Kind.Double));
+        addq(AMD64.rsp, target.getSizeInBytes(Kind.Double));
     }
 
     /**
--- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java	Mon Mar 17 12:40:35 2014 -0700
@@ -264,9 +264,6 @@
             case Byte:
                 prefix = "s8";
                 break;
-            case NarrowOop:
-                prefix = "u32";
-                break;
             default:
                 throw GraalInternalError.shouldNotReachHere();
         }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Mar 17 12:40:35 2014 -0700
@@ -198,11 +198,6 @@
         suites.getLowTier().apply(graph, lowTierContext);
         graph.maybeCompress();
 
-        // we do not want to store statistics about OSR compilations because it may prevent inlining
-        if (!graph.isOSR()) {
-            InliningPhase.storeStatisticsAfterLowTier(graph);
-        }
-
         SchedulePhase schedule = new SchedulePhase();
         schedule.apply(graph);
         Debug.dump(schedule, "final schedule");
@@ -298,14 +293,9 @@
             for (int i = 0; i < dms.length; i++) {
                 dms[i] = Debug.metric("DataPatches-" + Kind.values()[i].toString());
             }
-            DebugMetric dmRaw = Debug.metric("DataPatches-raw");
 
             for (DataPatch dp : ldp) {
-                if (dp.getConstant() != null) {
-                    dms[dp.getConstant().getKind().ordinal()].add(1);
-                } else {
-                    dmRaw.add(1);
-                }
+                dms[dp.data.getKind().ordinal()].add(1);
             }
 
             Debug.metric("CompilationResults").increment();
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java	Mon Mar 17 12:40:35 2014 -0700
@@ -25,15 +25,12 @@
 import static com.oracle.graal.compiler.phases.HighTier.Options.*;
 import static com.oracle.graal.phases.GraalOptions.*;
 
-import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.loop.phases.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.common.*;
 import com.oracle.graal.phases.tiers.*;
-import com.oracle.graal.phases.verify.*;
 import com.oracle.graal.virtual.phases.ea.*;
 
 public class HighTier extends PhaseSuite<HighTierContext> {
@@ -41,8 +38,6 @@
     public static class Options {
 
         // @formatter:off
-        @Option(help = "")
-        public static final OptionValue<Boolean> VerifyUsageWithEquals = new OptionValue<>(true);
         @Option(help = "Enable inlining")
         public static final OptionValue<Boolean> Inline = new OptionValue<>(true);
         // @formatter:on
@@ -51,11 +46,6 @@
     public HighTier() {
         CanonicalizerPhase canonicalizer = new CanonicalizerPhase(!ImmutableCode.getValue());
 
-        if (VerifyUsageWithEquals.getValue()) {
-            appendPhase(new VerifyUsageWithEquals(Value.class));
-            appendPhase(new VerifyUsageWithEquals(Register.class));
-        }
-
         if (OptCanonicalizer.getValue()) {
             appendPhase(canonicalizer);
         }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackendFactory.java	Mon Mar 17 12:40:35 2014 -0700
@@ -89,7 +89,7 @@
         final int stackFrameAlignment = 16;
         final int implicitNullCheckLimit = 4096;
         final boolean inlineObjects = true;
-        return new TargetDescription(createArchitecture(config), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
+        return new HotSpotTargetDescription(createArchitecture(config), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects, Kind.Int);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Mar 17 12:40:35 2014 -0700
@@ -473,8 +473,6 @@
     protected static Constant compress(Constant c, CompressEncoding encoding) {
         if (c.getKind() == Kind.Long) {
             return Constant.forIntegerKind(Kind.Int, (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL), c.getPrimitiveAnnotation());
-        } else if (c.getKind() == Kind.Object) {
-            return Constant.forNarrowOop(c.asObject());
         } else {
             throw GraalInternalError.shouldNotReachHere();
         }
@@ -523,8 +521,7 @@
             if (canStoreConstant(c, isCompressed)) {
                 if (isCompressed) {
                     if (c.getKind() == Kind.Object) {
-                        Constant value = c.isNull() ? c : compress(c, config.getOopEncoding());
-                        append(new StoreCompressedConstantOp(kind, storeAddress, value, state));
+                        append(new StoreCompressedConstantOp(kind, storeAddress, c, state));
                     } else if (c.getKind() == Kind.Long) {
                         // It's always a good idea to directly store compressed constants since they
                         // have to be materialized as 64 bits encoded otherwise.
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Mar 17 12:40:35 2014 -0700
@@ -33,6 +33,7 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
+import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
@@ -51,6 +52,9 @@
         public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (kind == Kind.Long) {
                 if (NumUtil.isInt(input.asLong())) {
+                    if (input.getPrimitiveAnnotation() != null) {
+                        crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), input.getPrimitiveAnnotation(), true));
+                    }
                     masm.movl(address.toAddress(), (int) input.asLong());
                 } else {
                     throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
@@ -59,7 +63,7 @@
                 if (input.isNull()) {
                     masm.movl(address.toAddress(), 0);
                 } else if (crb.target.inlineObjects) {
-                    crb.recordInlineDataInCode(input);
+                    crb.recordInlineDataInCode(new OopData(0, input.asObject(), true));
                     masm.movl(address.toAddress(), 0xDEADDEAD);
                 } else {
                     throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotRegisterConfig.java	Mon Mar 17 12:40:35 2014 -0700
@@ -33,6 +33,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.nodes.type.*;
 
 public class AMD64HotSpotRegisterConfig implements RegisterConfig {
 
@@ -61,9 +62,16 @@
             return categorized.get(kind);
         }
 
+        PlatformKind primitiveKind;
+        if (kind == NarrowOopStamp.NarrowOop) {
+            primitiveKind = Kind.Int;
+        } else {
+            primitiveKind = kind;
+        }
+
         ArrayList<Register> list = new ArrayList<>();
         for (Register reg : getAllocatableRegisters()) {
-            if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
+            if (architecture.canStoreValue(reg.getRegisterCategory(), primitiveKind)) {
                 list.add(reg);
             }
         }
@@ -211,7 +219,7 @@
 
             if (locations[i] == null) {
                 locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out);
-                currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize);
+                currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize);
             }
         }
 
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackendFactory.java	Mon Mar 17 12:40:35 2014 -0700
@@ -62,7 +62,7 @@
         final int stackFrameAlignment = 8;
         final int implicitNullCheckLimit = 0;
         final boolean inlineObjects = true;
-        return new TargetDescription(new HSAIL(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
+        return new HotSpotTargetDescription(new HSAIL(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects, Kind.Int);
     }
 
     public String getArchitecture() {
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Mon Mar 17 12:40:35 2014 -0700
@@ -162,7 +162,7 @@
             if (canStoreConstant(c, isCompressed)) {
                 if (isCompressed) {
                     if ((c.getKind() == Kind.Object) && c.isNull()) {
-                        append(new StoreConstantOp(Kind.NarrowOop, storeAddress, c, state));
+                        append(new StoreConstantOp(Kind.Int, storeAddress, Constant.forInt(0), state));
                     } else {
                         throw GraalInternalError.shouldNotReachHere("can't handle: " + access);
                     }
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotBackendFactory.java	Mon Mar 17 12:40:35 2014 -0700
@@ -59,7 +59,7 @@
         final int stackFrameAlignment = 1;
         final int implicitNullCheckLimit = 0;
         final boolean inlineObjects = true;
-        return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
+        return new HotSpotTargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects, Kind.Int);
     }
 
     public String getArchitecture() {
--- a/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.ptx/src/com/oracle/graal/hotspot/ptx/PTXHotSpotRegisterConfig.java	Mon Mar 17 12:40:35 2014 -0700
@@ -133,7 +133,7 @@
 
             if (locations[i] == null) {
                 locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out);
-                currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize);
+                currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize);
             }
         }
 
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Mar 17 12:40:35 2014 -0700
@@ -42,7 +42,7 @@
         final int stackFrameAlignment = 16;
         final int implicitNullCheckLimit = 4096;
         final boolean inlineObjects = true;
-        return new TargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
+        return new HotSpotTargetDescription(createArchitecture(), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects, Kind.Int);
     }
 
     public HotSpotBackend createBackend(HotSpotGraalRuntime runtime, HotSpotBackend host) {
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotCodeCacheProvider.java	Mon Mar 17 12:40:35 2014 -0700
@@ -34,6 +34,6 @@
 
     @Override
     protected RegisterConfig createRegisterConfig() {
-        return new SPARCHotSpotRegisterConfig(getTarget().arch, runtime.getConfig());
+        return new SPARCHotSpotRegisterConfig(getTarget(), runtime.getConfig());
     }
 }
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotRegisterConfig.java	Mon Mar 17 12:40:35 2014 -0700
@@ -130,10 +130,10 @@
         return registers;
     }
 
-    public SPARCHotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
-        this.architecture = architecture;
+    public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
+        this.architecture = target.arch;
 
-        csl = new CalleeSaveLayout(architecture, -1, -1, architecture.getWordSize(), calleeSaveRegisters);
+        csl = new CalleeSaveLayout(target, -1, -1, target.arch.getWordSize(), calleeSaveRegisters);
         allocatable = initAllocatable(config.useCompressedOops);
         attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters);
     }
@@ -203,7 +203,7 @@
 
             if (locations[i] == null) {
                 locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out);
-                currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize);
+                currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize);
             }
         }
 
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Mon Mar 17 12:40:35 2014 -0700
@@ -49,7 +49,7 @@
     protected InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult) {
         HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;
         HotSpotNmethod installedCode = new HotSpotNmethod(hsMethod, compResult.getName(), true);
-        HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(runtime().getTarget().arch, hsMethod, compResult);
+        HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(runtime().getTarget(), hsMethod, compResult);
         CodeInstallResult result = runtime().getCompilerToVM().installCode(compiledNmethod, installedCode, null);
         Assert.assertEquals("Error installing method " + method + ": " + result, result, CodeInstallResult.OK);
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java	Mon Mar 17 12:40:35 2014 -0700
@@ -102,10 +102,10 @@
         }
     }
 
-    public void finish(HotSpotResolvedJavaMethod method) {
+    public void finish(HotSpotResolvedJavaMethod method, HotSpotInstalledCode code) {
         if (ENABLED) {
             duration = System.nanoTime() - startTime;
-            codeSize = method.getCompiledCodeSize();
+            codeSize = (int) code.getCodeSize();
             memoryUsed = getThreadAllocatedBytes() - threadAllocatedBytesStart;
             if (current.get().getLast() != this) {
                 throw new RuntimeException("mismatch in finish()");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java	Mon Mar 17 12:40:35 2014 -0700
@@ -54,6 +54,8 @@
 
 public class CompilationTask implements Runnable, Comparable {
 
+    private static final long TIMESTAMP_START = System.currentTimeMillis();
+
     // Keep static finals in a group with withinEnqueue as the last one. CompilationTask can be
     // called from within it's own clinit so it needs to be careful about accessing state. Once
     // withinEnqueue is non-null we assume that CompilationTask is fully initialized.
@@ -279,8 +281,12 @@
 
             try (TimerCloseable b = CodeInstallationTime.start()) {
                 installedCode = installMethod(result);
+                if (!isOSR) {
+                    ProfilingInfo profile = method.getProfilingInfo();
+                    profile.setCompilerIRSize(StructuredGraph.class, graph.getNodeCount());
+                }
             }
-            stats.finish(method);
+            stats.finish(method, installedCode);
         } catch (BailoutException bailout) {
             BAILOUTS.increment();
             if (ExitVMOnBailout.getValue()) {
@@ -326,7 +332,24 @@
     private void printCompilation() {
         final boolean isOSR = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI;
         final int mod = method.getModifiers();
-        TTY.println(String.format("%7d %4d %c%c%c%c%c       %s %s(%d bytes)", 0, id, isOSR ? '%' : ' ', Modifier.isSynchronized(mod) ? 's' : ' ', ' ', ' ', Modifier.isNative(mod) ? 'n' : ' ',
+        String compilerName = "";
+        if (HotSpotCIPrintCompilerName.getValue()) {
+            compilerName = "Graal:";
+        }
+        HotSpotVMConfig config = backend.getRuntime().getConfig();
+        int compLevel = config.compilationLevelFullOptimization;
+        char compLevelChar;
+        if (config.tieredCompilation) {
+            compLevelChar = '-';
+            if (compLevel != -1) {
+                compLevelChar = (char) ('0' + compLevel);
+            }
+        } else {
+            compLevelChar = ' ';
+        }
+        boolean hasExceptionHandlers = method.getExceptionHandlers().length > 0;
+        TTY.println(String.format("%s%7d %4d %c%c%c%c%c%c      %s %s(%d bytes)", compilerName, (System.currentTimeMillis() - TIMESTAMP_START), id, isOSR ? '%' : ' ',
+                        Modifier.isSynchronized(mod) ? 's' : ' ', hasExceptionHandlers ? '!' : ' ', blocking ? 'b' : ' ', Modifier.isNative(mod) ? 'n' : ' ', compLevelChar,
                         MetaUtil.format("%H::%n(%p)", method), isOSR ? "@ " + entryBCI + " " : "", method.getCodeSize()));
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java	Mon Mar 17 12:40:35 2014 -0700
@@ -22,21 +22,17 @@
  */
 package com.oracle.graal.hotspot;
 
-import java.nio.*;
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CompilationResult.CodeAnnotation;
 import com.oracle.graal.api.code.CompilationResult.CodeComment;
-import com.oracle.graal.api.code.CompilationResult.Data;
-import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.ExceptionHandler;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.code.CompilationResult.JumpTable;
 import com.oracle.graal.api.code.CompilationResult.Mark;
 import com.oracle.graal.api.code.CompilationResult.Site;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
+import com.oracle.graal.hotspot.data.*;
 
 /**
  * A {@link CompilationResult} with additional HotSpot-specific information required for installing
@@ -53,111 +49,6 @@
 
     public final DataSection dataSection;
 
-    /**
-     * Represents a reference to the data section. Before the code is installed, all {@link Data}
-     * items referenced by a {@link DataPatch} are put into the data section of the method, and
-     * replaced by {@link HotSpotData}.
-     */
-    public static final class HotSpotData extends Data {
-
-        /**
-         * The offset of the data item in the data section.
-         */
-        public int offset;
-
-        /**
-         * If the data item is an oop that needs to be patched by the runtime, this field contains
-         * the reference to the object.
-         */
-        public Constant constant;
-
-        public HotSpotData(int offset) {
-            super(0);
-            this.offset = offset;
-        }
-
-        @Override
-        public int getSize(Architecture arch) {
-            return 0;
-        }
-
-        @Override
-        public void emit(Architecture arch, ByteBuffer buffer) {
-        }
-    }
-
-    /**
-     * Represents the data section of a method.
-     */
-    public static final class DataSection {
-
-        /**
-         * The minimum alignment required for this data section.
-         */
-        public final int sectionAlignment;
-
-        /**
-         * The raw data contained in the data section.
-         */
-        public final byte[] data;
-
-        /**
-         * A list of locations where oop pointers need to be patched by the runtime.
-         */
-        public final HotSpotData[] patches;
-
-        public DataSection(Architecture arch, Site[] sites) {
-            int size = 0;
-            int patchCount = 0;
-            List<DataPatch> externalDataList = new ArrayList<>();
-
-            // find all external data items and determine total size of data section
-            for (Site site : sites) {
-                if (site instanceof DataPatch) {
-                    DataPatch dataPatch = (DataPatch) site;
-                    if (dataPatch.externalData != null) {
-                        Data d = dataPatch.externalData;
-                        size = NumUtil.roundUp(size, d.getAlignment());
-                        size += d.getSize(arch);
-                        externalDataList.add(dataPatch);
-                        if (dataPatch.getConstant() != null && dataPatch.getConstant().getKind() == Kind.Object) {
-                            patchCount++;
-                        }
-                    }
-                }
-            }
-
-            data = new byte[size];
-            patches = new HotSpotData[patchCount];
-            ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());
-            int index = 0;
-            int patchIndex = 0;
-            int alignment = 0;
-
-            // build data section
-            for (DataPatch dataPatch : externalDataList) {
-                Data d = dataPatch.externalData;
-
-                alignment = Math.max(alignment, d.getAlignment());
-                index = NumUtil.roundUp(index, d.getAlignment());
-                buffer.position(index);
-
-                HotSpotData hsData = new HotSpotData(index);
-                if (dataPatch.getConstant() != null && dataPatch.getConstant().getKind() == Kind.Object) {
-                    // record patch location for oop pointers
-                    hsData.constant = dataPatch.getConstant();
-                    patches[patchIndex++] = hsData;
-                }
-                dataPatch.externalData = hsData;
-
-                index += d.getSize(arch);
-                d.emit(arch, buffer);
-            }
-
-            this.sectionAlignment = alignment;
-        }
-    }
-
     public static class Comment {
 
         public final String text;
@@ -169,10 +60,10 @@
         }
     }
 
-    public HotSpotCompiledCode(Architecture arch, CompilationResult compResult) {
+    public HotSpotCompiledCode(TargetDescription target, CompilationResult compResult) {
         this.comp = compResult;
         sites = getSortedSites(compResult);
-        dataSection = new DataSection(arch, sites);
+        dataSection = new DataSection(target, sites);
         if (compResult.getExceptionHandlers().isEmpty()) {
             exceptionHandlers = null;
         } else {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java	Mon Mar 17 12:40:35 2014 -0700
@@ -35,8 +35,8 @@
     public final int entryBCI;
     public final int id;
 
-    public HotSpotCompiledNmethod(Architecture arch, HotSpotResolvedJavaMethod method, CompilationResult compResult) {
-        super(arch, compResult);
+    public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult) {
+        super(target, compResult);
         this.method = method;
         this.entryBCI = compResult.getEntryBCI();
         this.id = compResult.getId();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java	Mon Mar 17 12:40:35 2014 -0700
@@ -26,7 +26,7 @@
 import com.oracle.graal.api.code.CompilationResult.Call;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
-import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.hotspot.stubs.*;
 
 /**
@@ -38,8 +38,8 @@
 
     public final String stubName;
 
-    public HotSpotCompiledRuntimeStub(Architecture arch, Stub stub, CompilationResult compResult) {
-        super(arch, compResult);
+    public HotSpotCompiledRuntimeStub(TargetDescription target, Stub stub, CompilationResult compResult) {
+        super(target, compResult);
         assert checkStubInvariants(compResult);
         this.stubName = stub.toString();
     }
@@ -50,11 +50,7 @@
     private boolean checkStubInvariants(CompilationResult compResult) {
         assert compResult.getExceptionHandlers().isEmpty();
         for (DataPatch data : compResult.getDataReferences()) {
-            Constant constant = data.getConstant();
-            if (constant != null) {
-                assert constant.getKind() != Kind.Object : this + " cannot have embedded object constant: " + constant;
-                assert constant.getPrimitiveAnnotation() == null : this + " cannot have embedded metadata: " + constant;
-            }
+            assert !(data.data instanceof PatchedData) : this + " cannot have embedded object or metadata constant: " + data.data;
         }
         for (Infopoint infopoint : compResult.getInfopoints()) {
             assert infopoint instanceof Call : this + " cannot have non-call infopoint: " + infopoint;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Mon Mar 17 12:40:35 2014 -0700
@@ -235,6 +235,9 @@
         if (HotSpotPrintInlining.getValue() == false) {
             HotSpotPrintInlining.setValue(config.printInlining);
         }
+        if (HotSpotCIPrintCompilerName.getValue() == false) {
+            HotSpotCIPrintCompilerName.setValue(config.printCompilerName);
+        }
 
         if (Boolean.valueOf(System.getProperty("graal.printconfig"))) {
             printConfig(config);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot;
+
+import java.io.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.nodes.type.*;
+
+public class HotSpotReferenceMap implements ReferenceMap, Serializable {
+
+    private static final long serialVersionUID = -1052183095979496819L;
+
+    /**
+     * Contains 2 bits per register.
+     * <ul>
+     * <li>bit0 = 0: contains no references</li>
+     * <li>bit0 = 1, bit1 = 0: contains a wide oop</li>
+     * <li>bit0 = 1, bit1 = 1: contains a narrow oop</li>
+     * </ul>
+     */
+    private final BitSet registerRefMap;
+
+    /**
+     * Contains 3 bits per stack slot.
+     * <ul>
+     * <li>bit0 = 0: contains no references</li>
+     * <li>bit0 = 1, bit1+2 = 0: contains a wide oop</li>
+     * <li>bit0 = 1, bit1 = 1: contains a narrow oop in the lower half</li>
+     * <li>bit0 = 1, bit2 = 1: contains a narrow oop in the upper half</li>
+     * </ul>
+     */
+    private final BitSet frameRefMap;
+
+    private final int frameSlotSize;
+
+    public HotSpotReferenceMap(int registerCount, int frameSlotCount, int frameSlotSize) {
+        if (registerCount > 0) {
+            this.registerRefMap = new BitSet(registerCount * 2);
+        } else {
+            this.registerRefMap = null;
+        }
+        this.frameRefMap = new BitSet(frameSlotCount * 3);
+        this.frameSlotSize = frameSlotSize;
+    }
+
+    public void setRegister(int idx, PlatformKind kind) {
+        if (kind == Kind.Object) {
+            registerRefMap.set(2 * idx);
+        } else if (kind == NarrowOopStamp.NarrowOop) {
+            registerRefMap.set(2 * idx);
+            registerRefMap.set(2 * idx + 1);
+        }
+    }
+
+    public void setStackSlot(int offset, PlatformKind kind) {
+        int idx = offset / frameSlotSize;
+        if (kind == Kind.Object) {
+            assert offset % frameSlotSize == 0;
+            frameRefMap.set(3 * idx);
+        } else if (kind == NarrowOopStamp.NarrowOop) {
+            frameRefMap.set(3 * idx);
+            if (offset % frameSlotSize == 0) {
+                frameRefMap.set(3 * idx + 1);
+            } else {
+                assert offset % frameSlotSize == frameSlotSize / 2;
+                frameRefMap.set(3 * idx + 2);
+            }
+        }
+    }
+
+    public boolean hasRegisterRefMap() {
+        return registerRefMap != null && registerRefMap.size() > 0;
+    }
+
+    public boolean hasFrameRefMap() {
+        return frameRefMap != null && frameRefMap.size() > 0;
+    }
+
+    public void appendRegisterMap(StringBuilder sb, RefMapFormatter formatter) {
+        for (int reg = registerRefMap.nextSetBit(0); reg >= 0; reg = registerRefMap.nextSetBit(reg + 2)) {
+            sb.append(' ').append(formatter.formatRegister(reg / 2));
+        }
+    }
+
+    public void appendFrameMap(StringBuilder sb, RefMapFormatter formatter) {
+        for (int slot = frameRefMap.nextSetBit(0); slot >= 0; slot = frameRefMap.nextSetBit(slot + 3)) {
+            sb.append(' ').append(formatter.formatStackSlot(slot / 3));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTargetDescription.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.nodes.type.*;
+
+public class HotSpotTargetDescription extends TargetDescription {
+
+    private final PlatformKind rawNarrowOopKind;
+
+    public HotSpotTargetDescription(Architecture arch, boolean isMP, int stackAlignment, int implicitNullCheckLimit, boolean inlineObjects, PlatformKind rawNarrowOopKind) {
+        super(arch, isMP, stackAlignment, implicitNullCheckLimit, inlineObjects);
+        this.rawNarrowOopKind = rawNarrowOopKind;
+    }
+
+    @Override
+    public int getSizeInBytes(PlatformKind kind) {
+        if (kind == NarrowOopStamp.NarrowOop) {
+            return super.getSizeInBytes(rawNarrowOopKind);
+        } else {
+            return super.getSizeInBytes(kind);
+        }
+    }
+
+    @Override
+    public ReferenceMap createReferenceMap(boolean hasRegisters, int stackSlotCount) {
+        return new HotSpotReferenceMap(hasRegisters ? arch.getRegisterReferenceMapBitCount() : 0, stackSlotCount, wordSize);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java	Mon Mar 17 12:40:35 2014 -0700
@@ -709,10 +709,12 @@
     @HotSpotVMFlag(name = "DontCompileHugeMethods") @Stable public boolean dontCompileHugeMethods;
     @HotSpotVMFlag(name = "HugeMethodLimit") @Stable public int hugeMethodLimit;
     @HotSpotVMFlag(name = "PrintCompilation") @Stable public boolean printCompilation;
+    @HotSpotVMFlag(name = "CIPrintCompilerName") @Stable public boolean printCompilerName;
     @HotSpotVMFlag(name = "PrintInlining") @Stable public boolean printInlining;
     @HotSpotVMFlag(name = "GraalUseFastLocking") @Stable public boolean useFastLocking;
     @HotSpotVMFlag(name = "ForceUnreachable") @Stable public boolean forceUnreachable;
     @HotSpotVMFlag(name = "GPUOffload") @Stable public boolean gpuOffload;
+    @HotSpotVMFlag(name = "TieredCompilation") @Stable public boolean tieredCompilation;
 
     @HotSpotVMFlag(name = "UseTLAB") @Stable public boolean useTLAB;
     @HotSpotVMFlag(name = "UseBiasedLocking") @Stable public boolean useBiasedLocking;
@@ -1189,6 +1191,7 @@
     @HotSpotVMField(name = "MethodData::_data_size", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataDataSize;
     @HotSpotVMField(name = "MethodData::_data[0]", type = "intptr_t", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopDataOffset;
     @HotSpotVMField(name = "MethodData::_trap_hist._array[0]", type = "u1", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataOopTrapHistoryOffset;
+    @HotSpotVMField(name = "MethodData::_graal_node_count", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int methodDataGraalNodeCountOffset;
 
     @HotSpotVMField(name = "nmethod::_verified_entry_point", type = "address", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodEntryOffset;
     @HotSpotVMField(name = "nmethod::_comp_level", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int nmethodCompLevelOffset;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVM.java	Mon Mar 17 12:40:35 2014 -0700
@@ -252,14 +252,6 @@
     boolean hasFinalizableSubclass(long metaspaceKlass);
 
     /**
-     * Gets the compiled code size for a method.
-     * 
-     * @param metaspaceMethod the metaspace Method object to query
-     * @return the compiled code size the method
-     */
-    int getCompiledCodeSize(long metaspaceMethod);
-
-    /**
      * Gets the metaspace Method object corresponding to a given {@link Class} object and slot
      * number.
      * 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/CompilerToVMImpl.java	Mon Mar 17 12:40:35 2014 -0700
@@ -111,9 +111,6 @@
     public native long getClassInitializer(long metaspaceKlass);
 
     @Override
-    public native int getCompiledCodeSize(long metaspaceMethod);
-
-    @Override
     public native long getMaxCallTargetOffset(long address);
 
     // The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import java.nio.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.CompilationResult.Data;
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.CompilationResult.Site;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.asm.*;
+
+/**
+ * Represents the data section of a method.
+ */
+public final class DataSection {
+
+    /**
+     * The minimum alignment required for this data section.
+     */
+    public final int sectionAlignment;
+
+    /**
+     * The raw data contained in the data section.
+     */
+    public final byte[] data;
+
+    /**
+     * A list of locations where oop pointers need to be patched by the runtime.
+     */
+    public final DataPatch[] patches;
+
+    public DataSection(TargetDescription target, Site[] sites) {
+        int size = 0;
+        int patchCount = 0;
+        List<DataPatch> externalDataList = new ArrayList<>();
+
+        // find all external data items and determine total size of data section
+        for (Site site : sites) {
+            if (site instanceof DataPatch) {
+                DataPatch dataPatch = (DataPatch) site;
+                Data d = dataPatch.data;
+                if (dataPatch.inline) {
+                    assert d instanceof PatchedData : "unnecessary data patch";
+                } else {
+                    size = NumUtil.roundUp(size, d.getAlignment());
+                    size += d.getSize(target);
+                    externalDataList.add(dataPatch);
+                    if (d instanceof PatchedData) {
+                        patchCount++;
+                    }
+                }
+            }
+        }
+
+        data = new byte[size];
+        patches = new DataPatch[patchCount];
+        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());
+        int index = 0;
+        int patchIndex = 0;
+        int alignment = 0;
+
+        // build data section
+        for (DataPatch dataPatch : externalDataList) {
+            assert !dataPatch.inline;
+            Data d = dataPatch.data;
+
+            alignment = Math.max(alignment, d.getAlignment());
+            index = NumUtil.roundUp(index, d.getAlignment());
+            buffer.position(index);
+
+            DataSectionReference reference = new DataSectionReference(index);
+            if (d instanceof PatchedData) {
+                // record patch location
+                patches[patchIndex++] = new DataPatch(index, d, true);
+            }
+            dataPatch.data = reference;
+
+            index += d.getSize(target);
+            d.emit(target, buffer);
+        }
+
+        this.sectionAlignment = alignment;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import java.nio.*;
+
+import com.oracle.graal.api.code.CompilationResult.Data;
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents a reference to the data section. Before the code is installed, all {@link Data} items
+ * referenced by a {@link DataPatch} are put into the data section of the method, and replaced by
+ * {@link DataSectionReference}.
+ */
+public class DataSectionReference extends Data {
+
+    public final int offset;
+
+    protected DataSectionReference(int offset) {
+        super(0);
+        this.offset = offset;
+    }
+
+    @Override
+    public int getSize(TargetDescription target) {
+        return 0;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.Illegal;
+    }
+
+    @Override
+    public void emit(TargetDescription target, ByteBuffer buffer) {
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import java.nio.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+
+/**
+ * A data item that represents a metaspace pointer.
+ */
+public class MetaspaceData extends PatchedData {
+
+    public final long value;
+    public final Object annotation;
+    public final boolean compressed;
+
+    public MetaspaceData(int alignment, long value, Object annotation, boolean compressed) {
+        super(alignment);
+        assert annotation != null;
+        this.value = value;
+        this.annotation = annotation;
+        this.compressed = compressed;
+    }
+
+    @Override
+    public int getSize(TargetDescription target) {
+        if (compressed) {
+            return target.getSizeInBytes(Kind.Int);
+        } else {
+            return target.getSizeInBytes(target.wordKind);
+        }
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.Long;
+    }
+
+    @Override
+    public void emit(TargetDescription target, ByteBuffer buffer) {
+        switch (getSize(target)) {
+            case 4:
+                buffer.putInt((int) value);
+                break;
+            case 8:
+                buffer.putLong(value);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("unexpected metaspace pointer size");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return (compressed ? "NarrowPointer[0x" + Integer.toHexString((int) value) : "Pointer[0x" + Long.toHexString(value)) + "]{" + annotation + "}";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import java.nio.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.nodes.type.*;
+
+/**
+ * A data item that represents an oop value.
+ */
+public class OopData extends PatchedData {
+
+    public final Object object;
+    public final boolean compressed;
+
+    public OopData(int alignment, Object object, boolean compressed) {
+        super(alignment);
+        this.object = object;
+        this.compressed = compressed;
+    }
+
+    @Override
+    public int getSize(TargetDescription target) {
+        if (compressed) {
+            return target.getSizeInBytes(NarrowOopStamp.NarrowOop);
+        } else {
+            return target.getSizeInBytes(Kind.Object);
+        }
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.Object;
+    }
+
+    @Override
+    public void emit(TargetDescription target, ByteBuffer buffer) {
+        switch (getSize(target)) {
+            case 4:
+                buffer.putInt(0xDEADDEAD);
+                break;
+            case 8:
+                buffer.putLong(0xDEADDEADDEADDEADL);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("unexpected oop size");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return (compressed ? "NarrowOop[" : "Oop[") + Kind.Object.format(object) + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import com.oracle.graal.api.code.CompilationResult.Data;
+
+/**
+ * Represents a data item that needs to be patched.
+ */
+public abstract class PatchedData extends Data {
+
+    protected PatchedData(int alignment) {
+        super(alignment);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Mar 17 12:40:35 2014 -0700
@@ -29,14 +29,17 @@
 import com.oracle.graal.api.code.CodeUtil.DefaultRefMapFormatter;
 import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
 import com.oracle.graal.api.code.CompilationResult.Call;
+import com.oracle.graal.api.code.CompilationResult.Data;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.code.CompilationResult.Mark;
+import com.oracle.graal.api.code.CompilationResult.PrimitiveData;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult;
+import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.printer.*;
 
@@ -82,7 +85,7 @@
                 }
             }
             for (DataPatch site : compResult.getDataReferences()) {
-                hcf.addOperandComment(site.pcOffset, "{" + site.getDataString() + "}");
+                hcf.addOperandComment(site.pcOffset, "{" + site.data.toString() + "}");
             }
             for (Mark mark : compResult.getMarks()) {
                 hcf.addComment(mark.pcOffset, getMarkName(mark));
@@ -173,7 +176,7 @@
             compResult.setId(method.allocateCompileId(compResult.getEntryBCI()));
         }
         HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), true);
-        runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target.arch, method, compResult), installedCode, method.getSpeculationLog());
+        runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, method, compResult), installedCode, method.getSpeculationLog());
         return logOrDump(installedCode, compResult);
     }
 
@@ -184,7 +187,7 @@
             compResult.setId(hotspotMethod.allocateCompileId(compResult.getEntryBCI()));
         }
         HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false);
-        CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target.arch, hotspotMethod, compResult), code, log);
+        CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, hotspotMethod, compResult), code, log);
         if (result != CodeInstallResult.OK) {
             return null;
         }
@@ -203,7 +206,7 @@
             compResult.setId(javaMethod.allocateCompileId(compResult.getEntryBCI()));
         }
         HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true);
-        HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(target.arch, javaMethod, compResult);
+        HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(target, javaMethod, compResult);
         CompilerToVM vm = runtime.getCompilerToVM();
         CodeInstallResult result = vm.installCode(compiled, code, null);
         if (result != CodeInstallResult.OK) {
@@ -216,6 +219,16 @@
         return constant.getPrimitiveAnnotation() != null;
     }
 
+    public Data createDataItem(Constant constant, int alignment) {
+        if (constant.getPrimitiveAnnotation() != null) {
+            return new MetaspaceData(alignment, constant.asLong(), constant.getPrimitiveAnnotation(), false);
+        } else if (constant.getKind().isObject()) {
+            return new OopData(alignment, constant.asObject(), false);
+        } else {
+            return new PrimitiveData(constant, alignment);
+        }
+    }
+
     @Override
     public TargetDescription getTarget() {
         return target;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java	Mon Mar 17 12:40:35 2014 -0700
@@ -700,9 +700,9 @@
 
     public int getScalingFactor(Kind kind) {
         if (useCompressedOops() && kind == Kind.Object) {
-            return this.runtime.getTarget().arch.getSizeInBytes(Kind.Int);
+            return this.runtime.getTarget().getSizeInBytes(Kind.Int);
         } else {
-            return this.runtime.getTarget().arch.getSizeInBytes(kind);
+            return this.runtime.getTarget().getSizeInBytes(kind);
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaAccessProvider.java	Mon Mar 17 12:40:35 2014 -0700
@@ -299,7 +299,7 @@
                     ResolvedJavaType elementType = lookupJavaType.getComponentType();
                     Kind elementKind = elementType.getKind();
                     final int headerSize = HotSpotGraalRuntime.getArrayBaseOffset(elementKind);
-                    int sizeOfElement = HotSpotGraalRuntime.runtime().getTarget().arch.getSizeInBytes(elementKind);
+                    int sizeOfElement = HotSpotGraalRuntime.runtime().getTarget().getSizeInBytes(elementKind);
                     int alignment = HotSpotGraalRuntime.runtime().getTarget().wordSize;
                     int log2ElementSize = CodeUtil.log2(sizeOfElement);
                     return NewObjectSnippets.computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMethodData.java	Mon Mar 17 12:40:35 2014 -0700
@@ -825,4 +825,12 @@
             super(runtime().getConfig().dataLayoutArgInfoDataTag, ARG_INFO_DATA_SIZE);
         }
     }
+
+    public void setCompiledGraphSize(int nodeCount) {
+        unsafe.putInt(metaspaceMethodData + config.methodDataGraalNodeCountOffset, nodeCount);
+    }
+
+    public int getCompiledGraphSize() {
+        return unsafe.getInt(metaspaceMethodData + config.methodDataGraalNodeCountOffset);
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotNmethod.java	Mon Mar 17 12:40:35 2014 -0700
@@ -43,7 +43,12 @@
 
     private static final long serialVersionUID = -1784683588947054103L;
 
+    /**
+     * This (indirect) Method* reference is safe since class redefinition preserves all methods
+     * associated with nmethods in the code cache.
+     */
     private final HotSpotResolvedJavaMethod method;
+
     private final boolean isDefault;
     private final boolean isExternal;
     private final String name;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotProfilingInfo.java	Mon Mar 17 12:40:35 2014 -0700
@@ -25,6 +25,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.nodes.*;
 
 public final class HotSpotProfilingInfo extends CompilerObject implements ProfilingInfo {
 
@@ -205,4 +206,21 @@
     public void setMature() {
         isMature = true;
     }
+
+    @Override
+    public boolean setCompilerIRSize(Class<?> irType, int size) {
+        if (irType == StructuredGraph.class) {
+            methodData.setCompiledGraphSize(size);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public int getCompilerIRSize(Class<?> irType) {
+        if (irType == StructuredGraph.class) {
+            return methodData.getCompiledGraphSize();
+        }
+        return -1;
+    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Mar 17 12:40:35 2014 -0700
@@ -28,8 +28,6 @@
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
-import java.util.*;
-import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -59,7 +57,6 @@
     private boolean forceInline;
     private boolean dontInline;
     private boolean ignoredBySecurityStackWalk;
-    private Map<Object, Object> compilerStorage;
     private HotSpotMethodData methodData;
     private byte[] code;
     private SpeculationLog speculationLog;
@@ -356,10 +353,6 @@
         return signature;
     }
 
-    public int getCompiledCodeSize() {
-        return runtime().getCompilerToVM().getCompiledCodeSize(metaspaceMethod);
-    }
-
     /**
      * Gets the value of {@code Method::_code}.
      * 
@@ -433,14 +426,6 @@
     }
 
     @Override
-    public Map<Object, Object> getCompilerStorage() {
-        if (compilerStorage == null) {
-            compilerStorage = new ConcurrentHashMap<>();
-        }
-        return compilerStorage;
-    }
-
-    @Override
     public ConstantPool getConstantPool() {
         return constantPool;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/type/NarrowOopStamp.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.nodes.type;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.type.*;
+
+public class NarrowOopStamp extends ObjectStamp {
+
+    public static final PlatformKind NarrowOop = new PlatformKind() {
+
+        public String name() {
+            return "NarrowOop";
+        }
+
+        @Override
+        public String toString() {
+            return name();
+        }
+    };
+
+    private final CompressEncoding encoding;
+
+    public NarrowOopStamp(ObjectStamp stamp, CompressEncoding encoding) {
+        this(stamp.type(), stamp.isExactType(), stamp.nonNull(), stamp.alwaysNull(), encoding);
+    }
+
+    public NarrowOopStamp(ResolvedJavaType type, boolean exactType, boolean nonNull, boolean alwaysNull, CompressEncoding encoding) {
+        super(type, exactType, nonNull, alwaysNull);
+        this.encoding = encoding;
+    }
+
+    public Stamp uncompressed() {
+        return new ObjectStamp(type(), isExactType(), nonNull(), alwaysNull());
+    }
+
+    public CompressEncoding getEncoding() {
+        return encoding;
+    }
+
+    @Override
+    public Stamp unrestricted() {
+        return new NarrowOopStamp((ObjectStamp) super.unrestricted(), encoding);
+    }
+
+    @Override
+    public Kind getStackKind() {
+        return Kind.Object;
+    }
+
+    @Override
+    public PlatformKind getPlatformKind(LIRTypeTool tool) {
+        return NarrowOop;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder();
+        str.append('n');
+        str.append(super.toString());
+        return str.toString();
+    }
+
+    @Override
+    public Stamp meet(Stamp otherStamp) {
+        if (this == otherStamp) {
+            return this;
+        }
+        if (otherStamp instanceof IllegalStamp) {
+            return otherStamp.meet(this);
+        }
+        if (!isCompatible(otherStamp)) {
+            return StampFactory.illegal(Kind.Illegal);
+        }
+        return new NarrowOopStamp((ObjectStamp) super.meet(otherStamp), encoding);
+    }
+
+    @Override
+    public Stamp join(Stamp otherStamp) {
+        if (this == otherStamp) {
+            return this;
+        }
+        if (otherStamp instanceof IllegalStamp) {
+            return otherStamp.join(this);
+        }
+        if (!isCompatible(otherStamp)) {
+            return StampFactory.illegal(Kind.Illegal);
+        }
+        return new NarrowOopStamp((ObjectStamp) super.join(otherStamp), encoding);
+    }
+
+    @Override
+    public boolean isCompatible(Stamp other) {
+        if (this == other) {
+            return true;
+        }
+        if (other instanceof NarrowOopStamp) {
+            NarrowOopStamp narrow = (NarrowOopStamp) other;
+            return encoding.equals(narrow.encoding);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        result = prime * result + encoding.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null || getClass() != obj.getClass()) {
+            return false;
+        }
+        NarrowOopStamp other = (NarrowOopStamp) obj;
+        if (!encoding.equals(other.encoding)) {
+            return false;
+        }
+        return super.equals(other);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java	Mon Mar 17 12:40:35 2014 -0700
@@ -73,11 +73,11 @@
             Node currentNode = iterator.next();
             assert !isSafepoint(currentNode) : "Write barrier must be present " + write;
             if (useG1GC()) {
-                if (!(currentNode instanceof G1PostWriteBarrier) || ((currentNode instanceof G1PostWriteBarrier) && !validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode))) {
+                if (!(currentNode instanceof G1PostWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode))) {
                     expandFrontier(frontier, currentNode);
                 }
             } else {
-                if (!(currentNode instanceof SerialWriteBarrier) || ((currentNode instanceof SerialWriteBarrier) && !validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode)) ||
+                if (!(currentNode instanceof SerialWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode)) ||
                                 ((currentNode instanceof SerialWriteBarrier) && !validateBarrier((FixedAccessNode) write, (WriteBarrier) currentNode))) {
                     expandFrontier(frontier, currentNode);
                 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Mar 17 12:40:35 2014 -0700
@@ -153,7 +153,7 @@
                 try (Scope s = Debug.scope("CodeInstall")) {
                     Stub stub = Stub.this;
                     HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub);
-                    HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(backend.getTarget().arch, stub, compResult);
+                    HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(backend.getTarget(), stub, compResult);
 
                     CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null);
                     if (result != CodeInstallResult.OK) {
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAIL.java	Mon Mar 17 12:40:35 2014 -0700
@@ -168,7 +168,7 @@
         Kind kind = arg.getKind();
         if (kind == Kind.Double || kind == Kind.Long) {
             regPrefix = "$d";
-        } else if (kind == Kind.Int || kind == Kind.Float || kind == Kind.NarrowOop) {
+        } else if (kind == Kind.Int || kind == Kind.Float) {
             regPrefix = "$s";
         } else {
             regPrefix = "$d";
@@ -193,7 +193,6 @@
                 case Int:
                 case Long:
                 case Object:
-                case NarrowOop:
                     return true;
             }
         } else if (category == FPU) {
--- a/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.hsail/src/com/oracle/graal/hsail/HSAILRegisterConfig.java	Mon Mar 17 12:40:35 2014 -0700
@@ -123,7 +123,7 @@
 
             if (locations[i] == null) {
                 locations[i] = StackSlot.get(kind.getStackKind(), currentStackOffset, !type.out);
-                currentStackOffset += Math.max(target.arch.getSizeInBytes(kind), target.wordSize);
+                currentStackOffset += Math.max(target.getSizeInBytes(kind), target.wordSize);
             }
         }
 
@@ -150,7 +150,6 @@
             case Short:
             case Byte:
             case Float:
-            case NarrowOop:
                 return regBitness32.clone();
             case Long:
             case Double:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/DecompilerTest.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,111 @@
+/*
+ * 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.java.decompiler.test;
+
+import java.lang.reflect.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.runtime.*;
+import com.oracle.graal.java.decompiler.test.example.*;
+import com.oracle.graal.printer.*;
+import com.oracle.graal.runtime.*;
+
+@Ignore
+public class DecompilerTest {
+
+    public static void doTest(String name) {
+        try {
+            DebugEnvironment.initialize(System.out);
+            MetaAccessProvider metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess();
+            Method method = Example.class.getDeclaredMethod(name, new Class[]{int.class, int.class});
+            final ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method);
+            TestUtil.compileMethod(javaMethod);
+        } catch (NoSuchMethodException e) {
+            Assert.fail();
+        } catch (SecurityException e) {
+            Assert.fail();
+        }
+    }
+
+    @Test
+    public void test01() {
+        doTest("loop7");
+    }
+
+    @Test
+    public void test02() {
+        doTest("loop6");
+    }
+
+    @Test
+    public void test03() {
+        doTest("loop5");
+    }
+
+    @Test
+    public void test04() {
+        doTest("loop4");
+    }
+
+    @Test
+    public void test05() {
+        doTest("loop3");
+    }
+
+    @Test
+    public void test06() {
+        doTest("loop2");
+    }
+
+    @Test
+    public void test07() {
+        doTest("loop");
+    }
+
+    @Test
+    public void test08() {
+        doTest("if0");
+    }
+
+    @Test
+    public void test09() {
+        doTest("if1");
+    }
+
+    @Test
+    public void test10() {
+        doTest("if2");
+    }
+
+    @Test
+    public void test11() {
+        doTest("if3");
+    }
+
+    @Test
+    public void test12() {
+        doTest("if4");
+    }
+}
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/Test.java	Mon Mar 17 12:39:25 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +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.java.decompiler.test;
-
-import java.lang.reflect.*;
-
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.runtime.*;
-import com.oracle.graal.java.decompiler.test.example.*;
-import com.oracle.graal.printer.*;
-import com.oracle.graal.runtime.*;
-
-public class Test {
-
-    /**
-     * @param args
-     * @throws SecurityException
-     * @throws NoSuchMethodException
-     */
-    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
-        DebugEnvironment.initialize(System.out);
-        MetaAccessProvider metaAccess = Graal.getRequiredCapability(RuntimeProvider.class).getHostBackend().getProviders().getMetaAccess();
-        Method method = Example.class.getDeclaredMethod("loop7", new Class[]{int.class, int.class});
-        final ResolvedJavaMethod javaMethod = metaAccess.lookupJavaMethod(method);
-        TestUtil.compileMethod(javaMethod);
-    }
-}
--- a/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.java.decompiler.test/src/com/oracle/graal/java/decompiler/test/TestUtil.java	Mon Mar 17 12:40:35 2014 -0700
@@ -24,6 +24,7 @@
 
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.compiler.GraalCompiler.*;
+
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CallingConvention.Type;
 import com.oracle.graal.api.meta.*;
--- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerIfSimplify.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/DecompilerIfSimplify.java	Mon Mar 17 12:40:35 2014 -0700
@@ -68,7 +68,7 @@
                         // TODO(mg)
                         // thenBlocks and elseBlocks can be both empty --> causes an AssertionError
                         DecompilerIfBlock ifBlock = new DecompilerIfBlock(block.getBlock(), decompiler, thenBlocks, elseBlocks, infoStream);
-                        if (thenBlocks.contains(block.getBlock()) || elseBlocks.contains(block.getBlock())) {
+                        if (thenBlocks.contains(block) || elseBlocks.contains(block)) {
                             throw new AssertionError();
                         }
                         blocks.add(ifBlock);
--- a/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/block/DecompilerIfBlock.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.java.decompiler/src/com/oracle/graal/java/decompiler/block/DecompilerIfBlock.java	Mon Mar 17 12:40:35 2014 -0700
@@ -158,7 +158,20 @@
 
     @Override
     public boolean contains(Block b) {
-        return b == block || thenBranch.contains(b) || elseBranch.contains(b);
+        if (b == block) {
+            return true;
+        }
+        for (DecompilerBlock i : thenBranch) {
+            if (i.block == b) {
+                return true;
+            }
+        }
+        for (DecompilerBlock i : elseBranch) {
+            if (i.block == b) {
+                return true;
+            }
+        }
+        return false;
     }
 
     @Override
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/FrameStateBuilder.java	Mon Mar 17 12:40:35 2014 -0700
@@ -205,7 +205,7 @@
                 return null;
             }
 
-            PhiNode phi = graph.addWithoutUnique(new PhiNode(currentValue.kind(), block));
+            PhiNode phi = graph.addWithoutUnique(new PhiNode(currentValue.stamp().unrestricted(), block));
             for (int i = 0; i < block.phiPredecessorCount(); i++) {
                 phi.addInput(currentValue);
             }
@@ -303,7 +303,7 @@
         }
         assert !block.isPhiAtMerge(value) : "phi function for this block already created";
 
-        PhiNode phi = graph.addWithoutUnique(new PhiNode(value.kind(), block));
+        PhiNode phi = graph.addWithoutUnique(new PhiNode(value.stamp().unrestricted(), block));
         phi.addInput(value);
         return phi;
     }
--- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java	Mon Mar 17 12:40:35 2014 -0700
@@ -237,13 +237,6 @@
                         throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to object ref");
                     }
                     break;
-                case NarrowOop:
-                    if (input.isNull()) {
-                        masm.emitStoreImmediate(kind, 0L, address.toAddress());
-                    } else {
-                        throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to object ref");
-                    }
-                    break;
                 default:
                     throw GraalInternalError.shouldNotReachHere();
             }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/FrameMap.java	Mon Mar 17 12:40:35 2014 -0700
@@ -170,7 +170,7 @@
             // Without this, frameNeedsAllocating() would never return true.
             int total = 0;
             for (StackSlot s : freedSlots) {
-                total += target.arch.getSizeInBytes(s.getKind());
+                total += target.getSizeInBytes(s.getKind());
             }
             if (total == spillSize - initialSpillSize) {
                 // reset spill area size
@@ -256,7 +256,7 @@
      * @return the size in bytes
      */
     protected int spillSlotSize(PlatformKind kind) {
-        return target.arch.getSizeInBytes(kind);
+        return target.getSizeInBytes(kind);
     }
 
     /**
@@ -347,8 +347,8 @@
         }
     }
 
-    public ReferenceMap initReferenceMap(boolean canHaveRegisters) {
-        ReferenceMap refMap = new ReferenceMap(canHaveRegisters ? target.arch.getRegisterReferenceMapBitCount() : 0, frameSize() / target.wordSize);
+    public ReferenceMap initReferenceMap(boolean hasRegisters) {
+        ReferenceMap refMap = target.createReferenceMap(hasRegisters, frameSize() / target.wordSize);
         for (StackSlot slot : objectStackSlots) {
             setReference(slot, refMap);
         }
@@ -364,22 +364,14 @@
      * @param refMap A reference map, as created by {@link #initReferenceMap(boolean)}.
      */
     public void setReference(Value location, ReferenceMap refMap) {
-        Kind kind = location.getKind();
-        if (kind == Kind.Object || kind == Kind.NarrowOop) {
-            if (isRegister(location)) {
-                refMap.setRegister(asRegister(location).number, kind == Kind.NarrowOop);
-            } else if (isStackSlot(location)) {
-                if (kind == Kind.NarrowOop) {
-                    int offset = offsetForStackSlot(asStackSlot(location));
-                    assert offset % target.wordSize == 0 || offset % target.wordSize == target.wordSize / 2;
-                    refMap.setStackSlot(offset / target.wordSize, offset % target.wordSize == 0, offset % target.wordSize != 0);
-                } else {
-                    int index = indexForStackSlot(asStackSlot(location));
-                    refMap.setStackSlot(index, false, false);
-                }
-            } else {
-                assert isConstant(location);
-            }
+        PlatformKind kind = location.getPlatformKind();
+        if (isRegister(location)) {
+            refMap.setRegister(asRegister(location).number, kind);
+        } else if (isStackSlot(location)) {
+            int offset = offsetForStackSlot(asStackSlot(location));
+            refMap.setStackSlot(offset, kind);
+        } else {
+            assert isConstant(location);
         }
     }
 }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Mon Mar 17 12:40:35 2014 -0700
@@ -27,7 +27,6 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.ConstantData;
 import com.oracle.graal.api.code.CompilationResult.Data;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
@@ -157,6 +156,10 @@
     }
 
     public void recordInlineDataInCode(Constant data) {
+        recordInlineDataInCode(codeCache.createDataItem(data, 0));
+    }
+
+    public void recordInlineDataInCode(Data data) {
         assert data != null;
         int pos = asm.position();
         Debug.log("Inline data in code: pos = %d, data = %s", pos, data);
@@ -165,7 +168,7 @@
 
     public AbstractAddress recordDataReferenceInCode(Constant data, int alignment) {
         assert data != null;
-        return recordDataReferenceInCode(new ConstantData(data, alignment));
+        return recordDataReferenceInCode(codeCache.createDataItem(data, alignment));
     }
 
     public AbstractAddress recordDataReferenceInCode(Data data) {
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragment.java	Mon Mar 17 12:40:35 2014 -0700
@@ -332,7 +332,7 @@
                     PhiNode phi;
                     switch (vpn.type()) {
                         case Value:
-                            phi = graph.addWithoutUnique(new PhiNode(vpn.kind(), merge));
+                            phi = graph.addWithoutUnique(new PhiNode(vpn.stamp(), merge));
                             break;
                         case Guard:
                             phi = graph.addWithoutUnique(new PhiNode(vpn.type(), merge));
--- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/LoopFragmentInside.java	Mon Mar 17 12:40:35 2014 -0700
@@ -170,7 +170,7 @@
         PhiNode ret;
         switch (phi.type()) {
             case Value:
-                ret = new PhiNode(phi.kind(), merge);
+                ret = new PhiNode(phi.stamp(), merge);
                 break;
             case Guard:
                 ret = new PhiNode(PhiType.Guard, merge);
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/PhiNode.java	Mon Mar 17 12:40:35 2014 -0700
@@ -22,7 +22,6 @@
  */
 package com.oracle.graal.nodes;
 
-import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.spi.*;
 import com.oracle.graal.nodes.calc.*;
@@ -53,15 +52,11 @@
     private final PhiType type;
 
     /**
-     * Create a value phi ({@link PhiType#Value}) with the specified kind.
+     * Create a value phi ({@link PhiType#Value}) with the specified stamp.
      * 
-     * @param kind the kind of the value
+     * @param stamp the stamp of the value
      * @param merge the merge that the new phi belongs to
      */
-    public PhiNode(Kind kind, MergeNode merge) {
-        this(StampFactory.forKind(kind), merge);
-    }
-
     public PhiNode(Stamp stamp, MergeNode merge) {
         super(stamp);
         assert stamp != StampFactory.forVoid();
@@ -186,7 +181,7 @@
 
     public void addInput(ValueNode x) {
         assert !(x instanceof PhiNode) || ((PhiNode) x).merge() instanceof LoopBeginNode || ((PhiNode) x).merge() != this.merge();
-        assert x.kind() == kind() || type != PhiType.Value;
+        assert x.stamp().isCompatible(stamp()) || type != PhiType.Value;
         values.add(x);
     }
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/type/IllegalStamp.java	Mon Mar 17 12:40:35 2014 -0700
@@ -85,8 +85,9 @@
         if (stamp instanceof IllegalStamp) {
             IllegalStamp other = (IllegalStamp) stamp;
             return kind == other.kind;
+        } else {
+            return stamp.isCompatible(this);
         }
-        return false;
     }
 
     @Override
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeoptimizationGroupingPhase.java	Mon Mar 17 12:40:35 2014 -0700
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.phases.*;
 import com.oracle.graal.phases.tiers.*;
 
@@ -55,8 +56,8 @@
                     if (target instanceof AbstractDeoptimizeNode) {
                         merge = graph.add(new MergeNode());
                         EndNode firstEnd = graph.add(new EndNode());
-                        reasonActionPhi = graph.addWithoutUnique(new PhiNode(Kind.Int, merge));
-                        speculationPhi = graph.addWithoutUnique(new PhiNode(Kind.Object, merge));
+                        reasonActionPhi = graph.addWithoutUnique(new PhiNode(StampFactory.forKind(Kind.Int), merge));
+                        speculationPhi = graph.addWithoutUnique(new PhiNode(StampFactory.forKind(Kind.Object), merge));
                         merge.addForwardEnd(firstEnd);
                         reasonActionPhi.addInput(((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess()));
                         speculationPhi.addInput(((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess()));
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java	Mon Mar 17 12:40:35 2014 -0700
@@ -91,14 +91,6 @@
         return inliningCount;
     }
 
-    public static void storeStatisticsAfterLowTier(StructuredGraph graph) {
-        ResolvedJavaMethod method = graph.method();
-        if (method != null) {
-            CompiledMethodInfo info = compiledMethodInfo(graph.method());
-            info.setLowLevelNodeCount(graph.getNodeCount());
-        }
-    }
-
     @Override
     protected void run(final StructuredGraph graph, final HighTierContext context) {
         final InliningData data = new InliningData(graph, context.getAssumptions());
@@ -310,15 +302,6 @@
         return newGraph;
     }
 
-    private static synchronized CompiledMethodInfo compiledMethodInfo(ResolvedJavaMethod m) {
-        CompiledMethodInfo info = (CompiledMethodInfo) m.getCompilerStorage().get(CompiledMethodInfo.class);
-        if (info == null) {
-            info = new CompiledMethodInfo();
-            m.getCompilerStorage().put(CompiledMethodInfo.class, info);
-        }
-        return info;
-    }
-
     private abstract static class AbstractInliningPolicy implements InliningPolicy {
 
         protected final Map<Invoke, Double> hints;
@@ -371,7 +354,12 @@
         protected static int previousLowLevelGraphSize(InlineInfo info) {
             int size = 0;
             for (int i = 0; i < info.numberOfMethods(); i++) {
-                size += compiledMethodInfo(info.methodAt(i)).lowLevelNodeCount();
+                ResolvedJavaMethod m = info.methodAt(i);
+                ProfilingInfo profile = m.getProfilingInfo();
+                int compiledGraphSize = profile.getCompilerIRSize(StructuredGraph.class);
+                if (compiledGraphSize > 0) {
+                    size += compiledGraphSize;
+                }
             }
             return size;
         }
@@ -864,21 +852,4 @@
             return (graph != null ? MetaUtil.format("%H.%n(%p)", method()) : "<null method>") + remainingInvokes;
         }
     }
-
-    private static class CompiledMethodInfo {
-
-        private int lowLevelNodes;
-
-        public CompiledMethodInfo() {
-        }
-
-        public int lowLevelNodeCount() {
-            return lowLevelNodes;
-        }
-
-        public void setLowLevelNodeCount(int lowLevelNodes) {
-            this.lowLevelNodes = lowLevelNodes;
-        }
-
-    }
 }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningUtil.java	Mon Mar 17 12:40:35 2014 -0700
@@ -625,7 +625,7 @@
 
             PhiNode returnValuePhi = null;
             if (invoke.asNode().kind() != Kind.Void) {
-                returnValuePhi = graph.addWithoutUnique(new PhiNode(invoke.asNode().kind(), returnMerge));
+                returnValuePhi = graph.addWithoutUnique(new PhiNode(invoke.asNode().stamp().unrestricted(), returnMerge));
             }
 
             MergeNode exceptionMerge = null;
@@ -638,7 +638,7 @@
 
                 FixedNode exceptionSux = exceptionEdge.next();
                 graph.addBeforeFixed(exceptionSux, exceptionMerge);
-                exceptionObjectPhi = graph.addWithoutUnique(new PhiNode(Kind.Object, exceptionMerge));
+                exceptionObjectPhi = graph.addWithoutUnique(new PhiNode(StampFactory.forKind(Kind.Object), exceptionMerge));
                 exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, Kind.Object, exceptionObjectPhi));
             }
 
@@ -1486,7 +1486,7 @@
 
             if (returnNode.result() != null) {
                 if (returnValuePhi == null) {
-                    returnValuePhi = merge.graph().addWithoutUnique(new PhiNode(returnNode.result().kind(), merge));
+                    returnValuePhi = merge.graph().addWithoutUnique(new PhiNode(returnNode.result().stamp().unrestricted(), merge));
                 }
                 returnValuePhi.addInput(returnNode.result());
             }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LoweringPhase.java	Mon Mar 17 12:40:35 2014 -0700
@@ -312,6 +312,8 @@
                     Mark preLoweringMark = node.graph().getMark();
                     ((Lowerable) node).lower(loweringTool);
                     if (loweringTool.guardAnchor.asNode().isDeleted()) {
+                        // TODO nextNode could be deleted but this is not currently supported
+                        assert nextNode.isAlive();
                         loweringTool.guardAnchor = BeginNode.prevBegin(nextNode);
                     }
                     assert checkPostNodeLowering(node, loweringTool, preLoweringMark, unscheduledUsages);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ReadEliminationPhase.java	Mon Mar 17 12:40:35 2014 -0700
@@ -87,7 +87,7 @@
         }
         if (lastLocationAccess instanceof PhiNode) {
             PhiNode phi = (PhiNode) lastLocationAccess;
-            PhiNode newPhi = phi.graph().addWithoutUnique(new PhiNode(n.kind(), phi.merge()));
+            PhiNode newPhi = phi.graph().addWithoutUnique(new PhiNode(n.stamp().unrestricted(), phi.merge()));
             nodeMap.set(phi, newPhi);
             for (ValueNode value : phi.values()) {
                 newPhi.addInput(getValue(n, (MemoryNode) value, nodeMap));
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/TailDuplicationPhase.java	Mon Mar 17 12:40:35 2014 -0700
@@ -486,7 +486,7 @@
                             // introduce a new phi
                             PhiNode newPhi = bottomPhis.get(node);
                             if (newPhi == null) {
-                                newPhi = graph.addWithoutUnique(new PhiNode(node.kind(), newBottomMerge));
+                                newPhi = graph.addWithoutUnique(new PhiNode(node.stamp().unrestricted(), newBottomMerge));
                                 bottomPhis.put(node, newPhi);
                                 newPhi.addInput(node);
                             }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Mon Mar 17 12:40:35 2014 -0700
@@ -177,6 +177,8 @@
     @Option(help = "")
     public static final OptionValue<Boolean> HotSpotPrintCompilation = new OptionValue<>(false);
     @Option(help = "")
+    public static final OptionValue<Boolean> HotSpotCIPrintCompilerName = new OptionValue<>(false);
+    @Option(help = "")
     public static final OptionValue<Boolean> HotSpotPrintInlining = new OptionValue<>(false);
 
     // Register allocator debugging
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/util/GraphOrder.java	Mon Mar 17 12:40:35 2014 -0700
@@ -85,7 +85,7 @@
 
     private static void visitForward(ArrayList<Node> nodes, NodeBitMap visited, Node node, boolean floatingOnly) {
         try {
-            assert node.isAlive() : node + " not alive";
+            assert node == null || node.isAlive() : node + " not alive";
             if (node != null && !visited.isMarked(node)) {
                 if (floatingOnly && node instanceof FixedNode) {
                     throw new GraalInternalError("unexpected reference to fixed node: %s (this indicates an unexpected cycle)", node);
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CompilationPrinter.java	Mon Mar 17 12:40:35 2014 -0700
@@ -134,16 +134,17 @@
      */
     protected String debugInfoToString(BytecodePosition codePos, ReferenceMap refMap, RegisterSaveLayout calleeSaveInfo, Architecture arch) {
         StringBuilder sb = new StringBuilder();
+        RefMapFormatter formatter = new CodeUtil.NumberedRefMapFormatter();
 
         if (refMap != null && refMap.hasRegisterRefMap()) {
             sb.append("reg-ref-map:");
-            refMap.appendRegisterMap(sb, arch != null ? new ArchitectureRegFormatter(arch) : null);
+            refMap.appendRegisterMap(sb, arch != null ? new ArchitectureRegFormatter(arch) : formatter);
             sb.append("\n");
         }
 
         if (refMap != null && refMap.hasFrameRefMap()) {
             sb.append("frame-ref-map:");
-            refMap.appendFrameMap(sb, null);
+            refMap.appendFrameMap(sb, formatter);
             sb.append("\n");
         }
 
--- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DecompilerDebugDumpHandler.java	Mon Mar 17 12:40:35 2014 -0700
@@ -35,6 +35,7 @@
 
 public class DecompilerDebugDumpHandler implements DebugDumpHandler {
 
+    public static boolean printToNowhere;
     private final PrintStream infoPrintStream = System.out;
     private File file;
     private FileOutputStream fos;
@@ -55,6 +56,15 @@
                 filter = filter.substring(0, filter.indexOf("Phase"));
             }
 
+            if (printToNowhere) {
+                printStream = new PrintStream(new OutputStream() {
+                    @Override
+                    public void write(int b) throws IOException {
+                        // DO NOTHING
+                    }
+                });
+            }
+
             if (printStream == null) {
                 fileName = "decompilerDump_" + uniqueId.incrementAndGet() + "_" + System.currentTimeMillis() + ".txt";
                 file = new File(fileName);
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Mon Mar 17 12:40:35 2014 -0700
@@ -1012,12 +1012,6 @@
             // Re-wire the control flow graph around the replacee
             FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
             replacee.replaceAtPredecessor(firstCFGNodeDuplicate);
-            FixedNode next = null;
-            if (replacee instanceof FixedWithNextNode) {
-                FixedWithNextNode fwn = (FixedWithNextNode) replacee;
-                next = fwn.next();
-                fwn.setNext(null);
-            }
 
             if (replacee instanceof StateSplit) {
                 for (StateSplit sideEffectNode : sideEffectNodes) {
@@ -1052,6 +1046,12 @@
                     replacer.replace(replacee, returnValue, mmap);
                 }
                 if (returnDuplicate.isAlive()) {
+                    FixedNode next = null;
+                    if (replacee instanceof FixedWithNextNode) {
+                        FixedWithNextNode fwn = (FixedWithNextNode) replacee;
+                        next = fwn.next();
+                        fwn.setNext(null);
+                    }
                     returnDuplicate.clearInputs();
                     returnDuplicate.replaceAndDelete(next);
                 }
--- a/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.sparc/src/com/oracle/graal/sparc/SPARC.java	Mon Mar 17 12:40:35 2014 -0700
@@ -162,7 +162,6 @@
                 case Int:
                 case Long:
                 case Object:
-                case NarrowOop:
                     return true;
             }
         } else if (category == FPU) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallNode.java	Mon Mar 17 12:40:35 2014 -0700
@@ -28,7 +28,7 @@
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
+import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter;
 
 /**
  * Call target that is optimized by Graal upon surpassing a specific invocation threshold.
@@ -85,6 +85,11 @@
         return new DefaultOptimizedCallNode(target);
     }
 
+    @Override
+    public boolean isInlinable() {
+        return true;
+    }
+
     private static final class DefaultOptimizedCallNode extends OptimizedCallNode {
 
         private boolean trySplit = true;
@@ -135,7 +140,7 @@
             if (isMaxSingleCall()) {
                 return true;
             }
-            return countPolymorphic() >= 1 || countGeneric() > 0;
+            return countPolymorphic() >= 1;
         }
 
         @Override
@@ -143,11 +148,6 @@
             trySplit = true;
         }
 
-        @Override
-        protected void notifyCallNodeAdded() {
-            trySplit = true;
-        }
-
         private boolean isMaxSingleCall() {
             final AtomicInteger count = new AtomicInteger(0);
             getCurrentCallTarget().getRootNode().accept(new NodeVisitor() {
@@ -163,11 +163,12 @@
         }
 
         private int countPolymorphic() {
-            return NodeUtil.countNodes(getCallTarget().getRootNode(), null, Kind.POLYMORPHIC, false);
-        }
-
-        private int countGeneric() {
-            return NodeUtil.countNodes(getCallTarget().getRootNode(), null, Kind.GENERIC, false);
+            return NodeUtil.countNodes(getCallTarget().getRootNode(), new NodeCountFilter() {
+                public boolean isCounted(Node node) {
+                    NodeCost cost = node.getCost();
+                    return cost == NodeCost.POLYMORPHIC || cost == NodeCost.MEGAMORPHIC;
+                }
+            });
         }
 
         @Override
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTarget.java	Mon Mar 17 12:40:35 2014 -0700
@@ -34,7 +34,7 @@
 import com.oracle.truffle.api.frame.*;
 import com.oracle.truffle.api.impl.*;
 import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
+import com.oracle.truffle.api.nodes.NodeUtil.NodeCountFilter;
 
 /**
  * Call target that is optimized by Graal upon surpassing a specific invocation threshold.
@@ -428,11 +428,11 @@
 
             target.getRootNode().accept(new NodeVisitor() {
                 public boolean visit(Node node) {
-                    Kind kind = node.getKind();
-                    if (kind == Kind.POLYMORPHIC || kind == Kind.GENERIC) {
+                    NodeCost kind = node.getCost();
+                    if (kind == NodeCost.POLYMORPHIC || kind == NodeCost.MEGAMORPHIC) {
                         Map<String, Object> props = new LinkedHashMap<>();
                         props.put("simpleName", node.getClass().getSimpleName());
-                        String msg = kind == Kind.GENERIC ? "generic" : "polymorphic";
+                        String msg = kind == NodeCost.MEGAMORPHIC ? "megamorphic" : "polymorphic";
                         log(0, msg, node.toString(), props);
                     }
                     if (node instanceof CallNode) {
@@ -461,8 +461,20 @@
     }
 
     static void addASTSizeProperty(RootNode target, Map<String, Object> properties) {
+        int polymorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() {
+            public boolean isCounted(Node node) {
+                return node.getCost() == NodeCost.POLYMORPHIC;
+            }
+        }, true);
+
+        int megamorphicCount = NodeUtil.countNodes(target.getRootNode(), new NodeCountFilter() {
+            public boolean isCounted(Node node) {
+                return node.getCost() == NodeCost.MEGAMORPHIC;
+            }
+        }, true);
+
         String value = String.format("%4d (%d/%d)", NodeUtil.countNodes(target.getRootNode(), null, true), //
-                        NodeUtil.countNodes(target.getRootNode(), null, Kind.POLYMORPHIC, true), NodeUtil.countNodes(target.getRootNode(), null, Kind.GENERIC, true)); //
+                        polymorphicCount, megamorphicCount); //
 
         properties.put("ASTSize", value);
     }
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PEReadEliminationClosure.java	Mon Mar 17 12:40:35 2014 -0700
@@ -162,7 +162,7 @@
                     }
                 }
                 if (phi) {
-                    PhiNode phiNode = getCachedPhi(entry, value.kind());
+                    PhiNode phiNode = getCachedPhi(entry, value.stamp().unrestricted());
                     mergeEffects.addFloatingNode(phiNode, "mergeReadCache");
                     for (int i = 0; i < states.size(); i++) {
                         afterMergeEffects.addPhiInput(phiNode, states.get(i).getReadCache(key.object, key.identity, PEReadEliminationClosure.this));
@@ -194,7 +194,7 @@
                 values[i] = value;
             }
 
-            PhiNode phiNode = getCachedPhi(new ReadCacheEntry(identity, phi), values[0].kind());
+            PhiNode phiNode = getCachedPhi(new ReadCacheEntry(identity, phi), values[0].stamp().unrestricted());
             mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi");
             for (int i = 0; i < values.length; i++) {
                 afterMergeEffects.addPhiInput(phiNode, values[i]);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapeClosure.java	Mon Mar 17 12:40:35 2014 -0700
@@ -35,6 +35,7 @@
 import com.oracle.graal.nodes.java.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.spi.Virtualizable.EscapeState;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.phases.util.*;
@@ -284,10 +285,10 @@
             super(mergeBlock);
         }
 
-        protected <T> PhiNode getCachedPhi(T virtual, Kind kind) {
+        protected <T> PhiNode getCachedPhi(T virtual, Stamp stamp) {
             PhiNode result = materializedPhis.get(virtual);
             if (result == null) {
-                result = new PhiNode(kind, merge);
+                result = new PhiNode(stamp, merge);
                 materializedPhis.put(virtual, result);
             }
             return result;
@@ -363,7 +364,7 @@
                         if (uniqueMaterializedValue != null) {
                             newState.addObject(object, new ObjectState(object, uniqueMaterializedValue, EscapeState.Materialized, null));
                         } else {
-                            PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object);
+                            PhiNode materializedValuePhi = getCachedPhi(object, StampFactory.forKind(Kind.Object));
                             mergeEffects.addFloatingNode(materializedValuePhi, "materializedPhi");
                             for (int i = 0; i < objStates.length; i++) {
                                 ObjectState obj = objStates[i];
@@ -458,7 +459,7 @@
                     for (int i = 1; i < objStates.length; i++) {
                         ValueNode[] fields = objStates[i].getEntries();
                         if (phis[valueIndex] == null && values[valueIndex] != fields[valueIndex]) {
-                            phis[valueIndex] = new PhiNode(values[valueIndex].kind(), merge);
+                            phis[valueIndex] = new PhiNode(values[valueIndex].stamp().unrestricted(), merge);
                         }
                     }
                     if (twoSlotKinds != null && twoSlotKinds[valueIndex] != null) {
@@ -487,7 +488,7 @@
                 return materialized;
             } else {
                 // not compatible: materialize in all predecessors
-                PhiNode materializedValuePhi = getCachedPhi(object, Kind.Object);
+                PhiNode materializedValuePhi = getCachedPhi(object, StampFactory.forKind(Kind.Object));
                 for (int i = 0; i < blockStates.size(); i++) {
                     ObjectState obj = objStates[i];
                     Block predecessor = mergeBlock.getPredecessors().get(i);
--- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java	Mon Mar 17 12:40:35 2014 -0700
@@ -33,6 +33,7 @@
 import com.oracle.graal.nodes.cfg.*;
 import com.oracle.graal.nodes.extended.*;
 import com.oracle.graal.nodes.java.*;
+import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
 import com.oracle.graal.phases.schedule.*;
 import com.oracle.graal.virtual.phases.ea.ReadEliminationBlockState.CacheEntry;
@@ -196,10 +197,10 @@
             super(mergeBlock);
         }
 
-        protected <T> PhiNode getCachedPhi(T virtual, Kind kind) {
+        protected <T> PhiNode getCachedPhi(T virtual, Stamp stamp) {
             PhiNode result = materializedPhis.get(virtual);
             if (result == null) {
-                result = new PhiNode(kind, merge);
+                result = new PhiNode(stamp, merge);
                 materializedPhis.put(virtual, result);
             }
             return result;
@@ -229,7 +230,7 @@
                     }
                 }
                 if (phi) {
-                    PhiNode phiNode = getCachedPhi(entry, value.kind());
+                    PhiNode phiNode = getCachedPhi(entry, value.stamp().unrestricted());
                     mergeEffects.addFloatingNode(phiNode, "mergeReadCache");
                     for (int i = 0; i < states.size(); i++) {
                         afterMergeEffects.addPhiInput(phiNode, states.get(i).getCacheEntry(key));
@@ -262,7 +263,7 @@
             }
 
             CacheEntry<?> newIdentifier = identifier.duplicateWithObject(phi);
-            PhiNode phiNode = getCachedPhi(newIdentifier, values[0].kind());
+            PhiNode phiNode = getCachedPhi(newIdentifier, values[0].stamp().unrestricted());
             mergeEffects.addFloatingNode(phiNode, "mergeReadCachePhi");
             for (int i = 0; i < values.length; i++) {
                 afterMergeEffects.addPhiInput(phiNode, values[i]);
--- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java	Mon Mar 17 12:40:35 2014 -0700
@@ -69,7 +69,7 @@
     @Override
     public void generate(LIRGeneratorTool generator) {
         assert kind() != input.kind();
-        assert generator.target().arch.getSizeInBytes(kind()) == generator.target().arch.getSizeInBytes(input.kind());
+        assert generator.target().getSizeInBytes(kind()) == generator.target().getSizeInBytes(input.kind());
 
         AllocatableValue result = generator.newVariable(kind());
         generator.emitMove(result, generator.operand(input));
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest.java	Mon Mar 17 12:40:35 2014 -0700
@@ -33,7 +33,6 @@
 import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
 import com.oracle.truffle.api.dsl.test.TypeSystemTest.ValueNode;
 import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
 
 public class PolymorphicTest {
 
@@ -55,7 +54,7 @@
         assertEquals("(boolean,boolean)", executeWith(node, false, false));
         assertEquals("(int,boolean)", executeWith(node, 42, false));
         assertEquals("(boolean,int)", executeWith(node, false, 42));
-        assertEquals(Kind.SPECIALIZED, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+        assertEquals(NodeCost.MONOMORPHIC, node.getNode().getCost());
         assertParent(node.getNode(), node.getNode().getLeft());
         assertParent(node.getNode(), node.getNode().getRight());
     }
@@ -65,7 +64,7 @@
         TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
         assertEquals("(int,boolean)", executeWith(node, 42, false));
         assertEquals("(int,int)", executeWith(node, 42, 42));
-        assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+        assertEquals(NodeCost.NONE, node.getNode().getCost());
         assertParent(node.getNode(), node.getNode().getLeft());
         assertParent(node.getNode(), node.getNode().getRight());
     }
@@ -76,7 +75,7 @@
         assertEquals("(int,boolean)", executeWith(node, 42, false));
         assertEquals("(boolean,boolean)", executeWith(node, true, false));
         assertEquals("(int,int)", executeWith(node, 42, 42));
-        assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+        assertEquals(NodeCost.NONE, node.getNode().getCost());
         assertParent(node.getNode(), node.getNode().getLeft());
         assertParent(node.getNode(), node.getNode().getRight());
     }
@@ -88,7 +87,7 @@
         assertEquals("(int,boolean)", executeWith(node, 42, false));
         assertEquals("(boolean,boolean)", executeWith(node, true, false));
         assertEquals("(int,int)", executeWith(node, 42, 42));
-        assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+        assertEquals(NodeCost.MEGAMORPHIC, node.getNode().getCost());
         assertParent(node.getNode(), node.getNode().getLeft());
         assertParent(node.getNode(), node.getNode().getRight());
     }
@@ -97,7 +96,7 @@
     public void testGenericInitial() {
         TestRootNode<Node1> node = TestHelper.createRoot(Node1Factory.getInstance());
         assertEquals("(generic,generic)", executeWith(node, "1", "1"));
-        assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+        assertEquals(NodeCost.MEGAMORPHIC, node.getNode().getCost());
         assertParent(node.getNode(), node.getNode().getLeft());
         assertParent(node.getNode(), node.getNode().getRight());
     }
@@ -108,7 +107,7 @@
         assertEquals("(boolean,int)", executeWith(node, false, 42));
         assertEquals("(boolean,boolean)", executeWith(node, false, false));
         assertEquals("(generic,generic)", executeWith(node, "", ""));
-        assertEquals(Kind.GENERIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+        assertEquals(NodeCost.MEGAMORPHIC, node.getNode().getCost());
         /* Assertions for bug GRAAL-425 */
         assertParent(node.getNode(), node.getNode().getLeft());
         assertParent(node.getNode(), node.getNode().getRight());
--- a/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api.dsl.test/src/com/oracle/truffle/api/dsl/test/PolymorphicTest2.java	Mon Mar 17 12:40:35 2014 -0700
@@ -32,7 +32,6 @@
 import com.oracle.truffle.api.dsl.test.PolymorphicTest2Factory.Node1Factory;
 import com.oracle.truffle.api.dsl.test.TypeSystemTest.TestRootNode;
 import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
 
 public class PolymorphicTest2 {
 
@@ -43,7 +42,7 @@
         assertEquals(21, executeWith(node, false, false));
         assertEquals(42, executeWith(node, 21, 21));
         assertEquals("(boolean,int)", executeWith(node, false, 42));
-        assertEquals(Kind.POLYMORPHIC, node.getNode().getClass().getAnnotation(NodeInfo.class).kind());
+        assertEquals(NodeCost.NONE, node.getNode().getCost());
     }
 
     @SuppressWarnings("unused")
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleOptions.java	Mon Mar 17 12:40:35 2014 -0700
@@ -25,7 +25,6 @@
 package com.oracle.truffle.api;
 
 import com.oracle.truffle.api.nodes.*;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
 
 /**
  * Class containing general Truffle options.
@@ -56,29 +55,29 @@
     public static String TraceRewritesFilterClass = System.getProperty("truffle.TraceRewritesFilterClass");
 
     /**
-     * Filters rewrites which does not contain the {@link Kind} in its source {@link NodeInfo}. If
-     * no {@link NodeInfo} is defined the element is filtered if the filter value is set.
+     * Filters rewrites which does not contain the {@link NodeCost} in its source {@link NodeInfo}.
+     * If no {@link NodeInfo} is defined the element is filtered if the filter value is set.
      * <p>
      * Can be set with
-     * {@code -Dtruffle.TraceRewritesFilterFromKind=UNINITIALIZED|SPECIALIZED|POLYMORPHIC|GENERIC}.
+     * {@code -Dtruffle.TraceRewritesFilterFromCost=NONE|MONOMORPHIC|POLYMORPHIC|MEGAMORPHIC}.
      */
-    public static NodeInfo.Kind TraceRewritesFilterFromKind = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterFromKind"));
+    public static NodeCost TraceRewritesFilterFromCost = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterFromCost"));
 
     /**
-     * Filters rewrites which does not contain the {@link Kind} in its target {@link NodeInfo}. If
-     * no {@link NodeInfo} is defined the element is filtered if the filter value is set.
+     * Filters rewrites which does not contain the {@link NodeCost} in its target {@link NodeInfo}.
+     * If no {@link NodeInfo} is defined the element is filtered if the filter value is set.
      * <p>
      * Can be set with
      * {@code -Dtruffle.TraceRewritesFilterToKind=UNINITIALIZED|SPECIALIZED|POLYMORPHIC|GENERIC}.
      */
-    public static NodeInfo.Kind TraceRewritesFilterToKind = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterToKind"));
+    public static NodeCost TraceRewritesFilterToCost = parseNodeInfoKind(System.getProperty("truffle.TraceRewritesFilterToCost"));
 
-    private static NodeInfo.Kind parseNodeInfoKind(String kind) {
+    private static NodeCost parseNodeInfoKind(String kind) {
         if (kind == null) {
             return null;
         }
 
-        return NodeInfo.Kind.valueOf(kind);
+        return NodeCost.valueOf(kind);
     }
 
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/DefaultCallNode.java	Mon Mar 17 12:40:35 2014 -0700
@@ -64,6 +64,11 @@
     }
 
     @Override
+    public boolean isInlinable() {
+        return false;
+    }
+
+    @Override
     public String toString() {
         return getParent() != null ? getParent().toString() : super.toString();
     }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/CallNode.java	Mon Mar 17 12:40:35 2014 -0700
@@ -28,13 +28,18 @@
 import com.oracle.truffle.api.frame.*;
 
 /**
- * This node represents a call to a static {@link CallTarget}. This node should be used whenever a
- * {@link CallTarget} is considered constant at a certain location in the tree. This enables the
- * Truffle runtime to perform inlining or other optimizations for this call-site. This class is
- * intended to be implemented by truffle runtime implementors and not by guest language
- * implementors.
+ * Represents a call to a {@link CallTarget} in the Truffle AST. Addtionally to calling the
+ * {@link CallTarget} this {@link Node} enables the runtime system to implement further
+ * optimizations. Optimizations that can possibly applied to a {@link CallNode} are inlining and
+ * splitting. Inlining inlines this call site into the call graph of the parent {@link CallTarget}.
+ * Splitting duplicates the {@link CallTarget} using {@link RootNode#split()} to collect call site
+ * sensitive profiling information.
  * 
- * @see #create(CallTarget) to create a CallNode instance.
+ * Please note: This class is not intended to be subclassed by guest language implementations.
+ * 
+ * @see TruffleRuntime#createCallNode(CallTarget)
+ * @see #inline()
+ * @see #split()
  */
 public abstract class CallNode extends Node {
 
@@ -45,7 +50,7 @@
     }
 
     /**
-     * Calls this constant target passing a caller frame and arguments.
+     * Calls the inner {@link CallTarget} returned by {@link #getCurrentCallTarget()}.
      * 
      * @param caller the caller frame
      * @param arguments the arguments that should be passed to the callee
@@ -65,27 +70,63 @@
     }
 
     /**
-     * @return true if this {@link CallNode} was already inlined.
+     * Returns <code>true</code> if the underlying runtime system supports inlining for the
+     * {@link CallTarget} in this {@link CallNode}.
+     * 
+     * @return true if inlining is supported.
+     */
+    public abstract boolean isInlinable();
+
+    /**
+     * Returns <code>true</code> if the {@link CallTarget} in this {@link CallNode} is inlined. A
+     * {@link CallNode} can either be inlined manually by invoking {@link #inline()} or by the
+     * runtime system which may at any point decide to inline.
+     * 
+     * @return true if this method was inlined else false.
      */
     public abstract boolean isInlined();
 
+    /**
+     * Enforces the runtime system to inline the {@link CallTarget} at this call site. If the
+     * runtime system does not support inlining or it is already inlined this method has no effect.
+     */
     public abstract void inline();
 
+    /**
+     * Returns <code>true</code> if this {@link CallNode} can be split. A {@link CallNode} can only
+     * be split if the runtime system supports splitting and if the {@link RootNode} contained the
+     * {@link CallTarget} returns <code>true</code> for {@link RootNode#isSplittable()}.
+     * 
+     * @return <code>true</code> if the target can be split
+     */
     public abstract boolean isSplittable();
 
+    /**
+     * Enforces the runtime system to split the {@link CallTarget}. If the {@link CallNode} is not
+     * splittable this methods has no effect.
+     */
     public abstract boolean split();
 
+    /**
+     * Returns <code>true</code> if the target of the {@link CallNode} was split.
+     * 
+     * @return if the target was split
+     */
     public final boolean isSplit() {
         return getSplitCallTarget() != null;
     }
 
+    /**
+     * Returns the splitted {@link CallTarget} if this method is split.
+     * 
+     * @return the split {@link CallTarget}
+     */
     public abstract CallTarget getSplitCallTarget();
 
     /**
      * Returns the used call target when {@link #call(PackedFrame, Arguments)} is invoked. If the
-     * {@link CallNode} was split this method returns the {@link CallTarget} returned by
-     * {@link #getSplitCallTarget()}. If not split this method returns the original supplied
-     * {@link CallTarget}.
+     * {@link CallTarget} was split this method returns the {@link CallTarget} returned by
+     * {@link #getSplitCallTarget()}.
      * 
      * @return the used {@link CallTarget} when node is called
      */
@@ -98,6 +139,22 @@
         }
     }
 
+    /**
+     * Returns the {@link RootNode} associated with {@link CallTarget} returned by
+     * {@link #getCurrentCallTarget()}. If the stored {@link CallTarget} does not contain a
+     * {@link RootNode} this method returns <code>null</code>.
+     * 
+     * @see #getCurrentCallTarget()
+     * @return the root node of the used call target
+     */
+    public final RootNode getCurrentRootNode() {
+        CallTarget target = getCurrentCallTarget();
+        if (target instanceof RootCallTarget) {
+            return ((RootCallTarget) target).getRootNode();
+        }
+        return null;
+    }
+
     @Override
     protected void onReplace(Node newNode, String reason) {
         super.onReplace(newNode, reason);
@@ -114,6 +171,9 @@
         registerCallTarget((CallNode) newNode);
     }
 
+    /**
+     * Internal API for the runtime system.
+     */
     protected static final void registerCallTarget(CallNode newNode) {
         RootNode newRoot = newNode.getCurrentRootNode();
         if (newRoot != null) {
@@ -121,51 +181,4 @@
         }
     }
 
-    protected void notifyCallNodeAdded() {
-
-    }
-
-    /**
-     * Returns the {@link RootNode} associated with {@link CallTarget} returned by
-     * {@link #getCurrentCallTarget()}.
-     * 
-     * @see #getCurrentCallTarget()
-     * @return the root node of the used call target
-     */
-    public final RootNode getCurrentRootNode() {
-        CallTarget target = getCurrentCallTarget();
-        if (target instanceof RootCallTarget) {
-            return ((RootCallTarget) target).getRootNode();
-        }
-        return null;
-    }
-
-    /**
-     * @deprecated always returns <code>true</code> now.
-     */
-    @Deprecated
-    public boolean isInlinable() {
-        return true;
-    }
-
-    /**
-     * @deprecated instead use {@link #getCurrentRootNode()} and check for {@link #isInlined()} for
-     *             true.
-     */
-    @Deprecated
-    public RootNode getInlinedRoot() {
-        if (!isInlined()) {
-            return null;
-        }
-        return getCurrentRootNode();
-    }
-
-    /**
-     * @deprecated use {@link TruffleRuntime#createCallNode(CallTarget)} instead
-     */
-    @Deprecated
-    public static CallNode create(CallTarget target) {
-        return Truffle.getRuntime().createCallNode(target);
-    }
-
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/GraphPrintVisitor.java	Mon Mar 17 12:40:35 2014 -0700
@@ -214,7 +214,7 @@
             setNodeProperty(node, "name", node.getClass().getSimpleName().replaceFirst("Node$", ""));
             NodeInfo nodeInfo = node.getClass().getAnnotation(NodeInfo.class);
             if (nodeInfo != null) {
-                setNodeProperty(node, "kind", nodeInfo.kind());
+                setNodeProperty(node, "cost", nodeInfo.cost());
                 if (!nodeInfo.shortName().isEmpty()) {
                     setNodeProperty(node, "shortName", nodeInfo.shortName());
                 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java	Mon Mar 17 12:40:35 2014 -0700
@@ -29,7 +29,6 @@
 import java.util.*;
 
 import com.oracle.truffle.api.*;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
 
 /**
  * Abstract base class for all Truffle nodes.
@@ -82,12 +81,20 @@
         this.sourceSection = section;
     }
 
-    public Kind getKind() {
+    /**
+     * Returns a rough estimate for the cost of this {@link Node}. This estimate can be used by
+     * runtime systems or guest languages to implement heuristics based on Truffle ASTs. This method
+     * is intended to be overridden by subclasses. The default implementation returns the value of
+     * {@link NodeInfo#cost()} of the {@link NodeInfo} annotation declared at the subclass. If no
+     * {@link NodeInfo} annotation is declared the method returns {@link NodeCost#MONOMORPHIC} as a
+     * default value.
+     */
+    public NodeCost getCost() {
         NodeInfo info = getClass().getAnnotation(NodeInfo.class);
         if (info != null) {
-            return info.kind();
+            return info.cost();
         }
-        return Kind.SPECIALIZED;
+        return NodeCost.MONOMORPHIC;
     }
 
     /**
@@ -277,61 +284,54 @@
     }
 
     private void traceRewrite(Node newNode, String reason) {
-        Class<? extends Node> from = getClass();
-        Class<? extends Node> to = newNode.getClass();
 
-        if (TruffleOptions.TraceRewritesFilterFromKind != null) {
-            if (filterByKind(from, TruffleOptions.TraceRewritesFilterFromKind)) {
+        if (TruffleOptions.TraceRewritesFilterFromCost != null) {
+            if (filterByKind(this, TruffleOptions.TraceRewritesFilterFromCost)) {
                 return;
             }
         }
 
-        if (TruffleOptions.TraceRewritesFilterToKind != null) {
-            if (filterByKind(to, TruffleOptions.TraceRewritesFilterToKind)) {
+        if (TruffleOptions.TraceRewritesFilterToCost != null) {
+            if (filterByKind(newNode, TruffleOptions.TraceRewritesFilterToCost)) {
                 return;
             }
         }
 
         String filter = TruffleOptions.TraceRewritesFilterClass;
+        Class<? extends Node> from = getClass();
+        Class<? extends Node> to = newNode.getClass();
         if (filter != null && (filterByContainsClassName(from, filter) || filterByContainsClassName(to, filter))) {
             return;
         }
 
         PrintStream out = System.out;
-        out.printf("[truffle]   rewrite %-50s |From %-40s |To %-40s |Reason %s.%n", this.toString(), formatNodeInfo(from), formatNodeInfo(to), reason);
+        out.printf("[truffle]   rewrite %-50s |From %-40s |To %-40s |Reason %s.%n", this.toString(), formatNodeInfo(this), formatNodeInfo(newNode), reason);
     }
 
-    private static String formatNodeInfo(Class<? extends Node> clazz) {
-        NodeInfo nodeInfo = clazz.getAnnotation(NodeInfo.class);
-        String kind = "?";
-        if (nodeInfo != null) {
-            switch (nodeInfo.kind()) {
-                case GENERIC:
-                    kind = "G";
-                    break;
-                case SPECIALIZED:
-                    kind = "S";
-                    break;
-                case UNINITIALIZED:
-                    kind = "U";
-                    break;
-                case POLYMORPHIC:
-                    kind = "P";
-                    break;
-                default:
-                    kind = "?";
-                    break;
-            }
+    private static String formatNodeInfo(Node node) {
+        String cost = "?";
+        switch (node.getCost()) {
+            case NONE:
+                cost = "G";
+                break;
+            case MONOMORPHIC:
+                cost = "M";
+                break;
+            case POLYMORPHIC:
+                cost = "P";
+                break;
+            case MEGAMORPHIC:
+                cost = "G";
+                break;
+            default:
+                cost = "?";
+                break;
         }
-        return kind + " " + clazz.getSimpleName();
+        return cost + " " + node.getClass().getSimpleName();
     }
 
-    private static boolean filterByKind(Class<?> clazz, Kind kind) {
-        NodeInfo info = clazz.getAnnotation(NodeInfo.class);
-        if (info != null) {
-            return info.kind() != kind;
-        }
-        return true;
+    private static boolean filterByKind(Node node, NodeCost cost) {
+        return node.getCost() == cost;
     }
 
     private static boolean filterByContainsClassName(Class<? extends Node> from, String filter) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeCost.java	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.truffle.api.nodes;
+
+import com.oracle.truffle.api.*;
+
+/**
+ * Represents a rough estimate for the cost of a {@link Node}. This estimate can be used by runtime
+ * systems or guest languages to implement heuristics based on Truffle ASTs.
+ * 
+ * @see Node#getCost()
+ */
+public enum NodeCost {
+
+    /**
+     * This node has literally no costs and should be ignored for heuristics. This is particularly
+     * useful for wrapper and profiling nodes which should not influence the heuristics.
+     */
+    NONE,
+
+    /**
+     * This node has a {@link CompilerDirectives#transferToInterpreter()} or
+     * {@link CompilerDirectives#transferToInterpreterAndInvalidate()} as its first unconditional
+     * statement.
+     */
+    UNINITIALIZED,
+
+    /**
+     * This node represents a specialized monomorphic version of an operation.
+     */
+    MONOMORPHIC,
+
+    /**
+     * This node represents a polymorphic version of an operation. For multiple chained polymorphic
+     * nodes the first may return {@link #MONOMORPHIC} and all addtional nodes should return
+     * {@link #POLYMORPHIC}.
+     */
+    POLYMORPHIC,
+
+    /**
+     * This node represents a megamorphic version of an operation. This value should only be used if
+     * the operation implementation supports monomorphism and polymorphism otherwise
+     * {@link #MONOMORPHIC} should be used instead.
+     */
+    MEGAMORPHIC;
+
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeInfo.java	Mon Mar 17 12:40:35 2014 -0700
@@ -40,10 +40,13 @@
      */
     String shortName() default "";
 
-    Kind kind() default Kind.SPECIALIZED;
-
-    public enum Kind {
-        UNINITIALIZED, SPECIALIZED, POLYMORPHIC, GENERIC
-    }
+    /**
+     * Provides a rough estimate for the cost of the annotated {@link Node}. This estimate can be
+     * used by runtime systems or guest languages to implement heuristics based on Truffle ASTs.
+     * 
+     * @see Node#getCost()
+     * @see NodeCost
+     */
+    NodeCost cost() default NodeCost.MONOMORPHIC;
 
 }
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/NodeUtil.java	Mon Mar 17 12:40:35 2014 -0700
@@ -34,7 +34,6 @@
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.nodes.Node.Child;
 import com.oracle.truffle.api.nodes.Node.Children;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
 
 /**
  * Utility class that manages the special access methods for node instances.
@@ -452,48 +451,6 @@
         return null;
     }
 
-    /**
-     * @deprecated will be removed, exposed Truffle runtime specific functionality.
-     */
-    @Deprecated
-    public static List<CallTarget> findOutermostCallTargets(Node node) {
-        RootNode root = node.getRootNode();
-        if (root == null) {
-            return Collections.emptyList();
-        }
-        List<CallTarget> roots = new ArrayList<>();
-        roots.add(root.getCallTarget());
-        for (CallNode callNode : root.getCachedCallNodes()) {
-            if (callNode.isInlined()) {
-                roots.addAll(findOutermostCallTargets(callNode));
-            }
-        }
-        return roots;
-    }
-
-    /**
-     * @deprecated will be removed, exposed Truffle runtime specific functionality.
-     */
-    @Deprecated
-    public static RootNode findOutermostRootNode(Node node) {
-        Node parent = node;
-        while (parent != null) {
-            if (parent instanceof RootNode) {
-                RootNode root = (RootNode) parent;
-                @SuppressWarnings("deprecation")
-                Node next = root.getParentInlinedCall();
-                if (next != null) {
-                    parent = next;
-                } else {
-                    return root;
-                }
-            } else {
-                parent = parent.getParent();
-            }
-        }
-        return null;
-    }
-
     public static <T> T findParent(Node start, Class<T> clazz) {
         Node parent = start.getParent();
         if (parent == null) {
@@ -614,39 +571,43 @@
     }
 
     public static int countNodes(Node root) {
-        return countNodes(root, null, null, false);
+        return countNodes(root, null, false);
     }
 
-    public static int countNodes(Node root, Class<?> clazz, Kind nodeKind, boolean countInlinedCallNodes) {
-        NodeCountVisitor nodeCount = new NodeCountVisitor(clazz, nodeKind, countInlinedCallNodes);
+    public static int countNodes(Node root, NodeCountFilter filter) {
+        return countNodes(root, filter, false);
+    }
+
+    public static int countNodes(Node root, NodeCountFilter filter, boolean visitInlinedCallNodes) {
+        NodeCountVisitor nodeCount = new NodeCountVisitor(filter, visitInlinedCallNodes);
         root.accept(nodeCount);
         return nodeCount.nodeCount;
     }
 
-    public static int countNodes(Node root, Class<?> clazz, boolean countInlinedCallNodes) {
-        return countNodes(root, clazz, null, countInlinedCallNodes);
+    public interface NodeCountFilter {
+
+        boolean isCounted(Node node);
+
     }
 
     private static final class NodeCountVisitor implements NodeVisitor {
 
-        private final boolean inspectInlinedCalls;
+        private final boolean visitInlinedCallNodes;
         int nodeCount;
-        private final Kind kind;
-        private final Class<?> clazz;
+        private final NodeCountFilter filter;
 
-        private NodeCountVisitor(Class<?> clazz, Kind kind, boolean inspectInlinedCalls) {
-            this.clazz = clazz;
-            this.kind = kind;
-            this.inspectInlinedCalls = inspectInlinedCalls;
+        private NodeCountVisitor(NodeCountFilter filter, boolean visitInlinedCallNodes) {
+            this.filter = filter;
+            this.visitInlinedCallNodes = visitInlinedCallNodes;
         }
 
         @Override
         public boolean visit(Node node) {
-            if ((clazz == null || clazz.isInstance(node)) && (kind == null || isKind(node))) {
+            if (filter == null || filter.isCounted(node)) {
                 nodeCount++;
             }
 
-            if (inspectInlinedCalls && node instanceof CallNode) {
+            if (visitInlinedCallNodes && node instanceof CallNode) {
                 CallNode call = (CallNode) node;
                 if (call.isInlined()) {
                     Node target = ((RootCallTarget) call.getCurrentCallTarget()).getRootNode();
@@ -659,9 +620,6 @@
             return true;
         }
 
-        private boolean isKind(Node n) {
-            return kind == n.getKind();
-        }
     }
 
     public static void printInliningTree(final PrintStream stream, RootNode root) {
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/RootNode.java	Mon Mar 17 12:40:35 2014 -0700
@@ -36,7 +36,7 @@
  */
 public abstract class RootNode extends Node {
 
-    private CallTarget callTarget;
+    private RootCallTarget callTarget;
     private final FrameDescriptor frameDescriptor;
 
     /*
@@ -62,36 +62,24 @@
     }
 
     /**
-     * @deprecated Not required anymore. Do not use.
+     * Creates a split {@link RootNode} based on the current {@link RootNode}. This method should
+     * return an AST that was never executed and must not be shared with other {@link RootNode} or
+     * {@link CallTarget} instances. This method is intended to be overridden by a subclass.
+     * 
+     * @return the split {@link RootNode}
      */
-    @Deprecated
-    public RootNode inline() {
-        if (!isInlinable()) {
-            throw new UnsupportedOperationException("Inlining is not enabled.");
-        }
-        return split();
+    public RootNode split() {
+        throw new UnsupportedOperationException();
     }
 
     /**
-     * @deprecated Not required anymore. Do not use.
-     */
-    @Deprecated
-    public int getInlineNodeCount() {
-        return 0;
-    }
-
-    /**
-     * @deprecated Not required anymore. Do not use.
+     * Returns <code>true</code> if this {@link RootNode} can be split. A {@link RootNode} can be
+     * split inside of a {@link CallTarget} that is invoked using a {@link CallNode}. If this method
+     * returns <code>true</code> a proper implementation of {@link #split()} must also be provided.
+     * This method is intended to be overridden by a subclass.
+     * 
+     * @return <code>true</code> if splittable else <code>false</code>.
      */
-    @Deprecated
-    public boolean isInlinable() {
-        return true;
-    }
-
-    public RootNode split() {
-        return NodeUtil.cloneNode(this);
-    }
-
     public boolean isSplittable() {
         return false;
     }
@@ -100,7 +88,7 @@
      * Reports the execution count of a loop that is a child of this node. The optimization
      * heuristics can use the loop count to guide compilation and inlining.
      */
-    public void reportLoopCount(int count) {
+    public final void reportLoopCount(int count) {
         if (getCallTarget() instanceof LoopCountReceiver) {
             ((LoopCountReceiver) getCallTarget()).reportLoopCount(count);
         }
@@ -114,7 +102,7 @@
      */
     public abstract Object execute(VirtualFrame frame);
 
-    public CallTarget getCallTarget() {
+    public final RootCallTarget getCallTarget() {
         return callTarget;
     }
 
@@ -122,17 +110,17 @@
         return frameDescriptor;
     }
 
-    public final void setCallTarget(CallTarget callTarget) {
+    public final void setCallTarget(RootCallTarget callTarget) {
         this.callTarget = callTarget;
     }
 
     /* Internal API. Do not use. */
-    void addCachedCallNode(CallNode callSite) {
+    final void addCachedCallNode(CallNode callSite) {
         this.cachedCallNodes.add(callSite);
     }
 
     /* Internal API. Do not use. */
-    void removeCachedCallNode(CallNode callSite) {
+    final void removeCachedCallNode(CallNode callSite) {
         this.cachedCallNodes.remove(callSite);
     }
 
@@ -148,11 +136,4 @@
         return Collections.unmodifiableSet(cachedCallNodes);
     }
 
-    /**
-     * @deprecated use {@link #getCachedCallNodes()} instead.
-     */
-    @Deprecated
-    public final CallNode getParentInlinedCall() {
-        return cachedCallNodes.isEmpty() ? null : cachedCallNodes.iterator().next();
-    }
 }
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/TruffleTypes.java	Mon Mar 17 12:40:35 2014 -0700
@@ -52,7 +52,7 @@
     private final DeclaredType childAnnotation;
     private final DeclaredType childrenAnnotation;
     private final DeclaredType nodeInfoAnnotation;
-    private final DeclaredType nodeInfoKind;
+    private final DeclaredType nodeCost;
     private final TypeMirror compilerDirectives;
     private final TypeMirror compilerAsserts;
     private final DeclaredType slowPath;
@@ -75,7 +75,7 @@
         assumption = getRequired(context, Assumption.class);
         invalidAssumption = getRequired(context, InvalidAssumptionException.class);
         nodeInfoAnnotation = getRequired(context, NodeInfo.class);
-        nodeInfoKind = getRequired(context, NodeInfo.Kind.class);
+        nodeCost = getRequired(context, NodeCost.class);
         slowPath = getRequired(context, SlowPath.class);
         sourceSection = getRequired(context, SourceSection.class);
         truffleOptions = getRequired(context, TruffleOptions.class);
@@ -107,8 +107,8 @@
         return false;
     }
 
-    public DeclaredType getNodeInfoKind() {
-        return nodeInfoKind;
+    public DeclaredType getNodeCost() {
+        return nodeCost;
     }
 
     private DeclaredType getRequired(ProcessorContext context, Class clazz) {
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/codewriter/AbstractCodeWriter.java	Mon Mar 17 12:40:35 2014 -0700
@@ -267,11 +267,9 @@
         if (parent.getKind() == ElementKind.ENUM && f.getModifiers().contains(Modifier.STATIC)) {
             write(f.getSimpleName());
             if (init != null) {
-                if (init != null) {
-                    write("(");
-                    init.acceptCodeElementScanner(this, p);
-                    write(")");
-                }
+                write("(");
+                init.acceptCodeElementScanner(this, p);
+                write(")");
             }
         } else {
             Element enclosing = f.getEnclosingElement();
--- a/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Mon Mar 17 12:39:25 2014 -0700
+++ b/graal/com.oracle.truffle.dsl.processor/src/com/oracle/truffle/dsl/processor/node/NodeCodeGenerator.java	Mon Mar 17 12:40:35 2014 -0700
@@ -32,7 +32,6 @@
 import javax.lang.model.util.*;
 
 import com.oracle.truffle.api.dsl.*;
-import com.oracle.truffle.api.nodes.NodeInfo.Kind;
 import com.oracle.truffle.api.nodes.*;
 import com.oracle.truffle.dsl.processor.*;
 import com.oracle.truffle.dsl.processor.ast.*;
@@ -223,7 +222,6 @@
                         }
                     }
                     ActualParameter sourceParameter = sourceMethod.findParameter(parameter.getLocalName());
-                    assert parameter != null;
 
                     if (castedValues && sourceParameter != null) {
                         builder.string(valueName(sourceParameter, parameter));
@@ -954,28 +952,28 @@
                 clazz.add(createGenericExecute(node, rootGroup));
             }
 
-            clazz.add(createGetKind(node, null, Kind.SPECIALIZED));
+            clazz.add(createGetCost(node, null, NodeCost.MONOMORPHIC));
         }
 
         protected boolean needsInvokeCopyConstructorMethod() {
             return getModel().getNode().isPolymorphic();
         }
 
-        protected CodeExecutableElement createGetKind(NodeData node, SpecializationData specialization, Kind kind) {
-            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getNodeInfoKind(), "getKind");
-
-            TypeMirror nodeInfoKind = context.getTruffleTypes().getNodeInfoKind();
+        protected CodeExecutableElement createGetCost(NodeData node, SpecializationData specialization, NodeCost cost) {
+            CodeExecutableElement method = new CodeExecutableElement(modifiers(PUBLIC), context.getTruffleTypes().getNodeCost(), "getCost");
+
+            TypeMirror nodeInfoKind = context.getTruffleTypes().getNodeCost();
 
             CodeTreeBuilder builder = method.createBuilder();
             if (node.isPolymorphic() && specialization == null) {
                 // assume next0 exists
-                builder.startIf().string("next0 != null && next0.getKind() == ").staticReference(nodeInfoKind, "SPECIALIZED").end();
+                builder.startIf().string("next0 != null && next0.getCost() == ").staticReference(nodeInfoKind, "MONOMORPHIC").end();
                 builder.startBlock();
                 builder.startReturn().staticReference(nodeInfoKind, "POLYMORPHIC").end();
                 builder.end();
             }
 
-            builder.startReturn().staticReference(nodeInfoKind, kind.name()).end();
+            builder.startReturn().staticReference(nodeInfoKind, cost.name()).end();
             return method;
         }
 
@@ -2476,7 +2474,7 @@
             }
             CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodePolymorphicClassName(node), baseType, false);
 
-            clazz.getAnnotationMirrors().add(createNodeInfo(node, Kind.POLYMORPHIC));
+            clazz.getAnnotationMirrors().add(createNodeInfo(node, NodeCost.NONE));
 
             for (ActualParameter polymorphParameter : polymorph.getSignatureParameters()) {
                 if (!polymorphParameter.getTypeSystemType().isGeneric()) {
@@ -2523,7 +2521,7 @@
             }
 
             createCachedExecuteMethods(specialization);
-            clazz.add(createGetKind(specialization.getNode(), specialization, Kind.SPECIALIZED));
+            clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.NONE));
         }
 
         private ExecutableElement createUpdateType(ActualParameter parameter) {
@@ -2563,34 +2561,34 @@
             }
             CodeTypeElement clazz = createClass(node, modifiers(PRIVATE, STATIC, FINAL), nodeSpecializationClassName(specialization), baseType, false);
 
-            Kind kind;
+            NodeCost cost;
             if (specialization.isGeneric()) {
-                kind = Kind.GENERIC;
+                cost = NodeCost.MEGAMORPHIC;
             } else if (specialization.isUninitialized()) {
-                kind = Kind.UNINITIALIZED;
+                cost = NodeCost.UNINITIALIZED;
             } else if (specialization.isPolymorphic()) {
-                kind = Kind.POLYMORPHIC;
+                cost = NodeCost.NONE;
             } else if (specialization.isSpecialized()) {
-                kind = Kind.SPECIALIZED;
+                cost = NodeCost.MONOMORPHIC;
             } else {
                 throw new AssertionError();
             }
-            clazz.getAnnotationMirrors().add(createNodeInfo(node, kind));
+            clazz.getAnnotationMirrors().add(createNodeInfo(node, cost));
 
             return clazz;
         }
 
-        protected CodeAnnotationMirror createNodeInfo(NodeData node, Kind kind) {
+        protected CodeAnnotationMirror createNodeInfo(NodeData node, NodeCost cost) {
             String shortName = node.getShortName();
             CodeAnnotationMirror nodeInfoMirror = new CodeAnnotationMirror(getContext().getTruffleTypes().getNodeInfoAnnotation());
             if (shortName != null) {
                 nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("shortName"), new CodeAnnotationValue(shortName));
             }
 
-            DeclaredType nodeinfoKind = getContext().getTruffleTypes().getNodeInfoKind();
-            VariableElement varKind = Utils.findVariableElement(nodeinfoKind, kind.name());
-
-            nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("kind"), new CodeAnnotationValue(varKind));
+            DeclaredType nodeinfoCost = getContext().getTruffleTypes().getNodeCost();
+            VariableElement varKind = Utils.findVariableElement(nodeinfoCost, cost.name());
+
+            nodeInfoMirror.setElementValue(nodeInfoMirror.findExecutableElement("cost"), new CodeAnnotationValue(varKind));
             return nodeInfoMirror;
         }
 
@@ -2609,9 +2607,9 @@
             }
 
             if (specialization.isGeneric()) {
-                clazz.add(createGetKind(specialization.getNode(), specialization, Kind.GENERIC));
+                clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.MEGAMORPHIC));
             } else if (specialization.isUninitialized()) {
-                clazz.add(createGetKind(specialization.getNode(), specialization, Kind.UNINITIALIZED));
+                clazz.add(createGetCost(specialization.getNode(), specialization, NodeCost.UNINITIALIZED));
             }
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/findbugsExcludeFilter.xml	Mon Mar 17 12:40:35 2014 -0700
@@ -0,0 +1,41 @@
+<FindBugsFilter>
+
+  <Match>
+    <Class name="com.oracle.graal.hotspot.CompilationTask" />
+    <Method name="run" />
+    <Bug pattern="NN_NAKED_NOTIFY" />
+  </Match>
+
+  <!-- justification = "concurrent abstraction calls are in synchronized block" -->
+  <Match>
+    <Class name="com.oracle.graal.hotspot.debug.BenchmarkCounters" />
+    <Method name="getIndex" />
+    <Bug pattern="AT_OPERATION_SEQUENCE_ON_CONCURRENT_ABSTRACTION" />
+  </Match>
+
+  <!-- justification = "counters are only used for statistics" -->
+  <Match>
+    <Class name="com.oracle.graal.hotspot.meta.HotSpotGraphCache" />
+    <Or>
+      <Method name="get" />
+      <Method name="put" />
+      <Method name="removeGraphs" />
+    </Or>
+    <Bug pattern="VO_VOLATILE_INCREMENT" />
+  </Match>
+
+  <!-- justification = "reference equality on the receiver is what we want" -->
+  <Match>
+    <Class name="com.oracle.graal.replacements.StringSubstitutions" />
+    <Method name="equals" />
+    <Bug pattern="ES_COMPARING_PARAMETER_STRING_WITH_EQ" />
+  </Match>
+
+  <!-- justification = "reference equality to test whether string is interned" -->
+  <Match>
+    <Class name="com.oracle.graal.hotspot.phases.AheadOfTimeVerificationPhase" />
+    <Method name="isInternedString" />
+    <Bug pattern="ES_COMPARING_STRINGS_WITH_EQ" />
+  </Match>
+
+</FindBugsFilter>
--- a/mx/mx_graal.py	Mon Mar 17 12:39:25 2014 -0700
+++ b/mx/mx_graal.py	Mon Mar 17 12:40:35 2014 -0700
@@ -1638,6 +1638,38 @@
     valueMap = parser.parse(output.getvalue())
     return valueMap
 
+def findbugs(args):
+    '''run FindBugs against non-test Java projects'''
+    findBugsHome = mx.get_env('FINDBUGS_HOME', None)
+    if findBugsHome:
+        findbugsJar = join(findBugsHome, 'lib', 'findbugs.jar')
+    else:
+        findbugsLib = join(_graal_home, 'lib', 'findbugs-3.0.0')
+        if not exists(findbugsLib):
+            tmp = tempfile.mkdtemp(prefix='findbugs-download-tmp', dir=_graal_home)
+            try:
+                findbugsDist = join(tmp, 'findbugs.zip')
+                mx.download(findbugsDist, ['http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0-dev-20131204-e3cbbd5.zip'])
+                with zipfile.ZipFile(findbugsDist) as zf:
+                    candidates = [e for e in zf.namelist() if e.endswith('/lib/findbugs.jar')]
+                    assert len(candidates) == 1, candidates
+                    libDirInZip = os.path.dirname(candidates[0])
+                    zf.extractall(tmp)
+                shutil.copytree(join(tmp, libDirInZip), findbugsLib)
+            finally:
+                shutil.rmtree(tmp)
+        findbugsJar = join(findbugsLib, 'findbugs.jar')
+    assert exists(findbugsJar)
+    nonTestProjects = [p for p in mx.projects() if not p.name.endswith('.test') and not p.name.endswith('.jtt')]
+    outputDirs = [p.output_dir() for p in nonTestProjects]
+    findbugsResults = join(_graal_home, 'findbugs.results')
+    exitcode = mx.run_java(['-jar', findbugsJar, '-textui', '-low', '-maxRank', '15', '-exclude', join(_graal_home, 'graal', 'findbugsExcludeFilter.xml'),
+                 '-auxclasspath', mx.classpath([p.name for p in nonTestProjects]), '-output', findbugsResults, '-progress', '-exitcode'] + args + outputDirs, nonZeroIsFatal=False)
+    if exitcode != 0:
+        with open(findbugsResults) as fp:
+            mx.log(fp.read())
+    os.unlink(findbugsResults)
+    return exitcode
 
 def mx_init(suite):
     commands = {
@@ -1646,6 +1678,7 @@
         'buildvms': [buildvms, '[-options]'],
         'c1visualizer' : [c1visualizer, ''],
         'clean': [clean, ''],
+        'findbugs': [findbugs, ''],
         'generateZshCompletion' : [generateZshCompletion, ''],
         'hsdis': [hsdis, '[att]'],
         'hcfdis': [hcfdis, ''],
--- a/mx/projects	Mon Mar 17 12:39:25 2014 -0700
+++ b/mx/projects	Mon Mar 17 12:40:35 2014 -0700
@@ -13,9 +13,6 @@
 library@CHECKSTYLE@path=lib/checkstyle-5.5-all.jar
 library@CHECKSTYLE@urls=jar:http://sourceforge.net/projects/checkstyle/files/checkstyle/5.5/checkstyle-5.5-bin.zip/download!/checkstyle-5.5/checkstyle-5.5-all.jar
 
-library@FINDBUGS@path=lib/findbugs-3.0.0-dev-20131204-e3cbbd5.jar
-library@FINDBUGS@urls=jar:http://sourceforge.net/projects/findbugs/files/findbugs/3.0.0/findbugs-3.0.0-dev-20131204-e3cbbd5.zip/download!/findbugs-3.0.0-dev-20131204-e3cbbd5/lib/findbugs.jar
-
 library@DACAPO@path=lib/dacapo-9.12-bach.jar
 library@DACAPO@urls=http://softlayer.dl.sourceforge.net/project/dacapobench/9.12-bach/dacapo-9.12-bach.jar
 
@@ -498,7 +495,7 @@
 # graal.java.decompiler.test
 project@com.oracle.graal.java.decompiler.test@subDir=graal
 project@com.oracle.graal.java.decompiler.test@sourceDirs=src
-project@com.oracle.graal.java.decompiler.test@dependencies=com.oracle.graal.printer,com.oracle.graal.runtime
+project@com.oracle.graal.java.decompiler.test@dependencies=JUNIT,com.oracle.graal.printer,com.oracle.graal.runtime
 project@com.oracle.graal.java.decompiler.test@checkstyle=com.oracle.graal.graph
 project@com.oracle.graal.java.decompiler.test@javaCompliance=1.7
 project@com.oracle.graal.java.decompiler.test@workingSets=Graal,Test
--- a/mxtool/mx.py	Mon Mar 17 12:39:25 2014 -0700
+++ b/mxtool/mx.py	Mon Mar 17 12:40:35 2014 -0700
@@ -1894,10 +1894,13 @@
         abort('Could not find Eclipse executable. Use -e option or ensure ECLIPSE_EXE environment variable is set.')
 
     # Maybe an Eclipse installation dir was specified - look for the executable in it
-    if join(args.eclipse_exe, exe_suffix('eclipse')):
+    if isdir(args.eclipse_exe):
         args.eclipse_exe = join(args.eclipse_exe, exe_suffix('eclipse'))
-
-    if not os.path.isfile(args.eclipse_exe) or not os.access(args.eclipse_exe, os.X_OK):
+        warn("The eclipse-exe was a directory, now using " + args.eclipse_exe)
+
+    if not os.path.isfile(args.eclipse_exe):
+        abort('File does not exist: ' + args.eclipse_exe)
+    if not os.access(args.eclipse_exe, os.X_OK):
         abort('Not an executable file: ' + args.eclipse_exe)
 
     eclipseinit([], buildProcessorJars=False)
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Mon Mar 17 12:40:35 2014 -0700
@@ -41,55 +41,32 @@
   }
 }
 
-inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) {
-  oop inlineData = CompilationResult_DataPatch::inlineData(site);
-  address pc = _instructions->start() + pc_offset;
+inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
+  if (OopData::compressed(obj)) {
+    fatal("unimplemented: narrow oop relocation");
+  } else {
+    address pc = _instructions->start() + pc_offset;
+    Handle obj = OopData::object(data);
+    jobject value = JNIHandles::make_local(obj());
 
-  if (inlineData != NULL) {
-    oop kind = Constant::kind(inlineData);
-    char typeChar = Kind::typeChar(kind);
+    NativeMovConstReg* move = nativeMovConstReg_at(pc);
+    move->set_data((intptr_t) value);
 
-    switch (typeChar) {
-      case 'z':
-      case 'b':
-      case 's':
-      case 'c':
-      case 'i':
-        fatal("int-sized values not expected in DataPatch");
-        break;
-      case 'f':
-      case 'j':
-      case 'd': {
-        NativeMovConstReg* move = nativeMovConstReg_at(pc);
-        uint64_t value = Constant::primitive(inlineData);
-        move->set_data(value);
-        break;
-      }
-      case 'a': {
-        NativeMovConstReg* move = nativeMovConstReg_at(pc);
-        Handle obj = Constant::object(inlineData);
-        jobject value = JNIHandles::make_local(obj());
-        move->set_data((intptr_t) value);
+    // We need two relocations:  one on the sethi and one on the add.
+    int oop_index = _oop_recorder->find_index(value);
+    RelocationHolder rspec = oop_Relocation::spec(oop_index);
+    _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec);
+    _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec);
+  }
+}
 
-        // We need two relocations:  one on the sethi and one on the add.
-        int oop_index = _oop_recorder->find_index(value);
-        RelocationHolder rspec = oop_Relocation::spec(oop_index);
-        _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec);
-        _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec);
-        break;
-      }
-      default:
-        fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
-        break;
-    }
-  } else {
-    oop dataRef = CompilationResult_DataPatch::externalData(site);
-    jint offset = HotSpotCompiledCode_HotSpotData::offset(dataRef);
+inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
+  address pc = _instructions->start() + pc_offset;
+  jint offset = DataSectionReference::offset(data);
 
-    NativeMovRegMem* load = nativeMovRegMem_at(pc);
-    int disp = _constants_size + pc_offset - offset - BytesPerInstWord;
-    load->set_offset(-disp);
-  }
+  NativeMovRegMem* load = nativeMovRegMem_at(pc);
+  int disp = _constants_size + pc_offset - offset - BytesPerInstWord;
+  load->set_offset(-disp);
 }
 
 inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Mon Mar 17 12:40:35 2014 -0700
@@ -59,68 +59,49 @@
   }
 }
 
-inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) {
-  oop inlineData = CompilationResult_DataPatch::inlineData(site);
+inline bool check_metaspace_data(address pc, oop data) {
+  jlong value = MetaspaceData::value(data);
+  address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
+  if (MetaspaceData::compressed(data)) {
+    assert(*((jint*) operand) == value, err_msg("wrong compressed metaspace pointer: %p != %p", *((jint*) operand), value));
+  } else {
+    assert(*((jlong*) operand) == value, err_msg("wrong metaspace pointer: %p != %p", *((jlong*) operand), value));
+  }
+  return true;
+}
+
+inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
   address pc = _instructions->start() + pc_offset;
 
-  if (inlineData != NULL) {
-    oop kind = Constant::kind(inlineData);
-    char typeChar = Kind::typeChar(kind);
-
-    switch (typeChar) {
-      case 'z':
-      case 'b':
-      case 's':
-      case 'c':
-      case 'i':
-        fatal("int-sized values not expected in DataPatch");
-        break;
-      case 'n': {
-        address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
-        Handle obj = Constant::object(inlineData);
+  Handle obj = OopData::object(data);
+  jobject value = JNIHandles::make_local(obj());
+  if (OopData::compressed(data)) {
+    address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
+    int oop_index = _oop_recorder->find_index(value);
+    _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand);
+    TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand);
+  } else {
+    address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
+    *((jobject*) operand) = value;
+    _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+    TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand);
+  }
+}
 
-        jobject value = JNIHandles::make_local(obj());
-        int oop_index = _oop_recorder->find_index(value);
-        _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand);
-        TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand);
-        break;
-      }
-      case 'f':
-      case 'j':
-      case 'd':
-      case '*': {
-        address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
-        *((jlong*) operand) = Constant::primitive(inlineData);
-        break;
-      }
-      case 'a': {
-        address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
-        Handle obj = Constant::object(inlineData);
+inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
+  address pc = _instructions->start() + pc_offset;
+  jint offset = DataSectionReference::offset(data);
 
-        jobject value = JNIHandles::make_local(obj());
-        *((jobject*) operand) = value;
-        _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
-        TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand);
-        break;
-      }
-      default:
-        fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
-        break;
-    }
-  } else {
-    oop dataRef = CompilationResult_DataPatch::externalData(site);
-    jint offset = HotSpotCompiledCode_HotSpotData::offset(dataRef);
-    address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
-    address next_instruction = Assembler::locate_next_instruction(pc);
-    address dest = _constants->start() + offset;
+  address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
+  address next_instruction = Assembler::locate_next_instruction(pc);
+  address dest = _constants->start() + offset;
 
-    long disp = dest - next_instruction;
-    assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
-    *((jint*) operand) = (jint) disp;
+  long disp = dest - next_instruction;
+  assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
+  *((jint*) operand) = (jint) disp;
 
-    _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
-    TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset);
-  }
+  _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
+  TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset);
 }
 
 inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/share/vm/classfile/systemDictionary.hpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Mar 17 12:40:35 2014 -0700
@@ -187,12 +187,15 @@
   do_klass(BitSet_klass,                          java_util_BitSet,                                             Opt) \
   /* graal.hotspot */                                                                                                \
   do_klass(HotSpotCompiledCode_klass,             com_oracle_graal_hotspot_HotSpotCompiledCode,                 Opt) \
-  do_klass(HotSpotCompiledCode_HotSpotData_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_HotSpotData,     Opt) \
-  do_klass(HotSpotCompiledCode_DataSection_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_DataSection,     Opt) \
   do_klass(HotSpotCompiledCode_Comment_klass,     com_oracle_graal_hotspot_HotSpotCompiledCode_Comment,         Opt) \
   do_klass(HotSpotCompiledNmethod_klass,          com_oracle_graal_hotspot_HotSpotCompiledNmethod,              Opt) \
   do_klass(HotSpotCompiledRuntimeStub_klass,      com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub,          Opt) \
   do_klass(HotSpotForeignCallLinkage_klass,       com_oracle_graal_hotspot_HotSpotForeignCallLinkage,           Opt) \
+  do_klass(HotSpotReferenceMap_klass,             com_oracle_graal_hotspot_HotSpotReferenceMap,                 Opt) \
+  do_klass(DataSection_klass,                     com_oracle_graal_hotspot_data_DataSection,                    Opt) \
+  do_klass(DataSectionReference_klass,            com_oracle_graal_hotspot_data_DataSectionReference,           Opt) \
+  do_klass(MetaspaceData_klass,                   com_oracle_graal_hotspot_data_MetaspaceData,                  Opt) \
+  do_klass(OopData_klass,                         com_oracle_graal_hotspot_data_OopData,                        Opt) \
   do_klass(HotSpotCodeInfo_klass,                 com_oracle_graal_hotspot_meta_HotSpotCodeInfo,                Opt) \
   do_klass(HotSpotInstalledCode_klass,            com_oracle_graal_hotspot_meta_HotSpotInstalledCode,           Opt) \
   do_klass(HotSpotNmethod_klass,                  com_oracle_graal_hotspot_meta_HotSpotNmethod,                 Opt) \
@@ -210,7 +213,6 @@
   do_klass(Assumptions_CallSiteTargetValue_klass, com_oracle_graal_api_code_Assumptions_CallSiteTargetValue,    Opt) \
   do_klass(BytecodePosition_klass,                com_oracle_graal_api_code_BytecodePosition,                   Opt) \
   do_klass(DebugInfo_klass,                       com_oracle_graal_api_code_DebugInfo,                          Opt) \
-  do_klass(ReferenceMap_klass,                    com_oracle_graal_api_code_ReferenceMap,                       Opt) \
   do_klass(RegisterSaveLayout_klass,              com_oracle_graal_api_code_RegisterSaveLayout,                 Opt) \
   do_klass(BytecodeFrame_klass,                   com_oracle_graal_api_code_BytecodeFrame,                      Opt) \
   do_klass(CompilationResult_klass,               com_oracle_graal_api_code_CompilationResult,                  Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Mar 17 12:40:35 2014 -0700
@@ -296,14 +296,17 @@
   template(com_oracle_graal_hotspot_HotSpotKlassOop,                 "com/oracle/graal/hotspot/HotSpotKlassOop")                      \
   template(com_oracle_graal_hotspot_HotSpotOptions,                  "com/oracle/graal/hotspot/HotSpotOptions")                       \
   template(com_oracle_graal_hotspot_HotSpotCompiledCode,             "com/oracle/graal/hotspot/HotSpotCompiledCode")                  \
-  template(com_oracle_graal_hotspot_HotSpotCompiledCode_HotSpotData, "com/oracle/graal/hotspot/HotSpotCompiledCode$HotSpotData")      \
-  template(com_oracle_graal_hotspot_HotSpotCompiledCode_DataSection, "com/oracle/graal/hotspot/HotSpotCompiledCode$DataSection")      \
   template(com_oracle_graal_hotspot_HotSpotCompiledCode_Comment,     "com/oracle/graal/hotspot/HotSpotCompiledCode$Comment")          \
   template(com_oracle_graal_hotspot_HotSpotCompiledNmethod,          "com/oracle/graal/hotspot/HotSpotCompiledNmethod")               \
   template(com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub,      "com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub")           \
   template(com_oracle_graal_hotspot_HotSpotForeignCallLinkage,       "com/oracle/graal/hotspot/HotSpotForeignCallLinkage")            \
+  template(com_oracle_graal_hotspot_HotSpotReferenceMap,             "com/oracle/graal/hotspot/HotSpotReferenceMap")                  \
   template(com_oracle_graal_hotspot_bridge_VMToCompiler,             "com/oracle/graal/hotspot/bridge/VMToCompiler")                  \
   template(com_oracle_graal_hotspot_bridge_CompilerToVMImpl,         "com/oracle/graal/hotspot/bridge/CompilerToVMImpl")              \
+  template(com_oracle_graal_hotspot_data_DataSection,                "com/oracle/graal/hotspot/data/DataSection")                     \
+  template(com_oracle_graal_hotspot_data_DataSectionReference,       "com/oracle/graal/hotspot/data/DataSectionReference")            \
+  template(com_oracle_graal_hotspot_data_MetaspaceData,              "com/oracle/graal/hotspot/data/MetaspaceData")                   \
+  template(com_oracle_graal_hotspot_data_OopData,                    "com/oracle/graal/hotspot/data/OopData")                         \
   template(com_oracle_graal_hotspot_meta_HotSpotCodeInfo,            "com/oracle/graal/hotspot/meta/HotSpotCodeInfo")                 \
   template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode,       "com/oracle/graal/hotspot/meta/HotSpotInstalledCode")            \
   template(com_oracle_graal_hotspot_meta_HotSpotNmethod,             "com/oracle/graal/hotspot/meta/HotSpotNmethod")                  \
@@ -340,7 +343,6 @@
   template(com_oracle_graal_api_code_BytecodeFrame,                  "com/oracle/graal/api/code/BytecodeFrame")                       \
   template(com_oracle_graal_api_code_BytecodePosition,               "com/oracle/graal/api/code/BytecodePosition")                    \
   template(com_oracle_graal_api_code_DebugInfo,                      "com/oracle/graal/api/code/DebugInfo")                           \
-  template(com_oracle_graal_api_code_ReferenceMap,                   "com/oracle/graal/api/code/ReferenceMap")                        \
   template(com_oracle_graal_api_code_Register,                       "com/oracle/graal/api/code/Register")                            \
   template(com_oracle_graal_api_code_RegisterValue,                  "com/oracle/graal/api/code/RegisterValue")                       \
   template(com_oracle_graal_api_code_StackSlot,                      "com/oracle/graal/api/code/StackSlot")                           \
--- a/src/share/vm/code/nmethod.cpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/code/nmethod.cpp	Mon Mar 17 12:40:35 2014 -0700
@@ -1025,6 +1025,7 @@
 void nmethod::print_on(outputStream* st, const char* msg) const {
   if (st != NULL) {
     ttyLocker ttyl;
+    if (CIPrintCompilerName) st->print("%s:", compiler()->name());
     if (WizardMode) {
       CompileTask::print_compilation(st, this, msg, /*short_form:*/ true);
       st->print_cr(" (" INTPTR_FORMAT ")", this);
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Mar 17 12:40:35 2014 -0700
@@ -91,8 +91,8 @@
 static OopMap* create_oop_map(jint total_frame_size, jint parameter_count, oop debug_info) {
   OopMap* map = new OopMap(total_frame_size, parameter_count);
   oop reference_map = DebugInfo::referenceMap(debug_info);
-  oop register_map = ReferenceMap::registerRefMap(reference_map);
-  oop frame_map = ReferenceMap::frameRefMap(reference_map);
+  oop register_map = HotSpotReferenceMap::registerRefMap(reference_map);
+  oop frame_map = HotSpotReferenceMap::frameRefMap(reference_map);
   oop callee_save_info = (oop) DebugInfo::calleeSaveInfo(debug_info);
 
   if (register_map != NULL) {
@@ -157,6 +157,27 @@
   return map;
 }
 
+static void record_metadata_reference(oop obj, jlong prim, bool compressed, OopRecorder* oop_recorder) {
+  if (obj->is_a(HotSpotResolvedObjectType::klass())) {
+    Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj));
+    if (compressed) {
+      assert(Klass::decode_klass((narrowKlass) prim) == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim));
+    } else {
+      assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim));
+    }
+    int index = oop_recorder->find_index(klass);
+    TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string());
+  } else if (obj->is_a(HotSpotResolvedJavaMethod::klass())) {
+    Method* method = (Method*) (address) HotSpotResolvedJavaMethod::metaspaceMethod(obj);
+    assert(!compressed, err_msg("unexpected compressed method pointer %s @ %p = %p", method->name()->as_C_string(), method, prim));
+    int index = oop_recorder->find_index(method);
+    TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string());
+  } else {
+    assert(java_lang_String::is_instance(obj),
+        err_msg("unexpected metadata reference (%s) for constant %ld (%p)", obj->klass()->name()->as_C_string(), prim, prim));
+  }
+}
+
 // Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectType.klass()).
 static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) {
   char kind = Kind::typeChar(Constant::kind(constant));
@@ -165,23 +186,15 @@
     oop obj = Constant::object(constant);
     jlong prim = Constant::primitive(constant);
     if (obj != NULL) {
-      if (obj->is_a(HotSpotResolvedObjectType::klass())) {
-        Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj));
-        assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim));
-        int index = oop_recorder->find_index(klass);
-        TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string());
-      } else if (obj->is_a(HotSpotResolvedJavaMethod::klass())) {
-        Method* method = (Method*) (address) HotSpotResolvedJavaMethod::metaspaceMethod(obj);
-        int index = oop_recorder->find_index(method);
-        TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string());
-      } else {
-        assert(java_lang_String::is_instance(obj),
-            err_msg("unexpected annotation type (%s) for constant %ld (%p) of kind %c", obj->klass()->name()->as_C_string(), prim, prim, kind));
-      }
+      record_metadata_reference(obj, prim, false, oop_recorder);
     }
   }
 }
 
+static void record_metadata_in_patch(oop data, OopRecorder* oop_recorder) {
+  record_metadata_reference(MetaspaceData::annotation(data), MetaspaceData::value(data), MetaspaceData::compressed(data), oop_recorder);
+}
+
 ScopeValue* CodeInstaller::get_scope_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) {
   second = NULL;
   if (value == Value::ILLEGAL()) {
@@ -445,8 +458,8 @@
 
   // Pre-calculate the constants section size.  This is required for PC-relative addressing.
   _dataSection = HotSpotCompiledCode::dataSection(compiled_code);
-  guarantee(HotSpotCompiledCode_DataSection::sectionAlignment(_dataSection) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
-  arrayOop data = (arrayOop) HotSpotCompiledCode_DataSection::data(_dataSection);
+  guarantee(DataSection::sectionAlignment(_dataSection) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
+  arrayOop data = (arrayOop) DataSection::data(_dataSection);
   _constants_size = data->length();
   if (_constants_size > 0) {
     _constants_size = align_size_up(_constants_size, _constants->alignment());
@@ -482,30 +495,24 @@
 
   // copy the constant data into the newly created CodeBuffer
   address end_data = _constants->start() + _constants_size;
-  arrayOop data = (arrayOop) HotSpotCompiledCode_DataSection::data(_dataSection);
+  arrayOop data = (arrayOop) DataSection::data(_dataSection);
   memcpy(_constants->start(), data->base(T_BYTE), data->length());
   _constants->set_end(end_data);
 
-  objArrayOop patches = (objArrayOop) HotSpotCompiledCode_DataSection::patches(_dataSection);
+  objArrayOop patches = (objArrayOop) DataSection::patches(_dataSection);
   for (int i = 0; i < patches->length(); i++) {
     oop patch = patches->obj_at(i);
-    oop constant = HotSpotCompiledCode_HotSpotData::constant(patch);
-    oop kind = Constant::kind(constant);
-    char typeChar = Kind::typeChar(kind);
-    switch (typeChar) {
-      case 'f':
-      case 'j':
-      case 'd':
-        record_metadata_in_constant(constant, _oop_recorder);
-        break;
-      case 'a':
-        Handle obj = Constant::object(constant);
-        jobject value = JNIHandles::make_local(obj());
-        int oop_index = _oop_recorder->find_index(value);
+    oop data = CompilationResult_DataPatch::data(patch);
+    if (data->is_a(MetaspaceData::klass())) {
+      record_metadata_in_patch(data, _oop_recorder);
+    } else if (data->is_a(OopData::klass())) {
+      Handle obj = OopData::object(data);
+      jobject value = JNIHandles::make_local(obj());
+      int oop_index = _oop_recorder->find_index(value);
 
-        address dest = _constants->start() + HotSpotCompiledCode_HotSpotData::offset(patch);
-        _constants->relocate(dest, oop_Relocation::spec(oop_index));
-        break;
+      address dest = _constants->start() + CompilationResult_Site::pcOffset(patch);
+      assert(!OopData::compressed(data), err_msg("unexpected compressed oop in data section"));
+      _constants->relocate(dest, oop_Relocation::spec(oop_index));
     }
   }
 
@@ -777,19 +784,16 @@
 }
 
 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
-  oop inlineData = CompilationResult_DataPatch::inlineData(site);
-  if (inlineData != NULL) {
-    oop kind = Constant::kind(inlineData);
-    char typeChar = Kind::typeChar(kind);
-    switch (typeChar) {
-      case 'f':
-      case 'j':
-      case 'd':
-        record_metadata_in_constant(inlineData, _oop_recorder);
-        break;
-    }
+  oop data = CompilationResult_DataPatch::data(site);
+  if (data->is_a(MetaspaceData::klass())) {
+    record_metadata_in_patch(data, _oop_recorder);
+  } else if (data->is_a(OopData::klass())) {
+    pd_patch_OopData(pc_offset, data);
+  } else if (data->is_a(DataSectionReference::klass())) {
+    pd_patch_DataSectionReference(pc_offset, data);
+  } else {
+    fatal("unknown data patch type");
   }
-  CodeInstaller::pd_site_DataPatch(pc_offset, site);
 }
 
 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Mon Mar 17 12:40:35 2014 -0700
@@ -77,7 +77,8 @@
   ExceptionHandlerTable     _exception_handler_table;
 
   jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method);
-  void pd_site_DataPatch(int pc_offset, oop site);
+  void pd_patch_OopData(int pc_offset, oop data);
+  void pd_patch_DataSectionReference(int pc_offset, oop data);
   void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst);
   void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination);
   void pd_relocate_JavaMethod(oop method, jint pc_offset);
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Mon Mar 17 12:40:35 2014 -0700
@@ -348,11 +348,6 @@
   return CompilerOracle::should_inline(method) || method->force_inline();
 C2V_END
 
-C2V_ENTRY(jint, getCompiledCodeSize, (JNIEnv *env, jobject, jlong metaspace_method))
-  nmethod* code = (asMethod(metaspace_method))->code();
-  return code == NULL ? 0 : code->insts_size();
-C2V_END
-
 C2V_VMENTRY(jlong, lookupType, (JNIEnv *env, jobject, jstring jname, jclass accessing_class, jboolean resolve))
   ResourceMark rm;
   Handle name = JNIHandles::resolve(jname);
@@ -814,7 +809,6 @@
   {CC"doNotInlineOrCompile",                         CC"("METASPACE_METHOD")V",                                        FN_PTR(doNotInlineOrCompile)},
   {CC"canInlineMethod",                              CC"("METASPACE_METHOD")Z",                                        FN_PTR(canInlineMethod)},
   {CC"shouldInlineMethod",                           CC"("METASPACE_METHOD")Z",                                        FN_PTR(shouldInlineMethod)},
-  {CC"getCompiledCodeSize",                          CC"("METASPACE_METHOD")I",                                        FN_PTR(getCompiledCodeSize)},
   {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)},
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Mar 17 12:40:35 2014 -0700
@@ -79,16 +79,7 @@
     oop_field(HotSpotCompiledCode, sites, "[Lcom/oracle/graal/api/code/CompilationResult$Site;")                                                               \
     oop_field(HotSpotCompiledCode, exceptionHandlers, "[Lcom/oracle/graal/api/code/CompilationResult$ExceptionHandler;")                                       \
     oop_field(HotSpotCompiledCode, comments, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$Comment;")                                                        \
-    oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/HotSpotCompiledCode$DataSection;")                                                  \
-  end_class                                                                                                                                                    \
-  start_class(HotSpotCompiledCode_HotSpotData)                                                                                                                 \
-    int_field(HotSpotCompiledCode_HotSpotData, offset)                                                                                                         \
-    oop_field(HotSpotCompiledCode_HotSpotData, constant, "Lcom/oracle/graal/api/meta/Constant;")                                                               \
-  end_class                                                                                                                                                    \
-  start_class(HotSpotCompiledCode_DataSection)                                                                                                                 \
-    int_field(HotSpotCompiledCode_DataSection, sectionAlignment)                                                                                               \
-    oop_field(HotSpotCompiledCode_DataSection, data, "[B")                                                                                                     \
-    oop_field(HotSpotCompiledCode_DataSection, patches, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$HotSpotData;")                                         \
+    oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/data/DataSection;")                                                                 \
   end_class                                                                                                                                                    \
   start_class(HotSpotCompiledCode_Comment)                                                                                                                     \
     oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;")                                                                                         \
@@ -97,7 +88,7 @@
   start_class(HotSpotCompiledNmethod)                                                                                                                          \
     oop_field(HotSpotCompiledNmethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;")                                                     \
     int_field(HotSpotCompiledNmethod, entryBCI)                                                                                                                \
-    int_field(HotSpotCompiledNmethod, id)                                                                                                                \
+    int_field(HotSpotCompiledNmethod, id)                                                                                                                      \
   end_class                                                                                                                                                    \
   start_class(HotSpotCompiledRuntimeStub)                                                                                                                      \
     oop_field(HotSpotCompiledRuntimeStub, stubName, "Ljava/lang/String;")                                                                                      \
@@ -105,6 +96,23 @@
   start_class(HotSpotForeignCallLinkage)                                                                                                                       \
     long_field(HotSpotForeignCallLinkage, address)                                                                                                             \
   end_class                                                                                                                                                    \
+  start_class(DataSection)                                                                                                                                     \
+    int_field(DataSection, sectionAlignment)                                                                                                                   \
+    oop_field(DataSection, data, "[B")                                                                                                                         \
+    oop_field(DataSection, patches, "[Lcom/oracle/graal/api/code/CompilationResult$DataPatch;")                                                                \
+  end_class                                                                                                                                                    \
+  start_class(DataSectionReference)                                                                                                                            \
+    int_field(DataSectionReference, offset)                                                                                                                    \
+  end_class                                                                                                                                                    \
+  start_class(MetaspaceData)                                                                                                                                   \
+    long_field(MetaspaceData, value)                                                                                                                           \
+    oop_field(MetaspaceData, annotation, "Ljava/lang/Object;")                                                                                                 \
+    boolean_field(MetaspaceData, compressed)                                                                                                                   \
+  end_class                                                                                                                                                    \
+  start_class(OopData)                                                                                                                                         \
+    oop_field(OopData, object, "Ljava/lang/Object;")                                                                                                           \
+    boolean_field(OopData, compressed)                                                                                                                         \
+  end_class                                                                                                                                                    \
   start_class(ExternalCompilationResult)                                                                                                                       \
     long_field(ExternalCompilationResult, entryPoint)                                                                                                          \
   end_class                                                                                                                                                    \
@@ -145,8 +153,7 @@
     oop_field(CompilationResult_Call, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;")                                                                      \
   end_class                                                                                                                                                    \
   start_class(CompilationResult_DataPatch)                                                                                                                     \
-    oop_field(CompilationResult_DataPatch, externalData, "Lcom/oracle/graal/api/code/CompilationResult$Data;")                                                 \
-    oop_field(CompilationResult_DataPatch, inlineData, "Lcom/oracle/graal/api/meta/Constant;")                                                                 \
+    oop_field(CompilationResult_DataPatch, data, "Lcom/oracle/graal/api/code/CompilationResult$Data;")                                                         \
   end_class                                                                                                                                                    \
   start_class(InfopointReason)                                                                                                                                 \
     static_oop_field(InfopointReason, UNKNOWN, "Lcom/oracle/graal/api/code/InfopointReason;")                                                                  \
@@ -172,9 +179,9 @@
     oop_field(DebugInfo, referenceMap, "Lcom/oracle/graal/api/code/ReferenceMap;")                                                                             \
     oop_field(DebugInfo, calleeSaveInfo, "Lcom/oracle/graal/api/code/RegisterSaveLayout;")                                                                     \
   end_class                                                                                                                                                    \
-  start_class(ReferenceMap)                                                                                                                                    \
-    oop_field(ReferenceMap, registerRefMap, "Ljava/util/BitSet;")                                                                                              \
-    oop_field(ReferenceMap, frameRefMap, "Ljava/util/BitSet;")                                                                                                 \
+  start_class(HotSpotReferenceMap)                                                                                                                             \
+    oop_field(HotSpotReferenceMap, registerRefMap, "Ljava/util/BitSet;")                                                                                       \
+    oop_field(HotSpotReferenceMap, frameRefMap, "Ljava/util/BitSet;")                                                                                          \
   end_class                                                                                                                                                    \
   start_class(RegisterSaveLayout)                                                                                                                              \
     oop_field(RegisterSaveLayout, registers, "[Lcom/oracle/graal/api/code/Register;")                                                                          \
--- a/src/share/vm/graal/vmStructs_graal.hpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/graal/vmStructs_graal.hpp	Mon Mar 17 12:40:35 2014 -0700
@@ -32,6 +32,7 @@
 #define VM_STRUCTS_GRAAL(nonstatic_field, static_field)                       \
   nonstatic_field(ThreadShadow, _pending_deoptimization, int)                 \
   nonstatic_field(ThreadShadow, _pending_failed_speculation, oop)             \
+  nonstatic_field(MethodData,   _graal_node_count, int)                       \
 
 #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type)                   \
 
--- a/src/share/vm/oops/methodData.cpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/oops/methodData.cpp	Mon Mar 17 12:40:35 2014 -0700
@@ -1216,6 +1216,9 @@
   _highest_comp_level = 0;
   _highest_osr_comp_level = 0;
   _would_profile = true;
+#ifdef GRAAL
+  _graal_node_count = 0;
+#endif
 
   // Initialize flags and trap history.
   _nof_decompiles = 0;
--- a/src/share/vm/oops/methodData.hpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/oops/methodData.hpp	Mon Mar 17 12:40:35 2014 -0700
@@ -2203,6 +2203,11 @@
   // Does this method contain anything worth profiling?
   bool              _would_profile;
 
+#ifdef GRAAL
+  // Support for HotSpotMethodData.setCompiledGraphSize(int)
+  int               _graal_node_count;
+#endif
+
   // Size of _data array in bytes.  (Excludes header and extra_data fields.)
   int _data_size;
 
--- a/src/share/vm/utilities/globalDefinitions.hpp	Mon Mar 17 12:39:25 2014 -0700
+++ b/src/share/vm/utilities/globalDefinitions.hpp	Mon Mar 17 12:40:35 2014 -0700
@@ -834,7 +834,7 @@
   CompLevel_full_profile      = 3,         // C1, invocation & backedge counters + mdo
   CompLevel_full_optimization = 4,         // C2, Shark or Graal
 
-#if defined(COMPILER2) || defined(SHARK) || defined(GRAAL)
+#if defined(COMPILER2) || defined(SHARK) || defined(COMPILERGRAAL)
   CompLevel_highest_tier      = CompLevel_full_optimization,  // pure C2 and tiered or Graal and tiered
 #elif defined(COMPILER1)
   CompLevel_highest_tier      = CompLevel_simple,             // pure C1 or Graal
@@ -844,7 +844,7 @@
 
 #if defined(TIERED)
   CompLevel_initial_compile   = CompLevel_full_profile        // tiered
-#elif defined(COMPILER1) || defined(GRAAL)
+#elif defined(COMPILER1) || defined(COMPILERGRAAL)
   CompLevel_initial_compile   = CompLevel_simple              // pure C1 or Graal
 #elif defined(COMPILER2) || defined(SHARK)
   CompLevel_initial_compile   = CompLevel_full_optimization   // pure C2