changeset 18176:c2270ad35f57

Better construction of data section and data patches.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 27 Oct 2014 14:07:49 +0100
parents cf09e921458f
children 89f97291c3a5
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DataSection.java graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/VMConstant.java graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp src/cpu/x86/vm/graalCodeInstaller_x86.cpp src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCodeInstaller.hpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 39 files changed, 622 insertions(+), 746 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Mon Oct 27 14:07:49 2014 +0100
@@ -22,8 +22,8 @@
  */
 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.code.DataSection.Data;
 import com.oracle.graal.api.meta.*;
 
 /**
@@ -87,7 +87,7 @@
     /**
      * Create a {@link Data} item for a {@link Constant}, that can be used in a {@link DataPatch}.
      */
-    Data createDataItem(Constant constant, int alignment);
+    Data createDataItem(Constant constant);
 
     /**
      * Gets a description of the target architecture.
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2013, 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
@@ -25,7 +25,6 @@
 import static java.util.Collections.*;
 
 import java.io.*;
-import java.nio.*;
 import java.util.*;
 
 import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
@@ -141,93 +140,28 @@
     /**
      * Represents some external data that is referenced by the code.
      */
-    public abstract static class Data {
-
-        private final int alignment;
-
-        protected Data(int alignment) {
-            this.alignment = alignment;
-        }
+    public abstract static class Reference implements Serializable {
 
-        public int getAlignment() {
-            return alignment;
-        }
-
-        public abstract int getSize(TargetDescription target);
-
-        public abstract Kind getKind();
-
-        public abstract void emit(TargetDescription target, ByteBuffer buffer);
+        private static final long serialVersionUID = 4841246083028477946L;
     }
 
-    public abstract static class ConstantData extends Data {
+    public static class ConstantReference extends Reference {
+
+        private static final long serialVersionUID = 5841121930949053612L;
 
-        private final Constant constant;
+        private final VMConstant constant;
 
-        protected ConstantData(Constant constant, int alignment) {
-            super(alignment);
+        public ConstantReference(VMConstant constant) {
             this.constant = constant;
         }
 
-        public Constant getConstant() {
+        public VMConstant getConstant() {
             return constant;
         }
-    }
-
-    /**
-     * 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 ConstantData {
-
-        public PrimitiveData(Constant constant, int alignment) {
-            super(constant, alignment);
-            assert constant.getKind().isPrimitive();
-        }
-
-        @Override
-        public int getSize(TargetDescription target) {
-            return getConstant().getKind().getByteCount();
-        }
-
-        @Override
-        public Kind getKind() {
-            return getConstant().getKind();
-        }
-
-        @Override
-        public void emit(TargetDescription target, ByteBuffer buffer) {
-            switch (getConstant().getKind()) {
-                case Boolean:
-                    buffer.put(getConstant().asBoolean() ? (byte) 1 : (byte) 0);
-                    break;
-                case Byte:
-                    buffer.put((byte) getConstant().asInt());
-                    break;
-                case Char:
-                    buffer.putChar((char) getConstant().asInt());
-                    break;
-                case Short:
-                    buffer.putShort((short) getConstant().asInt());
-                    break;
-                case Int:
-                    buffer.putInt(getConstant().asInt());
-                    break;
-                case Long:
-                    buffer.putLong(getConstant().asLong());
-                    break;
-                case Float:
-                    buffer.putFloat(getConstant().asFloat());
-                    break;
-                case Double:
-                    buffer.putDouble(getConstant().asDouble());
-                    break;
-            }
-        }
 
         @Override
         public String toString() {
-            return getConstant().toString();
+            return constant.toString();
         }
 
         @Override
@@ -240,8 +174,8 @@
             if (this == obj) {
                 return true;
             }
-            if (obj instanceof PrimitiveData) {
-                PrimitiveData other = (PrimitiveData) obj;
+            if (obj instanceof ConstantReference) {
+                ConstantReference other = (ConstantReference) obj;
                 return getConstant().equals(other.getConstant());
             } else {
                 return false;
@@ -249,80 +183,44 @@
         }
     }
 
-    public static final class RawData extends Data {
-
-        public final byte[] data;
+    public static class DataSectionReference extends Reference {
 
-        public RawData(byte[] data, int alignment) {
-            super(alignment);
-            this.data = data;
-        }
+        private static final long serialVersionUID = 9011681879878139182L;
 
-        @Override
-        public int getSize(TargetDescription target) {
-            return data.length;
-        }
+        private int offset;
 
-        @Override
-        public Kind getKind() {
-            return Kind.Illegal;
-        }
-
-        @Override
-        public void emit(TargetDescription target, ByteBuffer buffer) {
-            buffer.put(data);
+        public DataSectionReference() {
+            // will be set after the data section layout is fixed
+            offset = 0xDEADDEAD;
         }
 
-        @Override
-        public String toString() {
-            Formatter ret = new Formatter();
-            boolean first = true;
-            for (byte b : data) {
-                ret.format(first ? "%02X" : " %02X", b);
-                first = false;
-            }
-            return ret.toString();
+        public int getOffset() {
+            return offset;
         }
 
-        @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;
-            }
+        public void setOffset(int offset) {
+            this.offset = offset;
         }
     }
 
     /**
      * Represents a code site that references some data. The associated data can be either a
-     * reference to an external {@link Data} item in the data section, or it may be an inlined
+     * {@link DataSectionReference reference} to the data section, or it may be an inlined
      * {@link Constant} that needs to be patched.
      */
     public static final class DataPatch extends Site {
 
         private static final long serialVersionUID = 5771730331604867476L;
-        public Data data;
-        public boolean inline;
+        public Reference reference;
 
-        public DataPatch(int pcOffset, Data data, boolean inline) {
+        public DataPatch(int pcOffset, Reference reference) {
             super(pcOffset);
-            this.data = data;
-            this.inline = inline;
+            this.reference = reference;
         }
 
         @Override
         public String toString() {
-            return String.format("%d[<data patch referring to %s data %s>]", pcOffset, inline ? "inline" : "external", data.toString());
+            return String.format("%d[<data patch referring to %s>]", pcOffset, reference.toString());
         }
     }
 
@@ -453,8 +351,10 @@
     private int id = -1;
     private int entryBCI = -1;
 
+    private final DataSection dataSection = new DataSection();
+
     private final List<Infopoint> infopoints = new ArrayList<>();
-    private final List<DataPatch> dataReferences = new ArrayList<>();
+    private final List<DataPatch> dataPatches = new ArrayList<>();
     private final List<ExceptionHandler> exceptionHandlers = new ArrayList<>();
     private final List<Mark> marks = new ArrayList<>();
 
@@ -521,6 +421,10 @@
         return assumptions;
     }
 
+    public DataSection getDataSection() {
+        return dataSection;
+    }
+
     /**
      * The total frame size of the method in bytes. This includes the return address pushed onto the
      * stack, if any.
@@ -554,26 +458,16 @@
     }
 
     /**
-     * Records a reference to the data section in the code section (e.g. to load an integer or
-     * floating point constant).
+     * Records a data patch in the code section. The data patch can refer to something in the
+     * {@link DataSectionReference data section} or directly to an {@link ConstantReference inlined
+     * constant}.
      *
-     * @param codePos the position in the code where the data reference occurs
-     * @param data the data that is referenced
+     * @param codePos The position in the code that needs to be patched.
+     * @param ref The reference that should be inserted in the code.
      */
-    public void recordDataReference(int codePos, Data data) {
-        assert codePos >= 0 && data != null;
-        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 data the data that is referenced
-     */
-    public void recordInlineData(int codePos, Data data) {
-        assert codePos >= 0 && data != null;
-        dataReferences.add(new DataPatch(codePos, data, true));
+    public void recordDataPatch(int codePos, Reference ref) {
+        assert codePos >= 0 && ref != null;
+        dataPatches.add(new DataPatch(codePos, ref));
     }
 
     /**
@@ -755,11 +649,11 @@
     /**
      * @return the list of data references
      */
-    public List<DataPatch> getDataReferences() {
-        if (dataReferences.isEmpty()) {
+    public List<DataPatch> getDataPatches() {
+        if (dataPatches.isEmpty()) {
             return emptyList();
         }
-        return unmodifiableList(dataReferences);
+        return unmodifiableList(dataPatches);
     }
 
     /**
@@ -788,7 +682,7 @@
 
     public void reset() {
         infopoints.clear();
-        dataReferences.clear();
+        dataPatches.clear();
         exceptionHandlers.clear();
         marks.clear();
         if (annotations != null) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/DataSection.java	Mon Oct 27 14:07:49 2014 +0100
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.code;
+
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+import java.util.function.*;
+
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.CompilationResult.DataSectionReference;
+import com.oracle.graal.api.code.DataSection.Data;
+import com.oracle.graal.api.meta.*;
+
+public class DataSection implements Serializable, Iterable<Data> {
+
+    private static final long serialVersionUID = -1375715553825731716L;
+
+    @FunctionalInterface
+    public interface DataBuilder {
+
+        void emit(ByteBuffer buffer, Consumer<DataPatch> patch);
+
+        static DataBuilder raw(byte[] data) {
+            return (buffer, patch) -> buffer.put(data);
+        }
+
+        static DataBuilder primitive(PrimitiveConstant c) {
+            switch (c.getKind()) {
+                case Boolean:
+                    return (buffer, patch) -> buffer.put(c.asBoolean() ? (byte) 1 : (byte) 0);
+                case Byte:
+                    return (buffer, patch) -> buffer.put((byte) c.asInt());
+                case Char:
+                    return (buffer, patch) -> buffer.putChar((char) c.asInt());
+                case Short:
+                    return (buffer, patch) -> buffer.putShort((short) c.asInt());
+                case Int:
+                    return (buffer, patch) -> buffer.putInt(c.asInt());
+                case Long:
+                    return (buffer, patch) -> buffer.putLong(c.asLong());
+                case Float:
+                    return (buffer, patch) -> buffer.putFloat(c.asFloat());
+                case Double:
+                    return (buffer, patch) -> buffer.putDouble(c.asDouble());
+                default:
+                    throw new IllegalArgumentException();
+            }
+        }
+
+        static DataBuilder zero(int size) {
+            switch (size) {
+                case 1:
+                    return (buffer, patch) -> buffer.put((byte) 0);
+                case 2:
+                    return (buffer, patch) -> buffer.putShort((short) 0);
+                case 4:
+                    return (buffer, patch) -> buffer.putInt(0);
+                case 8:
+                    return (buffer, patch) -> buffer.putLong(0L);
+                default:
+                    return (buffer, patch) -> {
+                        int rest = size;
+                        while (rest > 8) {
+                            buffer.putLong(0L);
+                            rest -= 8;
+                        }
+                        while (rest > 0) {
+                            buffer.put((byte) 0);
+                            rest--;
+                        }
+                    };
+            }
+        }
+    }
+
+    public static class Data implements Serializable {
+
+        private static final long serialVersionUID = -719932751800916080L;
+
+        private int alignment;
+        private final int size;
+        private final DataBuilder builder;
+
+        private DataSectionReference ref;
+
+        public Data(int alignment, int size, DataBuilder builder) {
+            this.alignment = alignment;
+            this.size = size;
+            this.builder = builder;
+
+            // initialized in DataSection.insertData(Data)
+            ref = null;
+        }
+
+        public void updateAlignment(int newAlignment) {
+            if (newAlignment == alignment) {
+                return;
+            }
+            alignment = lcm(alignment, newAlignment);
+        }
+
+        public int getAlignment() {
+            return alignment;
+        }
+
+        public int getSize() {
+            return size;
+        }
+
+        public DataBuilder getBuilder() {
+            return builder;
+        }
+    }
+
+    private final ArrayList<Data> dataItems = new ArrayList<>();
+
+    private boolean finalLayout;
+    private int sectionAlignment;
+    private int sectionSize;
+
+    /**
+     * Insert a {@link Data} item into the data section. If the item is already in the data section,
+     * the same {@link DataSectionReference} is returned.
+     *
+     * @param data the {@link Data} item to be inserted
+     * @return a unique {@link DataSectionReference} identifying the {@link Data} item
+     */
+    public DataSectionReference insertData(Data data) {
+        assert !finalLayout;
+        if (data.ref == null) {
+            data.ref = new DataSectionReference();
+            dataItems.add(data);
+        }
+        return data.ref;
+    }
+
+    /**
+     * Compute the layout of the data section. This can be called only once, and after it has been
+     * called, the data section can no longer be modified.
+     */
+    public void finalizeLayout() {
+        assert !finalLayout;
+        finalLayout = true;
+
+        // simple heuristic: put items with larger alignment requirement first
+        dataItems.sort((a, b) -> a.alignment - b.alignment);
+
+        int position = 0;
+        for (Data d : dataItems) {
+            sectionAlignment = lcm(sectionAlignment, d.alignment);
+            position = align(position, d.alignment);
+
+            d.ref.setOffset(position);
+            position += d.size;
+        }
+
+        sectionSize = position;
+    }
+
+    /**
+     * Get the size of the data section. Can only be called after {@link #finalizeLayout}.
+     */
+    public int getSectionSize() {
+        assert finalLayout;
+        return sectionSize;
+    }
+
+    /**
+     * Get the minimum alignment requirement of the data section. Can only be called after
+     * {@link #finalizeLayout}.
+     */
+    public int getSectionAlignment() {
+        assert finalLayout;
+        return sectionAlignment;
+    }
+
+    /**
+     * Build the data section. Can only be called after {@link #finalizeLayout}.
+     *
+     * @param buffer The {@link ByteBuffer} where the data section should be built. The buffer must
+     *            hold at least {@link #getSectionSize()} bytes.
+     * @param patch A {@link Consumer} to receive {@link DataPatch data patches} for relocations in
+     *            the data section.
+     */
+    public void buildDataSection(ByteBuffer buffer, Consumer<DataPatch> patch) {
+        assert finalLayout;
+        for (Data d : dataItems) {
+            buffer.position(d.ref.getOffset());
+            d.builder.emit(buffer, patch);
+        }
+    }
+
+    public Data findData(DataSectionReference ref) {
+        for (Data d : dataItems) {
+            if (d.ref == ref) {
+                return d;
+            }
+        }
+        return null;
+    }
+
+    public Iterator<Data> iterator() {
+        return dataItems.iterator();
+    }
+
+    private static int lcm(int x, int y) {
+        if (x == 0) {
+            return y;
+        } else if (y == 0) {
+            return x;
+        }
+
+        int a = Math.max(x, y);
+        int b = Math.min(x, y);
+        while (b > 0) {
+            int tmp = a % b;
+            a = b;
+            b = tmp;
+        }
+
+        int gcd = a;
+        return x * y / gcd;
+    }
+
+    private static int align(int position, int alignment) {
+        return ((position + alignment - 1) / alignment) * alignment;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/VMConstant.java	Mon Oct 27 14:07:49 2014 +0100
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.meta;
+
+public interface VMConstant extends Constant {
+}
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,8 +29,9 @@
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.PrimitiveData;
-import com.oracle.graal.api.code.CompilationResult.RawData;
+import com.oracle.graal.api.code.CompilationResult.DataSectionReference;
+import com.oracle.graal.api.code.DataSection.Data;
+import com.oracle.graal.api.code.DataSection.DataBuilder;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.asm.test.*;
@@ -66,7 +67,9 @@
             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 PrimitiveData(Constant.forDouble(84.72), 8));
+                Data data = new Data(8, 8, DataBuilder.primitive((PrimitiveConstant) Constant.forDouble(84.72)));
+                DataSectionReference ref = compResult.getDataSection().insertData(data);
+                compResult.recordDataPatch(asm.position(), ref);
                 asm.movdbl(ret, asm.getPlaceholder());
                 asm.ret(0);
                 return asm.close(true);
@@ -86,7 +89,9 @@
 
                 byte[] rawBytes = new byte[8];
                 ByteBuffer.wrap(rawBytes).order(ByteOrder.nativeOrder()).putDouble(84.72);
-                compResult.recordDataReference(asm.position(), new RawData(rawBytes, 8));
+                Data data = new Data(8, 8, DataBuilder.raw(rawBytes));
+                DataSectionReference ref = compResult.getDataSection().insertData(data);
+                compResult.recordDataPatch(asm.position(), ref);
                 asm.movdbl(ret, asm.getPlaceholder());
                 asm.ret(0);
                 return asm.close(true);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, 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
@@ -31,6 +31,7 @@
 
 import com.oracle.graal.alloc.*;
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.code.CompilationResult.ConstantReference;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.api.meta.ProfilingInfo.TriState;
@@ -307,7 +308,7 @@
         }
 
         if (Debug.isMeterEnabled()) {
-            List<DataPatch> ldp = compilationResult.getDataReferences();
+            List<DataPatch> ldp = compilationResult.getDataPatches();
             Kind[] kindValues = Kind.values();
             DebugMetric[] dms = new DebugMetric[kindValues.length];
             for (int i = 0; i < dms.length; i++) {
@@ -315,7 +316,11 @@
             }
 
             for (DataPatch dp : ldp) {
-                dms[dp.data.getKind().ordinal()].add(1);
+                Kind kind = Kind.Illegal;
+                if (dp.reference instanceof ConstantReference) {
+                    kind = ((ConstantReference) dp.reference).getConstant().getKind();
+                }
+                dms[kind.ordinal()].add(1);
             }
 
             Debug.metric("CompilationResults").increment();
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotCompare.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.amd64.*;
 import com.oracle.graal.compiler.common.*;
-import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
@@ -58,21 +57,21 @@
             } else if (y instanceof HotSpotObjectConstant) {
                 if (HotSpotObjectConstant.isCompressed(y)) {
                     // compressed oop
-                    crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(y), true));
+                    crb.recordInlineDataInCode(y);
                     masm.cmpl(asRegister(x), 0xDEADDEAD);
                 } else {
                     // uncompressed oop
-                    AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(new OopData(8, HotSpotObjectConstant.asObject(y), false));
+                    AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(y, 8);
                     masm.cmpq(asRegister(x), patch);
                 }
             } else if (y instanceof HotSpotMetaspaceConstant) {
                 if (y.getKind() == Kind.Int) {
                     // compressed metaspace pointer
-                    crb.recordInlineDataInCode(new MetaspaceData(0, y.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(y), true));
+                    crb.recordInlineDataInCode(y);
                     masm.cmpl(asRegister(x), y.asInt());
                 } else {
                     // uncompressed metaspace pointer
-                    AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(new MetaspaceData(8, y.asLong(), HotSpotObjectConstant.asObject(y), false));
+                    AMD64Address patch = (AMD64Address) crb.recordDataReferenceInCode(y, 8);
                     masm.cmpq(asRegister(x), patch);
                 }
             } else {
@@ -99,7 +98,7 @@
             } else if (y instanceof HotSpotObjectConstant) {
                 if (HotSpotObjectConstant.isCompressed(y) && crb.target.inlineObjects) {
                     // compressed oop
-                    crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(y), true));
+                    crb.recordInlineDataInCode(y);
                     masm.cmpl(address.toAddress(), 0xDEADDEAD);
                 } else {
                     // uncompressed oop
@@ -108,11 +107,11 @@
             } else if (y instanceof HotSpotMetaspaceConstant) {
                 if (y.getKind() == Kind.Int) {
                     // compressed metaspace pointer
-                    crb.recordInlineDataInCode(new MetaspaceData(0, y.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(y), true));
+                    crb.recordInlineDataInCode(y);
                     masm.cmpl(address.toAddress(), y.asInt());
                 } else if (y.getKind() == Kind.Long && NumUtil.is32bit(y.asLong())) {
                     // uncompressed metaspace pointer
-                    crb.recordInlineDataInCode(new MetaspaceData(0, y.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(y), false));
+                    crb.recordInlineDataInCode(y);
                     masm.cmpq(address.toAddress(), (int) y.asLong());
                 } else {
                     throw GraalInternalError.shouldNotReachHere();
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Mon Oct 27 14:07:49 2014 +0100
@@ -426,7 +426,7 @@
         if (c.getKind() == Kind.Long) {
             int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL);
             if (c instanceof HotSpotMetaspaceConstant) {
-                return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c));
+                return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c), true);
             } else {
                 return Constant.forIntegerKind(Kind.Int, compressedValue);
             }
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,6 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
-import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.MoveOp;
@@ -64,9 +63,8 @@
                 }
             } else if (input instanceof HotSpotObjectConstant) {
                 boolean compressed = HotSpotObjectConstant.isCompressed(input);
-                OopData data = new OopData(compressed ? 4 : 8, HotSpotObjectConstant.asObject(input), compressed);
                 if (crb.target.inlineObjects) {
-                    crb.recordInlineDataInCode(data);
+                    crb.recordInlineDataInCode(input);
                     if (isRegister(result)) {
                         if (compressed) {
                             masm.movl(asRegister(result), 0xDEADDEAD);
@@ -83,7 +81,7 @@
                     }
                 } else {
                     if (isRegister(result)) {
-                        AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(data);
+                        AMD64Address address = (AMD64Address) crb.recordDataReferenceInCode(input, compressed ? 4 : 8);
                         if (compressed) {
                             masm.movl(asRegister(result), address);
                         } else {
@@ -96,8 +94,7 @@
             } else if (input instanceof HotSpotMetaspaceConstant) {
                 assert input.getKind() == Kind.Int || input.getKind() == Kind.Long;
                 boolean compressed = input.getKind() == Kind.Int;
-                MetaspaceData data = new MetaspaceData(compressed ? 4 : 8, input.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(input), compressed);
-                crb.recordInlineDataInCode(data);
+                crb.recordInlineDataInCode(input);
                 if (isRegister(result)) {
                     if (compressed) {
                         masm.movl(asRegister(result), input.asInt());
@@ -140,7 +137,7 @@
             } else if (input instanceof HotSpotObjectConstant) {
                 if (HotSpotObjectConstant.isCompressed(input) && crb.target.inlineObjects) {
                     // compressed oop
-                    crb.recordInlineDataInCode(new OopData(0, HotSpotObjectConstant.asObject(input), true));
+                    crb.recordInlineDataInCode(input);
                     masm.movl(address.toAddress(), 0xDEADDEAD);
                 } else {
                     // uncompressed oop
@@ -149,7 +146,7 @@
             } else if (input instanceof HotSpotMetaspaceConstant) {
                 if (input.getKind() == Kind.Int) {
                     // compressed metaspace pointer
-                    crb.recordInlineDataInCode(new MetaspaceData(0, input.asInt(), HotSpotMetaspaceConstant.getMetaspaceObject(input), true));
+                    crb.recordInlineDataInCode(input);
                     masm.movl(address.toAddress(), input.asInt());
                 } else {
                     // uncompressed metaspace pointer
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java	Mon Oct 27 14:07:49 2014 +0100
@@ -43,9 +43,11 @@
 import com.oracle.graal.api.code.CompilationResult.Call;
 import com.oracle.graal.api.code.CompilationResult.CodeAnnotation;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.CompilationResult.DataSectionReference;
 import com.oracle.graal.api.code.CompilationResult.ExceptionHandler;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.code.CompilationResult.Mark;
+import com.oracle.graal.api.code.DataSection.Data;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.asm.hsail.*;
@@ -297,7 +299,7 @@
         HSAILHotSpotNmethod code = new HSAILHotSpotNmethod(javaMethod, hsailCode.getName(), false, true);
         code.setOopMapArray(hsailCode.getOopMapArray());
         code.setUsesAllocationFlag(hsailCode.getUsesAllocationFlag());
-        HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(getTarget(), javaMethod, compilationResult);
+        HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, compilationResult);
         CodeInstallResult result = getRuntime().getCompilerToVM().installCode(compiled, code, null);
         if (result != CodeInstallResult.OK) {
             return null;
@@ -314,7 +316,7 @@
         result.setEntryBCI(hsailCode.getEntryBCI());
         assert hsailCode.getMarks().isEmpty();
         assert hsailCode.getExceptionHandlers().isEmpty();
-        assert hsailCode.getDataReferences().isEmpty();
+        assert hsailCode.getDataPatches().isEmpty();
 
         // from host code
         result.setTotalFrameSize(hostCode.getTotalFrameSize());
@@ -329,14 +331,13 @@
         for (ExceptionHandler handler : hostCode.getExceptionHandlers()) {
             result.recordExceptionHandler(handler.pcOffset, handler.handlerPos);
         }
-        for (DataPatch patch : hostCode.getDataReferences()) {
-            if (patch.data != null) {
-                if (patch.inline) {
-                    result.recordInlineData(patch.pcOffset, patch.data);
-                } else {
-                    result.recordDataReference(patch.pcOffset, patch.data);
-                }
+        for (DataPatch patch : hostCode.getDataPatches()) {
+            if (patch.reference instanceof DataSectionReference) {
+                Data hostData = hostCode.getDataSection().findData((DataSectionReference) patch.reference);
+                Data resultData = new Data(hostData.getAlignment(), hostData.getSize(), hostData.getBuilder());
+                patch.reference = result.getDataSection().insertData(resultData);
             }
+            result.recordDataPatch(patch.pcOffset, patch.reference);
         }
         for (Infopoint infopoint : hostCode.getInfopoints()) {
             if (infopoint instanceof Call) {
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotLIRGenerator.java	Mon Oct 27 14:07:49 2014 +0100
@@ -257,7 +257,7 @@
         if (c.getKind() == Kind.Long) {
             int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL);
             if (c instanceof HotSpotMetaspaceConstant) {
-                return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c));
+                return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c), true);
             } else {
                 return Constant.forIntegerKind(Kind.Int, compressedValue);
             }
--- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotNodeLIRBuilder.java	Mon Oct 27 14:07:49 2014 +0100
@@ -68,7 +68,7 @@
         if (c.getKind() == Kind.Long) {
             int compressedValue = (int) (((c.asLong() - encoding.base) >> encoding.shift) & 0xffffffffL);
             if (c instanceof HotSpotMetaspaceConstant) {
-                return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c));
+                return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, compressedValue, HotSpotMetaspaceConstant.getMetaspaceObject(c), true);
             } else {
                 return Constant.forIntegerKind(Kind.Int, compressedValue);
             }
--- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/HotSpotCryptoSubstitutionTest.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -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(), hsMethod, compResult);
+        HotSpotCompiledNmethod compiledNmethod = new HotSpotCompiledNmethod(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/HotSpotCompiledCode.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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,17 +22,20 @@
  */
 package com.oracle.graal.hotspot;
 
+import java.nio.*;
 import java.util.*;
+import java.util.stream.*;
+import java.util.stream.Stream.Builder;
 
 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.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.hotspot.data.*;
 
 /**
  * A {@link CompilationResult} with additional HotSpot-specific information required for installing
@@ -47,7 +50,9 @@
     public final ExceptionHandler[] exceptionHandlers;
     public final Comment[] comments;
 
-    public final DataSection dataSection;
+    public final byte[] dataSection;
+    public final int dataSectionAlignment;
+    public final DataPatch[] dataSectionPatches;
 
     public static class Comment {
 
@@ -60,10 +65,9 @@
         }
     }
 
-    public HotSpotCompiledCode(TargetDescription target, CompilationResult compResult) {
+    public HotSpotCompiledCode(CompilationResult compResult) {
         this.comp = compResult;
         sites = getSortedSites(compResult);
-        dataSection = new DataSection(target, sites);
         if (compResult.getExceptionHandlers().isEmpty()) {
             exceptionHandlers = null;
         } else {
@@ -88,6 +92,17 @@
             }
         }
         assert validateFrames();
+
+        DataSection data = compResult.getDataSection();
+        data.finalizeLayout();
+        dataSection = new byte[data.getSectionSize()];
+
+        ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder());
+        Builder<DataPatch> patchBuilder = Stream.builder();
+        data.buildDataSection(buffer, patchBuilder);
+
+        dataSectionAlignment = data.getSectionAlignment();
+        dataSectionPatches = patchBuilder.build().toArray(len -> new DataPatch[len]);
     }
 
     /**
@@ -118,7 +133,7 @@
     }
 
     private static Site[] getSortedSites(CompilationResult target) {
-        List<?>[] lists = new List<?>[]{target.getInfopoints(), target.getDataReferences(), target.getMarks()};
+        List<?>[] lists = new List<?>[]{target.getInfopoints(), target.getDataPatches(), target.getMarks()};
         int count = 0;
         for (List<?> list : lists) {
             count += list.size();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -36,12 +36,12 @@
     public final int id;
     public final long ctask;
 
-    public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult) {
-        this(target, method, compResult, 0L);
+    public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) {
+        this(method, compResult, 0L);
     }
 
-    public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask) {
-        super(target, compResult);
+    public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask) {
+        super(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 Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -26,9 +26,9 @@
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CompilationResult.Call;
+import com.oracle.graal.api.code.CompilationResult.ConstantReference;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
-import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
 
@@ -41,8 +41,8 @@
 
     public final String stubName;
 
-    public HotSpotCompiledRuntimeStub(TargetDescription target, Stub stub, CompilationResult compResult) {
-        super(target, compResult);
+    public HotSpotCompiledRuntimeStub(Stub stub, CompilationResult compResult) {
+        super(compResult);
         this.stubName = stub.toString();
         assert checkStubInvariants(compResult);
     }
@@ -52,17 +52,20 @@
      */
     private boolean checkStubInvariants(CompilationResult compResult) {
         assert compResult.getExceptionHandlers().isEmpty();
-        for (DataPatch data : compResult.getDataReferences()) {
-            if (data.data instanceof MetaspaceData) {
-                MetaspaceData meta = (MetaspaceData) data.data;
-                if (meta.annotation instanceof HotSpotResolvedObjectType && ((HotSpotResolvedObjectType) meta.annotation).getName().equals("[I")) {
-                    // special handling for NewArrayStub
-                    // embedding the type '[I' is safe, since it is never unloaded
-                    continue;
+        for (DataPatch data : compResult.getDataPatches()) {
+            if (data.reference instanceof ConstantReference) {
+                ConstantReference ref = (ConstantReference) data.reference;
+                if (ref.getConstant() instanceof HotSpotMetaspaceConstant) {
+                    Object object = HotSpotMetaspaceConstant.getMetaspaceObject(ref.getConstant());
+                    if (object instanceof HotSpotResolvedObjectType && ((HotSpotResolvedObjectType) object).getName().equals("[I")) {
+                        // special handling for NewArrayStub
+                        // embedding the type '[I' is safe, since it is never unloaded
+                        continue;
+                    }
                 }
             }
 
-            assert !(data.data instanceof PatchedData) : this + " cannot have embedded object or metadata constant: " + data.data;
+            assert !(data.reference instanceof ConstantReference) : this + " cannot have embedded object or metadata constant: " + data.reference;
         }
         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/data/DataSection.java	Mon Oct 27 13:39:12 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/*
- * 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<>();
-
-        Map<Data, Integer> dataMap = new HashMap<>();
-
-        // 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 {
-                    Integer existingPos = dataMap.get(d);
-                    if (existingPos == null) {
-                        size = NumUtil.roundUp(size, d.getAlignment());
-                        size += d.getSize(target);
-                        patchCount += PatchedData.getPatchCount(d);
-                        dataMap.put(d, externalDataList.size());
-                    }
-                    externalDataList.add(dataPatch);
-                }
-            }
-        }
-
-        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 (int i = 0; i < externalDataList.size(); i++) {
-            DataPatch dataPatch = externalDataList.get(i);
-            assert !dataPatch.inline;
-            Data d = dataPatch.data;
-
-            Integer existingPos = dataMap.get(d);
-            if (existingPos == i) {
-                alignment = Math.max(alignment, d.getAlignment());
-                index = NumUtil.roundUp(index, d.getAlignment());
-                buffer.position(index);
-
-                DataSectionReference reference = new DataSectionReference(index);
-
-                // record patch locations
-                Iterator<DataPatch> it = PatchedData.getPatches(d, index).iterator();
-                while (it.hasNext()) {
-                    patches[patchIndex++] = it.next();
-                }
-
-                dataPatch.data = reference;
-
-                index += d.getSize(target);
-                d.emit(target, buffer);
-            } else {
-                dataPatch.data = externalDataList.get(existingPos).data;
-            }
-        }
-
-        this.sectionAlignment = alignment;
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java	Mon Oct 27 13:39:12 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * 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) {
-    }
-
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java	Mon Oct 27 13:39:12 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * 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.compiler.common.*;
-
-/**
- * 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 + "}";
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java	Mon Oct 27 13:39:12 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * 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.compiler.common.*;
-import com.oracle.graal.hotspot.*;
-
-/**
- * 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);
-        assert !compressed || HotSpotGraalRuntime.runtime().getConfig().useCompressedOops;
-        this.object = object;
-        this.compressed = compressed;
-    }
-
-    @Override
-    public int getSize(TargetDescription target) {
-        if (compressed) {
-            return target.getSizeInBytes(Kind.Int);
-        } 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) + "]";
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java	Mon Oct 27 13:39:12 2014 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * 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.util.stream.*;
-
-import com.oracle.graal.api.code.CompilationResult.Data;
-import com.oracle.graal.api.code.CompilationResult.DataPatch;
-
-/**
- * Represents a data item that needs to be patched.
- */
-public abstract class PatchedData extends Data {
-
-    protected PatchedData(int alignment) {
-        super(alignment);
-    }
-
-    public int getPatchCount() {
-        return 1;
-    }
-
-    public Stream<DataPatch> getPatches(int offset) {
-        return Stream.of(new DataPatch(offset, this, true));
-    }
-
-    public static int getPatchCount(Data data) {
-        if (data instanceof PatchedData) {
-            return ((PatchedData) data).getPatchCount();
-        } else {
-            return 0;
-        }
-    }
-
-    public static Stream<DataPatch> getPatches(Data data, int offset) {
-        if (data instanceof PatchedData) {
-            return ((PatchedData) data).getPatches(offset);
-        } else {
-            return Stream.empty();
-        }
-    }
-}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,18 +29,18 @@
 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.ConstantReference;
 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.code.DataSection.Data;
+import com.oracle.graal.api.code.DataSection.DataBuilder;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.*;
 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.lir.asm.*;
 import com.oracle.graal.printer.*;
@@ -136,8 +136,8 @@
                     addOperandComment(hcf, infopoint.pcOffset, "{infopoint: " + infopoint.reason + "}");
                 }
             }
-            for (DataPatch site : compResult.getDataReferences()) {
-                hcf.addOperandComment(site.pcOffset, "{" + site.data.toString() + "}");
+            for (DataPatch site : compResult.getDataPatches()) {
+                hcf.addOperandComment(site.pcOffset, "{" + site.reference.toString() + "}");
             }
             for (Mark mark : compResult.getMarks()) {
                 hcf.addComment(mark.pcOffset, MarkId.getEnum((int) mark.id).toString());
@@ -209,7 +209,7 @@
             compResult.setId(method.allocateCompileId(compResult.getEntryBCI()));
         }
         HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), isDefault);
-        runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, method, compResult, ctask), installedCode, method.getSpeculationLog());
+        runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, compResult, ctask), installedCode, method.getSpeculationLog());
         return logOrDump(installedCode, compResult);
     }
 
@@ -224,7 +224,7 @@
             HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false);
             installedCode = code;
         }
-        CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, hotspotMethod, compResult), installedCode, log);
+        CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, compResult), installedCode, log);
         if (result != CodeInstallResult.OK) {
             throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, "Code installation failed: %s", result);
         }
@@ -243,7 +243,7 @@
             compResult.setId(javaMethod.allocateCompileId(compResult.getEntryBCI()));
         }
         HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true);
-        HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(target, javaMethod, compResult);
+        HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, compResult);
         CompilerToVM vm = runtime.getCompilerToVM();
         CodeInstallResult result = vm.installCode(compiled, code, null);
         if (result != CodeInstallResult.OK) {
@@ -256,16 +256,48 @@
         return constant instanceof HotSpotMetaspaceConstant;
     }
 
-    public Data createDataItem(Constant constant, int alignment) {
-        if (constant instanceof HotSpotMetaspaceConstant) {
-            // constant.getKind() == target.wordKind for uncompressed pointers
-            // otherwise, it's a compressed pointer
-            return new MetaspaceData(alignment, constant.asLong(), HotSpotMetaspaceConstant.getMetaspaceObject(constant), constant.getKind() != target.wordKind);
-        } else if (constant.getKind().isObject()) {
-            return new OopData(alignment, HotSpotObjectConstant.asObject(constant), false);
+    public Data createDataItem(Constant constant) {
+        int size;
+        DataBuilder builder;
+        if (constant instanceof VMConstant) {
+            VMConstant vmConstant = (VMConstant) constant;
+            boolean compressed;
+            long raw;
+            if (vmConstant instanceof HotSpotObjectConstant) {
+                compressed = HotSpotObjectConstant.isCompressed(constant);
+                raw = 0xDEADDEADDEADDEADL;
+            } else if (vmConstant instanceof HotSpotMetaspaceConstant) {
+                compressed = vmConstant.getKind() != target.wordKind;
+                raw = vmConstant.asLong();
+            } else {
+                throw GraalInternalError.shouldNotReachHere();
+            }
+
+            size = target.getSizeInBytes(compressed ? Kind.Int : target.wordKind);
+            if (size == 4) {
+                builder = (buffer, patch) -> {
+                    patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant)));
+                    buffer.putInt((int) raw);
+                };
+            } else {
+                assert size == 8;
+                builder = (buffer, patch) -> {
+                    patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant)));
+                    buffer.putLong(raw);
+                };
+            }
+        } else if (constant.isNull()) {
+            boolean compressed = HotSpotObjectConstant.isCompressed(constant);
+            size = target.getSizeInBytes(compressed ? Kind.Int : target.wordKind);
+            builder = DataBuilder.zero(size);
+        } else if (constant instanceof PrimitiveConstant) {
+            size = target.getSizeInBytes(constant.getKind());
+            builder = DataBuilder.primitive((PrimitiveConstant) constant);
         } else {
-            return new PrimitiveData(constant, alignment);
+            throw GraalInternalError.shouldNotReachHere();
         }
+
+        return new Data(size, size, builder);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -166,10 +166,10 @@
                 assert bits == 32 && kind == Kind.Int;
                 long klassPointer = config().getKlassEncoding().uncompress((int) rawValue);
                 assert klassPointer == runtime.getCompilerToVM().readUnsafeKlassPointer(base);
-                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(klassPointer));
+                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(klassPointer), true);
             } else {
                 assert bits == 64 && kind == Kind.Long;
-                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(rawValue));
+                return HotSpotMetaspaceConstant.forMetaspaceObject(kind, rawValue, HotSpotResolvedObjectType.fromMetaspaceKlass(rawValue), false);
             }
         } else {
             switch (kind) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotMetaspaceConstant.java	Mon Oct 27 14:07:49 2014 +0100
@@ -26,12 +26,12 @@
 
 import com.oracle.graal.api.meta.*;
 
-public final class HotSpotMetaspaceConstant extends PrimitiveConstant implements HotSpotConstant {
+public final class HotSpotMetaspaceConstant extends PrimitiveConstant implements HotSpotConstant, VMConstant {
 
     private static final long serialVersionUID = 1003463314013122983L;
 
-    public static Constant forMetaspaceObject(Kind kind, long primitive, Object metaspaceObject) {
-        return new HotSpotMetaspaceConstant(kind, primitive, metaspaceObject);
+    public static Constant forMetaspaceObject(Kind kind, long primitive, Object metaspaceObject, boolean compressed) {
+        return new HotSpotMetaspaceConstant(kind, primitive, metaspaceObject, compressed);
     }
 
     public static Object getMetaspaceObject(Constant constant) {
@@ -39,10 +39,12 @@
     }
 
     private final Object metaspaceObject;
+    private final boolean compressed;
 
-    private HotSpotMetaspaceConstant(Kind kind, long primitive, Object metaspaceObject) {
+    private HotSpotMetaspaceConstant(Kind kind, long primitive, Object metaspaceObject, boolean compressed) {
         super(kind, primitive);
         this.metaspaceObject = metaspaceObject;
+        this.compressed = compressed;
     }
 
     @Override
@@ -57,6 +59,6 @@
 
     @Override
     public String toString() {
-        return super.toString() + "{" + metaspaceObject + "}";
+        return super.toString() + "{" + metaspaceObject + (compressed ? ";compressed}" : "}");
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotObjectConstant.java	Mon Oct 27 14:07:49 2014 +0100
@@ -28,7 +28,7 @@
  * Represents a constant non-{@code null} object reference, within the compiler and across the
  * compiler/runtime interface.
  */
-public final class HotSpotObjectConstant extends AbstractConstant implements HotSpotConstant {
+public final class HotSpotObjectConstant extends AbstractConstant implements HotSpotConstant, VMConstant {
 
     private static final long serialVersionUID = 3592151693708093496L;
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Mon Oct 27 14:07:49 2014 +0100
@@ -160,7 +160,7 @@
      * Gets the address of the C++ Method object for this method.
      */
     public Constant getMetaspaceMethodConstant() {
-        return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this);
+        return HotSpotMetaspaceConstant.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this, false);
     }
 
     public long getMetaspaceMethod() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedObjectType.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -769,7 +769,7 @@
      * Gets the metaspace Klass boxed in a {@link Constant}.
      */
     public Constant klass() {
-        return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, getMetaspaceKlass(), this);
+        return HotSpotMetaspaceConstant.forMetaspaceObject(runtime().getTarget().wordKind, getMetaspaceKlass(), this, false);
     }
 
     public boolean isPrimaryType() {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/CompressionNode.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -80,7 +80,7 @@
             return ((HotSpotObjectConstant) c).compress();
         } else if (c instanceof HotSpotMetaspaceConstant) {
             assert c.getKind() == Kind.Long;
-            return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, encoding.compress(c.asLong()), HotSpotMetaspaceConstant.getMetaspaceObject(c));
+            return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Int, encoding.compress(c.asLong()), HotSpotMetaspaceConstant.getMetaspaceObject(c), true);
         } else {
             throw GraalInternalError.shouldNotReachHere("invalid constant input for compress op: " + c);
         }
@@ -93,7 +93,7 @@
             return ((HotSpotObjectConstant) c).uncompress();
         } else if (c instanceof HotSpotMetaspaceConstant) {
             assert c.getKind() == Kind.Int;
-            return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Long, encoding.uncompress(c.asInt()), HotSpotMetaspaceConstant.getMetaspaceObject(c));
+            return HotSpotMetaspaceConstant.forMetaspaceObject(Kind.Long, encoding.uncompress(c.asInt()), HotSpotMetaspaceConstant.getMetaspaceObject(c), false);
         } else {
             throw GraalInternalError.shouldNotReachHere("invalid constant input for uncompress op: " + c);
         }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -174,7 +174,7 @@
                 try (Scope s = Debug.scope("CodeInstall")) {
                     Stub stub = Stub.this;
                     HotSpotRuntimeStub installedCode = new HotSpotRuntimeStub(stub);
-                    HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(backend.getTarget(), stub, compResult);
+                    HotSpotCompiledCode hsCompResult = new HotSpotCompiledRuntimeStub(stub, compResult);
 
                     CodeInstallResult result = runtime().getCompilerToVM().installCode(hsCompResult, installedCode, null);
                     if (result != CodeInstallResult.OK) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -28,7 +28,6 @@
 import static java.lang.Float.*;
 
 import com.oracle.graal.amd64.*;
-import com.oracle.graal.api.code.CompilationResult.RawData;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
@@ -333,8 +332,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
-            RawData rawData = new RawData(data, 16);
-            masm.leaq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(rawData));
+            masm.leaq(asRegister(result), (AMD64Address) crb.recordDataReferenceInCode(data, 16));
         }
     }
 
--- a/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.lir.sparc/src/com/oracle/graal/lir/sparc/SPARCMove.java	Mon Oct 27 14:07:49 2014 +0100
@@ -27,15 +27,45 @@
 import static com.oracle.graal.asm.sparc.SPARCAssembler.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 import static com.oracle.graal.sparc.SPARC.*;
-import static com.oracle.graal.asm.sparc.SPARCMacroAssembler.*;
-import static com.oracle.graal.lir.StandardOp.*;
 
-import com.oracle.graal.api.code.CompilationResult.RawData;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.sparc.*;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Add;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovd;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fmovs;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fzerod;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Fzeros;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lddf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsb;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsh;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldsw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Lduh;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Ldx;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Membar;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movdtox;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movstosw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movstouw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movwtos;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Movxtod;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Or;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stb;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stdf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stf;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Sth;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stw;
+import com.oracle.graal.asm.sparc.SPARCAssembler.Stx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Cas;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Casx;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Clr;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Mov;
+import com.oracle.graal.asm.sparc.SPARCMacroAssembler.Setx;
 import com.oracle.graal.compiler.common.*;
 import com.oracle.graal.lir.*;
+import com.oracle.graal.lir.StandardOp.ImplicitNullCheck;
+import com.oracle.graal.lir.StandardOp.MoveOp;
+import com.oracle.graal.lir.StandardOp.NullCheck;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.sparc.*;
 import com.oracle.graal.sparc.SPARC.CPUFeature;
@@ -355,8 +385,7 @@
 
         @Override
         public void emitCode(CompilationResultBuilder crb, SPARCMacroAssembler masm) {
-            RawData rawData = new RawData(data, 16);
-            SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(rawData);
+            SPARCAddress addr = (SPARCAddress) crb.recordDataReferenceInCode(data, 16);
             assert addr == masm.getPlaceholder();
             final boolean forceRelocatable = true;
             Register dstReg = asRegister(result);
@@ -818,7 +847,8 @@
                         delaySlotLir.emitControlTransfer(crb, masm);
                         new Clr(asRegister(result)).emit(masm);
                     } else if (crb.target.inlineObjects) {
-                        crb.recordInlineDataInCode(input); // relocatable cannot be delayed
+                        VMConstant vmConstant = (VMConstant) input;
+                        crb.recordInlineDataInCode(vmConstant); // relocatable cannot be delayed
                         new Setx(0xDEADDEADDEADDEADL, asRegister(result), true).emit(masm);
                     } else {
                         throw GraalInternalError.unimplemented();
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Mon Oct 27 13:39:12 2014 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,10 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.Data;
+import com.oracle.graal.api.code.CompilationResult.ConstantReference;
+import com.oracle.graal.api.code.CompilationResult.DataSectionReference;
+import com.oracle.graal.api.code.DataSection.Data;
+import com.oracle.graal.api.code.DataSection.DataBuilder;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
 import com.oracle.graal.compiler.common.*;
@@ -77,6 +80,8 @@
 
     private List<ExceptionInfo> exceptionInfoList;
 
+    private final IdentityHashMap<Constant, Data> dataCache;
+
     public CompilationResultBuilder(CodeCacheProvider codeCache, ForeignCallsProvider foreignCalls, FrameMap frameMap, Assembler asm, FrameContext frameContext, CompilationResult compilationResult) {
         this.target = codeCache.getTarget();
         this.codeCache = codeCache;
@@ -86,6 +91,9 @@
         this.compilationResult = compilationResult;
         this.frameContext = frameContext;
         assert frameContext != null;
+
+        // constants are already GVNed in the high level graph, so we can use an IdentityHashMap
+        this.dataCache = new IdentityHashMap<>();
     }
 
     public void setTotalFrameSize(int frameSize) {
@@ -154,27 +162,39 @@
     }
 
     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);
-        compilationResult.recordInlineData(pos, data);
+        if (data instanceof VMConstant) {
+            compilationResult.recordDataPatch(pos, new ConstantReference((VMConstant) data));
+        }
+    }
+
+    private AbstractAddress recordDataSectionReference(Data data) {
+        assert data != null;
+        DataSectionReference reference = compilationResult.getDataSection().insertData(data);
+        compilationResult.recordDataPatch(asm.position(), reference);
+        return asm.getPlaceholder();
     }
 
-    public AbstractAddress recordDataReferenceInCode(Constant data, int alignment) {
-        assert data != null;
-        return recordDataReferenceInCode(codeCache.createDataItem(data, alignment));
+    public AbstractAddress recordDataReferenceInCode(Constant constant, int alignment) {
+        assert constant != null;
+        Debug.log("Constant reference in code: pos = %d, data = %s", asm.position(), constant);
+        Data data = dataCache.get(constant);
+        if (data == null) {
+            data = codeCache.createDataItem(constant);
+            dataCache.put(constant, data);
+        }
+        data.updateAlignment(alignment);
+        return recordDataSectionReference(data);
     }
 
-    public AbstractAddress recordDataReferenceInCode(Data data) {
+    public AbstractAddress recordDataReferenceInCode(byte[] data, int alignment) {
         assert data != null;
-        int pos = asm.position();
-        Debug.log("Data reference in code: pos = %d, data = %s", pos, data);
-        compilationResult.recordDataReference(pos, data);
-        return asm.getPlaceholder();
+        if (Debug.isLogEnabled()) {
+            Debug.log("Data reference in code: pos = %d, data = %s", asm.position(), Arrays.toString(data));
+        }
+        return recordDataSectionReference(new Data(alignment, data.length, DataBuilder.raw(data)));
     }
 
     /**
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Mon Oct 27 13:39:12 2014 -0700
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.cpp	Mon Oct 27 14:07:49 2014 +0100
@@ -40,11 +40,11 @@
   }
 }
 
-void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
+void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
   address pc = _instructions->start() + pc_offset;
-  Handle obj = OopData::object(data);
+  Handle obj = HotSpotObjectConstant::object(constant);
   jobject value = JNIHandles::make_local(obj());
-  if (OopData::compressed(data)) {
+  if (HotSpotObjectConstant::compressed(constant)) {
     fatal("unimplemented: narrow oop relocation");
   } else {
     NativeMovConstReg* move = nativeMovConstReg_at(pc);
@@ -58,15 +58,14 @@
   }
 }
 
-void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
   address pc = _instructions->start() + pc_offset;
   address const_start = _constants->start();
-  jint offset = DataSectionReference::offset(data);
-  address dest = _constants->start() + offset;
+  address dest = _constants->start() + data_offset;
 
   _instructions->relocate(pc + NativeMovConstReg::sethi_offset, internal_word_Relocation::spec((address) dest));
   _instructions->relocate(pc + NativeMovConstReg::add_offset, internal_word_Relocation::spec((address) dest));
-  TRACE_graal_3("relocating at %p with destination at %p (%d)", pc, dest, offset);
+  TRACE_graal_3("relocating at %p with destination at %p (%d)", pc, dest, data_offset);
 }
 
 void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.cpp	Mon Oct 27 13:39:12 2014 -0700
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.cpp	Mon Oct 27 14:07:49 2014 +0100
@@ -58,11 +58,11 @@
   }
 }
 
-void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
+void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
   address pc = _instructions->start() + pc_offset;
-  Handle obj = OopData::object(data);
+  Handle obj = HotSpotObjectConstant::object(constant);
   jobject value = JNIHandles::make_local(obj());
-  if (OopData::compressed(data)) {
+  if (HotSpotObjectConstant::compressed(constant)) {
     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);
@@ -75,20 +75,19 @@
   }
 }
 
-void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
+void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
   address pc = _instructions->start() + pc_offset;
-  jint offset = DataSectionReference::offset(data);
 
   address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
   address next_instruction = Assembler::locate_next_instruction(pc);
-  address dest = _constants->start() + offset;
+  address dest = _constants->start() + data_offset;
 
   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);
+  TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, data_offset);
 }
 
 void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/share/vm/classfile/systemDictionary.hpp	Mon Oct 27 13:39:12 2014 -0700
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Oct 27 14:07:49 2014 +0100
@@ -195,10 +195,6 @@
   GRAAL_ONLY(do_klass(HotSpotCompiledRuntimeStub_klass,      com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub,          Graal)) \
   GRAAL_ONLY(do_klass(HotSpotForeignCallLinkage_klass,       com_oracle_graal_hotspot_HotSpotForeignCallLinkage,           Graal)) \
   GRAAL_ONLY(do_klass(HotSpotReferenceMap_klass,             com_oracle_graal_hotspot_HotSpotReferenceMap,                 Graal)) \
-  GRAAL_ONLY(do_klass(DataSection_klass,                     com_oracle_graal_hotspot_data_DataSection,                    Graal)) \
-  GRAAL_ONLY(do_klass(DataSectionReference_klass,            com_oracle_graal_hotspot_data_DataSectionReference,           Graal)) \
-  GRAAL_ONLY(do_klass(MetaspaceData_klass,                   com_oracle_graal_hotspot_data_MetaspaceData,                  Graal)) \
-  GRAAL_ONLY(do_klass(OopData_klass,                         com_oracle_graal_hotspot_data_OopData,                        Graal)) \
   GRAAL_ONLY(do_klass(HotSpotInstalledCode_klass,            com_oracle_graal_hotspot_meta_HotSpotInstalledCode,           Graal)) \
   GRAAL_ONLY(do_klass(HotSpotNmethod_klass,                  com_oracle_graal_hotspot_meta_HotSpotNmethod,                 Graal)) \
   GRAAL_ONLY(do_klass(HotSpotResolvedJavaMethod_klass,       com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod,      Graal)) \
@@ -221,7 +217,9 @@
   GRAAL_ONLY(do_klass(BytecodeFrame_klass,                   com_oracle_graal_api_code_BytecodeFrame,                      Graal)) \
   GRAAL_ONLY(do_klass(CompilationResult_klass,               com_oracle_graal_api_code_CompilationResult,                  Graal)) \
   GRAAL_ONLY(do_klass(CompilationResult_Call_klass,          com_oracle_graal_api_code_CompilationResult_Call,             Graal)) \
+  GRAAL_ONLY(do_klass(CompilationResult_ConstantReference_klass, com_oracle_graal_api_code_CompilationResult_ConstantReference, Graal)) \
   GRAAL_ONLY(do_klass(CompilationResult_DataPatch_klass,     com_oracle_graal_api_code_CompilationResult_DataPatch,        Graal)) \
+  GRAAL_ONLY(do_klass(CompilationResult_DataSectionReference_klass, com_oracle_graal_api_code_CompilationResult_DataSectionReference, Graal)) \
   GRAAL_ONLY(do_klass(CompilationResult_ExceptionHandler_klass, com_oracle_graal_api_code_CompilationResult_ExceptionHandler, Graal))\
   GRAAL_ONLY(do_klass(CompilationResult_Mark_klass,          com_oracle_graal_api_code_CompilationResult_Mark,             Graal)) \
   GRAAL_ONLY(do_klass(CompilationResult_Infopoint_klass,     com_oracle_graal_api_code_CompilationResult_Infopoint,        Graal)) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Oct 27 13:39:12 2014 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -302,10 +302,6 @@
   GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotForeignCallLinkage,       "com/oracle/graal/hotspot/HotSpotForeignCallLinkage"))            \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_HotSpotReferenceMap,             "com/oracle/graal/hotspot/HotSpotReferenceMap"))                  \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_bridge_CompilerToVMImpl,         "com/oracle/graal/hotspot/bridge/CompilerToVMImpl"))              \
-  GRAAL_ONLY(template(com_oracle_graal_hotspot_data_DataSection,                "com/oracle/graal/hotspot/data/DataSection"))                     \
-  GRAAL_ONLY(template(com_oracle_graal_hotspot_data_DataSectionReference,       "com/oracle/graal/hotspot/data/DataSectionReference"))            \
-  GRAAL_ONLY(template(com_oracle_graal_hotspot_data_MetaspaceData,              "com/oracle/graal/hotspot/data/MetaspaceData"))                   \
-  GRAAL_ONLY(template(com_oracle_graal_hotspot_data_OopData,                    "com/oracle/graal/hotspot/data/OopData"))                         \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode,       "com/oracle/graal/hotspot/meta/HotSpotInstalledCode"))            \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotNmethod,             "com/oracle/graal/hotspot/meta/HotSpotNmethod"))                  \
   GRAAL_ONLY(template(com_oracle_graal_hotspot_meta_HotSpotResolvedJavaMethod,  "com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod"))       \
@@ -335,7 +331,9 @@
   GRAAL_ONLY(template(com_oracle_graal_api_code_Assumptions_CallSiteTargetValue,"com/oracle/graal/api/code/Assumptions$CallSiteTargetValue"))     \
   GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult,              "com/oracle/graal/api/code/CompilationResult"))                   \
   GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_Call,         "com/oracle/graal/api/code/CompilationResult$Call"))              \
+  GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_ConstantReference, "com/oracle/graal/api/code/CompilationResult$ConstantReference")) \
   GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_DataPatch,    "com/oracle/graal/api/code/CompilationResult$DataPatch"))         \
+  GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_DataSectionReference, "com/oracle/graal/api/code/CompilationResult$DataSectionReference")) \
   GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_ExceptionHandler, "com/oracle/graal/api/code/CompilationResult$ExceptionHandler")) \
   GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_Mark,         "com/oracle/graal/api/code/CompilationResult$Mark"))              \
   GRAAL_ONLY(template(com_oracle_graal_api_code_CompilationResult_Infopoint,    "com/oracle/graal/api/code/CompilationResult$Infopoint"))         \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Oct 27 13:39:12 2014 -0700
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Oct 27 14:07:49 2014 +0100
@@ -199,8 +199,8 @@
   }
 }
 
-static void record_metadata_in_patch(oop data, OopRecorder* oop_recorder) {
-  record_metadata_reference(MetaspaceData::annotation(data), MetaspaceData::value(data), MetaspaceData::compressed(data) != 0, oop_recorder);
+static void record_metadata_in_patch(Handle& constant, OopRecorder* oop_recorder) {
+  record_metadata_reference(HotSpotMetaspaceConstant::metaspaceObject(constant), HotSpotMetaspaceConstant::primitive(constant), HotSpotMetaspaceConstant::compressed(constant), oop_recorder);
 }
 
 ScopeValue* CodeInstaller::get_scope_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) {
@@ -498,13 +498,14 @@
 
   // Pre-calculate the constants section size.  This is required for PC-relative addressing.
   _data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code));
-  guarantee(DataSection::sectionAlignment(data_section()) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
-  typeArrayHandle data = DataSection::data(data_section());
-  _constants_size = data->length();
+  guarantee(HotSpotCompiledCode::dataSectionAlignment(compiled_code) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
+  _constants_size = data_section()->length();
   if (_constants_size > 0) {
     _constants_size = align_size_up(_constants_size, _constants->alignment());
   }
 
+  _data_section_patches_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSectionPatches(compiled_code));
+
 #ifndef PRODUCT
   _comments_handle = JNIHandles::make_local(HotSpotCompiledCode::comments(compiled_code));
 #endif
@@ -556,30 +557,33 @@
   if (!_instructions->allocates2(end_pc)) {
     return false;
   }
-  memcpy(_instructions->start(), code()->base(T_BYTE), _code_size);
+  memcpy(_instructions->start(), code()->base(T_BYTE), code()->length());
   _instructions->set_end(end_pc);
 
   // copy the constant data into the newly created CodeBuffer
   address end_data = _constants->start() + _constants_size;
-  typeArrayHandle data(DataSection::data(data_section()));
-  memcpy(_constants->start(), data->base(T_BYTE), data->length());
+  memcpy(_constants->start(), data_section()->base(T_BYTE), _constants_size);
   _constants->set_end(end_data);
 
   
-  objArrayHandle patches = DataSection::patches(data_section());
-  for (int i = 0; i < patches->length(); i++) {
-    Handle patch = patches->obj_at(i);
-    Handle 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);
+  for (int i = 0; i < data_section_patches()->length(); i++) {
+    Handle patch = data_section_patches()->obj_at(i);
+    Handle reference = CompilationResult_DataPatch::reference(patch);
+    assert(reference->is_a(CompilationResult_ConstantReference::klass()), err_msg("patch in data section must be a ConstantReference"));
+    Handle constant = CompilationResult_ConstantReference::constant(reference);
+    if (constant->is_a(HotSpotMetaspaceConstant::klass())) {
+      record_metadata_in_patch(constant, _oop_recorder);
+    } else if (constant->is_a(HotSpotObjectConstant::klass())) {
+      Handle obj = HotSpotObjectConstant::object(constant);
       jobject value = JNIHandles::make_local(obj());
       int oop_index = _oop_recorder->find_index(value);
 
       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));
+      if (HotSpotObjectConstant::compressed(constant)) {
+        fatal("unexpected compressed oop in data section");
+      } else {
+        _constants->relocate(dest, oop_Relocation::spec(oop_index));
+      }
     } else {
       ShouldNotReachHere();
     }
@@ -898,13 +902,20 @@
 }
 
 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
-  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);
+  oop reference = CompilationResult_DataPatch::reference(site);
+  if (reference->is_a(CompilationResult_ConstantReference::klass())) {
+    Handle constant = CompilationResult_ConstantReference::constant(reference);
+    if (constant->is_a(HotSpotObjectConstant::klass())) {
+      pd_patch_OopConstant(pc_offset, constant);
+    } else if (constant->is_a(HotSpotMetaspaceConstant::klass())) {
+      record_metadata_in_patch(constant, _oop_recorder);
+    } else {
+      fatal("unknown constant type in data patch");
+    }
+  } else if (reference->is_a(CompilationResult_DataSectionReference::klass())) {
+    int data_offset = CompilationResult_DataSectionReference::offset(reference);
+    assert(0 <= data_offset && data_offset < _constants_size, err_msg("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size));
+    pd_patch_DataSectionReference(pc_offset, data_offset);
   } else {
     fatal("unknown data patch type");
   }
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Mon Oct 27 13:39:12 2014 -0700
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Mon Oct 27 14:07:49 2014 +0100
@@ -53,6 +53,7 @@
   Arena         _arena;
 
   jobject       _data_section_handle;
+  jobject       _data_section_patches_handle;
   jobject       _sites_handle;
   jobject       _exception_handlers_handle;
   CodeOffsets   _offsets;
@@ -86,8 +87,8 @@
   static LocationValue*       _illegal_value;
 
   jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method);
-  void pd_patch_OopData(int pc_offset, oop data);
-  void pd_patch_DataSectionReference(int pc_offset, oop data);
+  void pd_patch_OopConstant(int pc_offset, Handle& constant);
+  void pd_patch_DataSectionReference(int pc_offset, int data_offset);
   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);
@@ -96,6 +97,7 @@
   objArrayOop sites() { return (objArrayOop) JNIHandles::resolve(_sites_handle); }
   arrayOop code() { return (arrayOop) JNIHandles::resolve(_code_handle); }
   arrayOop data_section() { return (arrayOop) JNIHandles::resolve(_data_section_handle); }
+  objArrayOop data_section_patches() { return (objArrayOop) JNIHandles::resolve(_data_section_patches_handle); }
   objArrayOop exception_handlers() { return (objArrayOop) JNIHandles::resolve(_exception_handlers_handle); }
 #ifndef PRODUCT
   objArrayOop comments() { return (objArrayOop) JNIHandles::resolve(_comments_handle); }
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon Oct 27 13:39:12 2014 -0700
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Oct 27 14:07:49 2014 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -73,7 +73,9 @@
     objArrayOop_field(HotSpotCompiledCode, sites, "[Lcom/oracle/graal/api/code/CompilationResult$Site;")                                                       \
     objArrayOop_field(HotSpotCompiledCode, exceptionHandlers, "[Lcom/oracle/graal/api/code/CompilationResult$ExceptionHandler;")                               \
     objArrayOop_field(HotSpotCompiledCode, comments, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$Comment;")                                                \
-    oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/data/DataSection;")                                                                 \
+    typeArrayOop_field(HotSpotCompiledCode, dataSection, "[B")                                                                                                 \
+    int_field(HotSpotCompiledCode, dataSectionAlignment)                                                                                                       \
+    objArrayOop_field(HotSpotCompiledCode, dataSectionPatches, "[Lcom/oracle/graal/api/code/CompilationResult$DataPatch;")                                     \
   end_class                                                                                                                                                    \
   start_class(HotSpotCompiledCode_Comment)                                                                                                                     \
     oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;")                                                                                         \
@@ -91,23 +93,6 @@
   start_class(HotSpotForeignCallLinkage)                                                                                                                       \
     long_field(HotSpotForeignCallLinkage, address)                                                                                                             \
   end_class                                                                                                                                                    \
-  start_class(DataSection)                                                                                                                                     \
-    int_field(DataSection, sectionAlignment)                                                                                                                   \
-    typeArrayOop_field(DataSection, data, "[B")                                                                                                                \
-    objArrayOop_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                                                                                                                                                    \
@@ -148,7 +133,13 @@
     oop_field(CompilationResult_Call, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;")                                                                      \
   end_class                                                                                                                                                    \
   start_class(CompilationResult_DataPatch)                                                                                                                     \
-    oop_field(CompilationResult_DataPatch, data, "Lcom/oracle/graal/api/code/CompilationResult$Data;")                                                         \
+    oop_field(CompilationResult_DataPatch, reference, "Lcom/oracle/graal/api/code/CompilationResult$Reference;")                                               \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_ConstantReference)                                                                                                             \
+    oop_field(CompilationResult_ConstantReference, constant, "Lcom/oracle/graal/api/meta/VMConstant;")                                                         \
+  end_class                                                                                                                                                    \
+  start_class(CompilationResult_DataSectionReference)                                                                                                          \
+    int_field(CompilationResult_DataSectionReference, offset)                                                                                                  \
   end_class                                                                                                                                                    \
   start_class(InfopointReason)                                                                                                                                 \
     static_oop_field(InfopointReason, UNKNOWN, "Lcom/oracle/graal/api/code/InfopointReason;")                                                                  \
@@ -214,10 +205,12 @@
   end_class                                                                                                                                                    \
   start_class(HotSpotObjectConstant)                                                                                                                           \
     oop_field(HotSpotObjectConstant, object, "Ljava/lang/Object;")                                                                                             \
+    boolean_field(HotSpotObjectConstant, compressed)                                                                                                           \
   end_class                                                                                                                                                    \
   start_class(HotSpotMetaspaceConstant)                                                                                                                        \
     long_field(HotSpotMetaspaceConstant, primitive)                                                                                                            \
     oop_field(HotSpotMetaspaceConstant, metaspaceObject, "Ljava/lang/Object;")                                                                                 \
+    boolean_field(HotSpotMetaspaceConstant, compressed)                                                                                                        \
   end_class                                                                                                                                                    \
   start_class(Kind)                                                                                                                                            \
     char_field(Kind, typeChar)                                                                                                                                 \