changeset 14561:e14198669e5c

Make data patch system use vm specific NarrowOop kind.
author Roland Schatz <roland.schatz@oracle.com>
date Mon, 17 Mar 2014 11:53:51 +0100
parents 570910f5412b
children 45812e05cdb3
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.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/AMD64HotSpotMove.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.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.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp src/cpu/x86/vm/graalCodeInstaller_x86.hpp 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 21 files changed, 601 insertions(+), 356 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Mon Mar 17 11:40:12 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Mon Mar 17 11:53:51 2014 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.api.code;
 
+import com.oracle.graal.api.code.CompilationResult.Data;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.meta.*;
 
@@ -85,6 +86,11 @@
     boolean needsDataPatch(Constant constant);
 
     /**
+     * Create a {@link Data} item for a {@link Constant}, that can be used in a {@link DataPatch}.
+     */
+    Data createDataItem(Constant constant, int alignment);
+
+    /**
      * Gets a description of the target architecture.
      */
     TargetDescription getTarget();
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Mon Mar 17 11:40:12 2014 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Mon Mar 17 11:53:51 2014 +0100
@@ -154,64 +154,62 @@
 
         public abstract int getSize(TargetDescription target);
 
+        public abstract Kind getKind();
+
         public abstract void emit(TargetDescription target, ByteBuffer buffer);
     }
 
-    public static final class ConstantData extends Data {
+    /**
+     * Represents a Java primitive value used in a {@link DataPatch}. This implementation uses
+     * {@link Kind#getByteCount()} bytes to encode each value.
+     */
+    public static final class PrimitiveData extends Data {
 
         public final Constant constant;
 
-        public ConstantData(Constant constant, int alignment) {
+        public PrimitiveData(Constant constant, int alignment) {
             super(alignment);
+            assert constant.getKind().isPrimitive();
             this.constant = constant;
         }
 
         @Override
         public int getSize(TargetDescription target) {
-            return target.getSizeInBytes(constant.getPlatformKind());
+            return constant.getKind().getByteCount();
+        }
+
+        @Override
+        public Kind getKind() {
+            return constant.getKind();
         }
 
         @Override
         public void emit(TargetDescription target, ByteBuffer buffer) {
             switch (constant.getKind()) {
                 case Boolean:
-                    assert getSize(target) == 1;
                     buffer.put(constant.asBoolean() ? (byte) 1 : (byte) 0);
                     break;
                 case Byte:
-                    assert getSize(target) == 1;
                     buffer.put((byte) constant.asInt());
                     break;
                 case Char:
-                    assert getSize(target) == 2;
                     buffer.putChar((char) constant.asInt());
                     break;
                 case Short:
-                    assert getSize(target) == 2;
                     buffer.putShort((short) constant.asInt());
                     break;
                 case Int:
-                    assert getSize(target) == 4;
                     buffer.putInt(constant.asInt());
                     break;
                 case Long:
-                    assert getSize(target) == 8;
                     buffer.putLong(constant.asLong());
                     break;
                 case Float:
-                    assert getSize(target) == 4;
                     buffer.putFloat(constant.asFloat());
                     break;
                 case Double:
-                    assert getSize(target) == 8;
                     buffer.putDouble(constant.asDouble());
                     break;
-                case Object:
-                    // placeholder for oop value
-                    for (int i = 0; i < getSize(target); i++) {
-                        buffer.put((byte) 0);
-                    }
-                    break;
             }
         }
 
@@ -219,6 +217,24 @@
         public String toString() {
             return constant.toString();
         }
+
+        @Override
+        public int hashCode() {
+            return constant.hashCode();
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof PrimitiveData) {
+                PrimitiveData other = (PrimitiveData) obj;
+                return constant.equals(other.constant);
+            } else {
+                return false;
+            }
+        }
     }
 
     public static final class RawData extends Data {
@@ -236,6 +252,11 @@
         }
 
         @Override
+        public Kind getKind() {
+            return Kind.Illegal;
+        }
+
+        @Override
         public void emit(TargetDescription target, ByteBuffer buffer) {
             buffer.put(data);
         }
@@ -250,6 +271,24 @@
             }
             return ret.toString();
         }
+
+        @Override
+        public int hashCode() {
+            return Arrays.hashCode(data);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj instanceof RawData) {
+                RawData other = (RawData) obj;
+                return Arrays.equals(data, other.data);
+            } else {
+                return false;
+            }
+        }
     }
 
     /**
@@ -260,53 +299,18 @@
     public static final class DataPatch extends Site {
 
         private static final long serialVersionUID = 5771730331604867476L;
-        public Data externalData;
-        public Constant inlineData;
-
-        DataPatch(int pcOffset, Data externalData) {
-            this(pcOffset, externalData, null);
-        }
-
-        DataPatch(int pcOffset, Constant inlineData) {
-            this(pcOffset, null, inlineData);
-        }
-
-        private DataPatch(int pcOffset, Data externalData, Constant inlineData) {
-            super(pcOffset);
-            assert (externalData == null) != (inlineData == null) : "data patch can not be both external and inlined";
-            this.externalData = externalData;
-            this.inlineData = inlineData;
-        }
+        public Data data;
+        public boolean inline;
 
-        public Constant getConstant() {
-            if (inlineData != null) {
-                return inlineData;
-            } else if (externalData instanceof ConstantData) {
-                return ((ConstantData) externalData).constant;
-            } else {
-                return null;
-            }
-        }
-
-        public int getAlignment() {
-            if (externalData instanceof ConstantData) {
-                return ((ConstantData) externalData).getAlignment();
-            } else {
-                return 0;
-            }
-        }
-
-        public String getDataString() {
-            if (inlineData != null) {
-                return inlineData.toString();
-            } else {
-                return externalData.toString();
-            }
+        public DataPatch(int pcOffset, Data data, boolean inline) {
+            super(pcOffset);
+            this.data = data;
+            this.inline = inline;
         }
 
         @Override
         public String toString() {
-            return String.format("%d[<data patch referring to data %s>]", pcOffset, getDataString());
+            return String.format("%d[<data patch referring to %s data %s>]", pcOffset, inline ? "inline" : "external", data.toString());
         }
     }
 
@@ -538,18 +542,18 @@
      */
     public void recordDataReference(int codePos, Data data) {
         assert codePos >= 0 && data != null;
-        dataReferences.add(new DataPatch(codePos, data));
+        dataReferences.add(new DataPatch(codePos, data, false));
     }
 
     /**
      * Records a reference to an inlined constant in the code section (e.g. to load a constant oop).
      * 
      * @param codePos the position in the code where the inlined constant occurs
-     * @param constant the constant that is referenced
+     * @param data the data that is referenced
      */
-    public void recordInlineData(int codePos, Constant constant) {
-        assert codePos >= 0 && constant != null;
-        dataReferences.add(new DataPatch(codePos, constant));
+    public void recordInlineData(int codePos, Data data) {
+        assert codePos >= 0 && data != null;
+        dataReferences.add(new DataPatch(codePos, data, true));
     }
 
     /**
--- a/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Mar 17 11:40:12 2014 +0100
+++ b/graal/com.oracle.graal.asm.amd64.test/src/com/oracle/graal/asm/amd64/test/SimpleAssemblerTest.java	Mon Mar 17 11:53:51 2014 +0100
@@ -27,7 +27,7 @@
 import org.junit.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.ConstantData;
+import com.oracle.graal.api.code.CompilationResult.PrimitiveData;
 import com.oracle.graal.api.code.CompilationResult.RawData;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.amd64.*;
@@ -59,7 +59,7 @@
             public byte[] generateCode(CompilationResult compResult, TargetDescription target, RegisterConfig registerConfig, CallingConvention cc) {
                 AMD64MacroAssembler asm = new AMD64MacroAssembler(target, registerConfig);
                 Register ret = registerConfig.getReturnRegister(Kind.Double);
-                compResult.recordDataReference(asm.position(), new ConstantData(Constant.forDouble(84.72), 8));
+                compResult.recordDataReference(asm.position(), new PrimitiveData(Constant.forDouble(84.72), 8));
                 asm.movdbl(ret, asm.getPlaceholder());
                 asm.ret(0);
                 return asm.close(true);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Mar 17 11:40:12 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Mar 17 11:53:51 2014 +0100
@@ -293,14 +293,9 @@
             for (int i = 0; i < dms.length; i++) {
                 dms[i] = Debug.metric("DataPatches-" + Kind.values()[i].toString());
             }
-            DebugMetric dmRaw = Debug.metric("DataPatches-raw");
 
             for (DataPatch dp : ldp) {
-                if (dp.getConstant() != null) {
-                    dms[dp.getConstant().getKind().ordinal()].add(1);
-                } else {
-                    dmRaw.add(1);
-                }
+                dms[dp.data.getKind().ordinal()].add(1);
             }
 
             Debug.metric("CompilationResults").increment();
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Mar 17 11:40:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotMove.java	Mon Mar 17 11:53:51 2014 +0100
@@ -33,6 +33,7 @@
 import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.HotSpotVMConfig.CompressEncoding;
+import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64Move.LoadOp;
@@ -51,6 +52,9 @@
         public void emitMemAccess(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
             if (kind == Kind.Long) {
                 if (NumUtil.isInt(input.asLong())) {
+                    if (input.getPrimitiveAnnotation() != null) {
+                        crb.recordInlineDataInCode(new MetaspaceData(0, input.asLong(), input.getPrimitiveAnnotation(), true));
+                    }
                     masm.movl(address.toAddress(), (int) input.asLong());
                 } else {
                     throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
@@ -59,7 +63,7 @@
                 if (input.isNull()) {
                     masm.movl(address.toAddress(), 0);
                 } else if (crb.target.inlineObjects) {
-                    crb.recordInlineDataInCode(input);
+                    crb.recordInlineDataInCode(new OopData(0, input.asObject(), true));
                     masm.movl(address.toAddress(), 0xDEADDEAD);
                 } else {
                     throw GraalInternalError.shouldNotReachHere("Cannot store 64-bit constants to memory");
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java	Mon Mar 17 11:40:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledCode.java	Mon Mar 17 11:53:51 2014 +0100
@@ -22,21 +22,17 @@
  */
 package com.oracle.graal.hotspot;
 
-import java.nio.*;
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.code.CompilationResult.CodeAnnotation;
 import com.oracle.graal.api.code.CompilationResult.CodeComment;
-import com.oracle.graal.api.code.CompilationResult.Data;
-import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.ExceptionHandler;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.code.CompilationResult.JumpTable;
 import com.oracle.graal.api.code.CompilationResult.Mark;
 import com.oracle.graal.api.code.CompilationResult.Site;
-import com.oracle.graal.api.meta.*;
-import com.oracle.graal.asm.*;
+import com.oracle.graal.hotspot.data.*;
 
 /**
  * A {@link CompilationResult} with additional HotSpot-specific information required for installing
@@ -53,111 +49,6 @@
 
     public final DataSection dataSection;
 
-    /**
-     * Represents a reference to the data section. Before the code is installed, all {@link Data}
-     * items referenced by a {@link DataPatch} are put into the data section of the method, and
-     * replaced by {@link HotSpotData}.
-     */
-    public static final class HotSpotData extends Data {
-
-        /**
-         * The offset of the data item in the data section.
-         */
-        public int offset;
-
-        /**
-         * If the data item is an oop that needs to be patched by the runtime, this field contains
-         * the reference to the object.
-         */
-        public Constant constant;
-
-        public HotSpotData(int offset) {
-            super(0);
-            this.offset = offset;
-        }
-
-        @Override
-        public int getSize(TargetDescription target) {
-            return 0;
-        }
-
-        @Override
-        public void emit(TargetDescription target, ByteBuffer buffer) {
-        }
-    }
-
-    /**
-     * Represents the data section of a method.
-     */
-    public static final class DataSection {
-
-        /**
-         * The minimum alignment required for this data section.
-         */
-        public final int sectionAlignment;
-
-        /**
-         * The raw data contained in the data section.
-         */
-        public final byte[] data;
-
-        /**
-         * A list of locations where oop pointers need to be patched by the runtime.
-         */
-        public final HotSpotData[] patches;
-
-        public DataSection(TargetDescription target, Site[] sites) {
-            int size = 0;
-            int patchCount = 0;
-            List<DataPatch> externalDataList = new ArrayList<>();
-
-            // find all external data items and determine total size of data section
-            for (Site site : sites) {
-                if (site instanceof DataPatch) {
-                    DataPatch dataPatch = (DataPatch) site;
-                    if (dataPatch.externalData != null) {
-                        Data d = dataPatch.externalData;
-                        size = NumUtil.roundUp(size, d.getAlignment());
-                        size += d.getSize(target);
-                        externalDataList.add(dataPatch);
-                        if (dataPatch.getConstant() != null && dataPatch.getConstant().getKind() == Kind.Object) {
-                            patchCount++;
-                        }
-                    }
-                }
-            }
-
-            data = new byte[size];
-            patches = new HotSpotData[patchCount];
-            ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());
-            int index = 0;
-            int patchIndex = 0;
-            int alignment = 0;
-
-            // build data section
-            for (DataPatch dataPatch : externalDataList) {
-                Data d = dataPatch.externalData;
-
-                alignment = Math.max(alignment, d.getAlignment());
-                index = NumUtil.roundUp(index, d.getAlignment());
-                buffer.position(index);
-
-                HotSpotData hsData = new HotSpotData(index);
-                if (dataPatch.getConstant() != null && dataPatch.getConstant().getKind() == Kind.Object) {
-                    // record patch location for oop pointers
-                    hsData.constant = dataPatch.getConstant();
-                    patches[patchIndex++] = hsData;
-                }
-                dataPatch.externalData = hsData;
-
-                index += d.getSize(target);
-                d.emit(target, buffer);
-            }
-
-            this.sectionAlignment = alignment;
-        }
-    }
-
     public static class Comment {
 
         public final String text;
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java	Mon Mar 17 11:40:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub.java	Mon Mar 17 11:53:51 2014 +0100
@@ -26,7 +26,7 @@
 import com.oracle.graal.api.code.CompilationResult.Call;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
-import com.oracle.graal.api.meta.*;
+import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.hotspot.stubs.*;
 
 /**
@@ -50,11 +50,7 @@
     private boolean checkStubInvariants(CompilationResult compResult) {
         assert compResult.getExceptionHandlers().isEmpty();
         for (DataPatch data : compResult.getDataReferences()) {
-            Constant constant = data.getConstant();
-            if (constant != null) {
-                assert constant.getKind() != Kind.Object : this + " cannot have embedded object constant: " + constant;
-                assert constant.getPrimitiveAnnotation() == null : this + " cannot have embedded metadata: " + constant;
-            }
+            assert !(data.data instanceof PatchedData) : this + " cannot have embedded object or metadata constant: " + data.data;
         }
         for (Infopoint infopoint : compResult.getInfopoints()) {
             assert infopoint instanceof Call : this + " cannot have non-call infopoint: " + infopoint;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSection.java	Mon Mar 17 11:53:51 2014 +0100
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import java.nio.*;
+import java.util.*;
+
+import com.oracle.graal.api.code.CompilationResult.Data;
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.CompilationResult.Site;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.asm.*;
+
+/**
+ * Represents the data section of a method.
+ */
+public final class DataSection {
+
+    /**
+     * The minimum alignment required for this data section.
+     */
+    public final int sectionAlignment;
+
+    /**
+     * The raw data contained in the data section.
+     */
+    public final byte[] data;
+
+    /**
+     * A list of locations where oop pointers need to be patched by the runtime.
+     */
+    public final DataPatch[] patches;
+
+    public DataSection(TargetDescription target, Site[] sites) {
+        int size = 0;
+        int patchCount = 0;
+        List<DataPatch> externalDataList = new ArrayList<>();
+
+        // find all external data items and determine total size of data section
+        for (Site site : sites) {
+            if (site instanceof DataPatch) {
+                DataPatch dataPatch = (DataPatch) site;
+                Data d = dataPatch.data;
+                if (dataPatch.inline) {
+                    assert d instanceof PatchedData : "unnecessary data patch";
+                } else {
+                    size = NumUtil.roundUp(size, d.getAlignment());
+                    size += d.getSize(target);
+                    externalDataList.add(dataPatch);
+                    if (d instanceof PatchedData) {
+                        patchCount++;
+                    }
+                }
+            }
+        }
+
+        data = new byte[size];
+        patches = new DataPatch[patchCount];
+        ByteBuffer buffer = ByteBuffer.wrap(data).order(ByteOrder.nativeOrder());
+        int index = 0;
+        int patchIndex = 0;
+        int alignment = 0;
+
+        // build data section
+        for (DataPatch dataPatch : externalDataList) {
+            assert !dataPatch.inline;
+            Data d = dataPatch.data;
+
+            alignment = Math.max(alignment, d.getAlignment());
+            index = NumUtil.roundUp(index, d.getAlignment());
+            buffer.position(index);
+
+            DataSectionReference reference = new DataSectionReference(index);
+            if (d instanceof PatchedData) {
+                // record patch location
+                patches[patchIndex++] = new DataPatch(index, d, true);
+            }
+            dataPatch.data = reference;
+
+            index += d.getSize(target);
+            d.emit(target, buffer);
+        }
+
+        this.sectionAlignment = alignment;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/DataSectionReference.java	Mon Mar 17 11:53:51 2014 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import java.nio.*;
+
+import com.oracle.graal.api.code.CompilationResult.Data;
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+
+/**
+ * Represents a reference to the data section. Before the code is installed, all {@link Data} items
+ * referenced by a {@link DataPatch} are put into the data section of the method, and replaced by
+ * {@link DataSectionReference}.
+ */
+public class DataSectionReference extends Data {
+
+    public final int offset;
+
+    protected DataSectionReference(int offset) {
+        super(0);
+        this.offset = offset;
+    }
+
+    @Override
+    public int getSize(TargetDescription target) {
+        return 0;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.Illegal;
+    }
+
+    @Override
+    public void emit(TargetDescription target, ByteBuffer buffer) {
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/MetaspaceData.java	Mon Mar 17 11:53:51 2014 +0100
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import java.nio.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+
+/**
+ * A data item that represents a metaspace pointer.
+ */
+public class MetaspaceData extends PatchedData {
+
+    public final long value;
+    public final Object annotation;
+    public final boolean compressed;
+
+    public MetaspaceData(int alignment, long value, Object annotation, boolean compressed) {
+        super(alignment);
+        assert annotation != null;
+        this.value = value;
+        this.annotation = annotation;
+        this.compressed = compressed;
+    }
+
+    @Override
+    public int getSize(TargetDescription target) {
+        if (compressed) {
+            return target.getSizeInBytes(Kind.Int);
+        } else {
+            return target.getSizeInBytes(target.wordKind);
+        }
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.Long;
+    }
+
+    @Override
+    public void emit(TargetDescription target, ByteBuffer buffer) {
+        switch (getSize(target)) {
+            case 4:
+                buffer.putInt((int) value);
+                break;
+            case 8:
+                buffer.putLong(value);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("unexpected metaspace pointer size");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return (compressed ? "NarrowPointer[0x" + Integer.toHexString((int) value) : "Pointer[0x" + Long.toHexString(value)) + "]{" + annotation + "}";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/OopData.java	Mon Mar 17 11:53:51 2014 +0100
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import java.nio.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.hotspot.nodes.type.*;
+
+/**
+ * A data item that represents an oop value.
+ */
+public class OopData extends PatchedData {
+
+    public final Object object;
+    public final boolean compressed;
+
+    public OopData(int alignment, Object object, boolean compressed) {
+        super(alignment);
+        this.object = object;
+        this.compressed = compressed;
+    }
+
+    @Override
+    public int getSize(TargetDescription target) {
+        if (compressed) {
+            return target.getSizeInBytes(NarrowOopStamp.NarrowOop);
+        } else {
+            return target.getSizeInBytes(Kind.Object);
+        }
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.Object;
+    }
+
+    @Override
+    public void emit(TargetDescription target, ByteBuffer buffer) {
+        switch (getSize(target)) {
+            case 4:
+                buffer.putInt(0xDEADDEAD);
+                break;
+            case 8:
+                buffer.putLong(0xDEADDEADDEADDEADL);
+                break;
+            default:
+                throw GraalInternalError.shouldNotReachHere("unexpected oop size");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return (compressed ? "NarrowOop[" : "Oop[") + Kind.Object.format(object) + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/data/PatchedData.java	Mon Mar 17 11:53:51 2014 +0100
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot.data;
+
+import com.oracle.graal.api.code.CompilationResult.Data;
+
+/**
+ * Represents a data item that needs to be patched.
+ */
+public abstract class PatchedData extends Data {
+
+    protected PatchedData(int alignment) {
+        super(alignment);
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Mar 17 11:40:12 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java	Mon Mar 17 11:53:51 2014 +0100
@@ -29,14 +29,17 @@
 import com.oracle.graal.api.code.CodeUtil.DefaultRefMapFormatter;
 import com.oracle.graal.api.code.CodeUtil.RefMapFormatter;
 import com.oracle.graal.api.code.CompilationResult.Call;
+import com.oracle.graal.api.code.CompilationResult.Data;
 import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.code.CompilationResult.Mark;
+import com.oracle.graal.api.code.CompilationResult.PrimitiveData;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.hotspot.*;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult;
+import com.oracle.graal.hotspot.data.*;
 import com.oracle.graal.java.*;
 import com.oracle.graal.printer.*;
 
@@ -82,7 +85,7 @@
                 }
             }
             for (DataPatch site : compResult.getDataReferences()) {
-                hcf.addOperandComment(site.pcOffset, "{" + site.getDataString() + "}");
+                hcf.addOperandComment(site.pcOffset, "{" + site.data.toString() + "}");
             }
             for (Mark mark : compResult.getMarks()) {
                 hcf.addComment(mark.pcOffset, getMarkName(mark));
@@ -216,6 +219,16 @@
         return constant.getPrimitiveAnnotation() != null;
     }
 
+    public Data createDataItem(Constant constant, int alignment) {
+        if (constant.getPrimitiveAnnotation() != null) {
+            return new MetaspaceData(alignment, constant.asLong(), constant.getPrimitiveAnnotation(), false);
+        } else if (constant.getKind().isObject()) {
+            return new OopData(alignment, constant.asObject(), false);
+        } else {
+            return new PrimitiveData(constant, alignment);
+        }
+    }
+
     @Override
     public TargetDescription getTarget() {
         return target;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Mon Mar 17 11:40:12 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/CompilationResultBuilder.java	Mon Mar 17 11:53:51 2014 +0100
@@ -27,7 +27,6 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.ConstantData;
 import com.oracle.graal.api.code.CompilationResult.Data;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
@@ -157,6 +156,10 @@
     }
 
     public void recordInlineDataInCode(Constant data) {
+        recordInlineDataInCode(codeCache.createDataItem(data, 0));
+    }
+
+    public void recordInlineDataInCode(Data data) {
         assert data != null;
         int pos = asm.position();
         Debug.log("Inline data in code: pos = %d, data = %s", pos, data);
@@ -165,7 +168,7 @@
 
     public AbstractAddress recordDataReferenceInCode(Constant data, int alignment) {
         assert data != null;
-        return recordDataReferenceInCode(new ConstantData(data, alignment));
+        return recordDataReferenceInCode(codeCache.createDataItem(data, alignment));
     }
 
     public AbstractAddress recordDataReferenceInCode(Data data) {
--- a/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Mon Mar 17 11:40:12 2014 +0100
+++ b/src/cpu/sparc/vm/graalCodeInstaller_sparc.hpp	Mon Mar 17 11:53:51 2014 +0100
@@ -41,55 +41,32 @@
   }
 }
 
-inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) {
-  oop inlineData = CompilationResult_DataPatch::inlineData(site);
-  address pc = _instructions->start() + pc_offset;
+inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
+  if (OopData::compressed(obj)) {
+    fatal("unimplemented: narrow oop relocation");
+  } else {
+    address pc = _instructions->start() + pc_offset;
+    Handle obj = OopData::object(data);
+    jobject value = JNIHandles::make_local(obj());
 
-  if (inlineData != NULL) {
-    oop kind = Constant::kind(inlineData);
-    char typeChar = Kind::typeChar(kind);
+    NativeMovConstReg* move = nativeMovConstReg_at(pc);
+    move->set_data((intptr_t) value);
 
-    switch (typeChar) {
-      case 'z':
-      case 'b':
-      case 's':
-      case 'c':
-      case 'i':
-        fatal("int-sized values not expected in DataPatch");
-        break;
-      case 'f':
-      case 'j':
-      case 'd': {
-        NativeMovConstReg* move = nativeMovConstReg_at(pc);
-        uint64_t value = Constant::primitive(inlineData);
-        move->set_data(value);
-        break;
-      }
-      case 'a': {
-        NativeMovConstReg* move = nativeMovConstReg_at(pc);
-        Handle obj = Constant::object(inlineData);
-        jobject value = JNIHandles::make_local(obj());
-        move->set_data((intptr_t) value);
+    // We need two relocations:  one on the sethi and one on the add.
+    int oop_index = _oop_recorder->find_index(value);
+    RelocationHolder rspec = oop_Relocation::spec(oop_index);
+    _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec);
+    _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec);
+  }
+}
 
-        // We need two relocations:  one on the sethi and one on the add.
-        int oop_index = _oop_recorder->find_index(value);
-        RelocationHolder rspec = oop_Relocation::spec(oop_index);
-        _instructions->relocate(pc + NativeMovConstReg::sethi_offset, rspec);
-        _instructions->relocate(pc + NativeMovConstReg::add_offset, rspec);
-        break;
-      }
-      default:
-        fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
-        break;
-    }
-  } else {
-    oop dataRef = CompilationResult_DataPatch::externalData(site);
-    jint offset = HotSpotCompiledCode_HotSpotData::offset(dataRef);
+inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
+  address pc = _instructions->start() + pc_offset;
+  jint offset = DataSectionReference::offset(data);
 
-    NativeMovRegMem* load = nativeMovRegMem_at(pc);
-    int disp = _constants_size + pc_offset - offset - BytesPerInstWord;
-    load->set_offset(-disp);
-  }
+  NativeMovRegMem* load = nativeMovRegMem_at(pc);
+  int disp = _constants_size + pc_offset - offset - BytesPerInstWord;
+  load->set_offset(-disp);
 }
 
 inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Mon Mar 17 11:40:12 2014 +0100
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Mon Mar 17 11:53:51 2014 +0100
@@ -59,68 +59,49 @@
   }
 }
 
-inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) {
-  oop inlineData = CompilationResult_DataPatch::inlineData(site);
+inline bool check_metaspace_data(address pc, oop data) {
+  jlong value = MetaspaceData::value(data);
+  address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
+  if (MetaspaceData::compressed(data)) {
+    assert(*((jint*) operand) == value, err_msg("wrong compressed metaspace pointer: %p != %p", *((jint*) operand), value));
+  } else {
+    assert(*((jlong*) operand) == value, err_msg("wrong metaspace pointer: %p != %p", *((jlong*) operand), value));
+  }
+  return true;
+}
+
+inline void CodeInstaller::pd_patch_OopData(int pc_offset, oop data) {
   address pc = _instructions->start() + pc_offset;
 
-  if (inlineData != NULL) {
-    oop kind = Constant::kind(inlineData);
-    char typeChar = Kind::typeChar(kind);
-
-    switch (typeChar) {
-      case 'z':
-      case 'b':
-      case 's':
-      case 'c':
-      case 'i':
-        fatal("int-sized values not expected in DataPatch");
-        break;
-      case 'n': {
-        address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
-        Handle obj = Constant::object(inlineData);
+  Handle obj = OopData::object(data);
+  jobject value = JNIHandles::make_local(obj());
+  if (OopData::compressed(data)) {
+    address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
+    int oop_index = _oop_recorder->find_index(value);
+    _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand);
+    TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand);
+  } else {
+    address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
+    *((jobject*) operand) = value;
+    _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
+    TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand);
+  }
+}
 
-        jobject value = JNIHandles::make_local(obj());
-        int oop_index = _oop_recorder->find_index(value);
-        _instructions->relocate(pc, oop_Relocation::spec(oop_index), Assembler::narrow_oop_operand);
-        TRACE_graal_3("relocating (narrow oop constant) at %p/%p", pc, operand);
-        break;
-      }
-      case 'f':
-      case 'j':
-      case 'd':
-      case '*': {
-        address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
-        *((jlong*) operand) = Constant::primitive(inlineData);
-        break;
-      }
-      case 'a': {
-        address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
-        Handle obj = Constant::object(inlineData);
+inline void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, oop data) {
+  address pc = _instructions->start() + pc_offset;
+  jint offset = DataSectionReference::offset(data);
 
-        jobject value = JNIHandles::make_local(obj());
-        *((jobject*) operand) = value;
-        _instructions->relocate(pc, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
-        TRACE_graal_3("relocating (oop constant) at %p/%p", pc, operand);
-        break;
-      }
-      default:
-        fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
-        break;
-    }
-  } else {
-    oop dataRef = CompilationResult_DataPatch::externalData(site);
-    jint offset = HotSpotCompiledCode_HotSpotData::offset(dataRef);
-    address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
-    address next_instruction = Assembler::locate_next_instruction(pc);
-    address dest = _constants->start() + offset;
+  address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
+  address next_instruction = Assembler::locate_next_instruction(pc);
+  address dest = _constants->start() + offset;
 
-    long disp = dest - next_instruction;
-    assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
-    *((jint*) operand) = (jint) disp;
+  long disp = dest - next_instruction;
+  assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
+  *((jint*) operand) = (jint) disp;
 
-    _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
-    TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset);
-  }
+  _instructions->relocate(pc, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
+  TRACE_graal_3("relocating at %p/%p with destination at %p (%d)", pc, operand, dest, offset);
 }
 
 inline void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
--- a/src/share/vm/classfile/systemDictionary.hpp	Mon Mar 17 11:40:12 2014 +0100
+++ b/src/share/vm/classfile/systemDictionary.hpp	Mon Mar 17 11:53:51 2014 +0100
@@ -187,12 +187,14 @@
   do_klass(BitSet_klass,                          java_util_BitSet,                                             Opt) \
   /* graal.hotspot */                                                                                                \
   do_klass(HotSpotCompiledCode_klass,             com_oracle_graal_hotspot_HotSpotCompiledCode,                 Opt) \
-  do_klass(HotSpotCompiledCode_HotSpotData_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_HotSpotData,     Opt) \
-  do_klass(HotSpotCompiledCode_DataSection_klass, com_oracle_graal_hotspot_HotSpotCompiledCode_DataSection,     Opt) \
   do_klass(HotSpotCompiledCode_Comment_klass,     com_oracle_graal_hotspot_HotSpotCompiledCode_Comment,         Opt) \
   do_klass(HotSpotCompiledNmethod_klass,          com_oracle_graal_hotspot_HotSpotCompiledNmethod,              Opt) \
   do_klass(HotSpotCompiledRuntimeStub_klass,      com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub,          Opt) \
   do_klass(HotSpotForeignCallLinkage_klass,       com_oracle_graal_hotspot_HotSpotForeignCallLinkage,           Opt) \
+  do_klass(DataSection_klass,                     com_oracle_graal_hotspot_data_DataSection,                    Opt) \
+  do_klass(DataSectionReference_klass,            com_oracle_graal_hotspot_data_DataSectionReference,           Opt) \
+  do_klass(MetaspaceData_klass,                   com_oracle_graal_hotspot_data_MetaspaceData,                  Opt) \
+  do_klass(OopData_klass,                         com_oracle_graal_hotspot_data_OopData,                        Opt) \
   do_klass(HotSpotCodeInfo_klass,                 com_oracle_graal_hotspot_meta_HotSpotCodeInfo,                Opt) \
   do_klass(HotSpotInstalledCode_klass,            com_oracle_graal_hotspot_meta_HotSpotInstalledCode,           Opt) \
   do_klass(HotSpotNmethod_klass,                  com_oracle_graal_hotspot_meta_HotSpotNmethod,                 Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Mon Mar 17 11:40:12 2014 +0100
+++ b/src/share/vm/classfile/vmSymbols.hpp	Mon Mar 17 11:53:51 2014 +0100
@@ -296,14 +296,16 @@
   template(com_oracle_graal_hotspot_HotSpotKlassOop,                 "com/oracle/graal/hotspot/HotSpotKlassOop")                      \
   template(com_oracle_graal_hotspot_HotSpotOptions,                  "com/oracle/graal/hotspot/HotSpotOptions")                       \
   template(com_oracle_graal_hotspot_HotSpotCompiledCode,             "com/oracle/graal/hotspot/HotSpotCompiledCode")                  \
-  template(com_oracle_graal_hotspot_HotSpotCompiledCode_HotSpotData, "com/oracle/graal/hotspot/HotSpotCompiledCode$HotSpotData")      \
-  template(com_oracle_graal_hotspot_HotSpotCompiledCode_DataSection, "com/oracle/graal/hotspot/HotSpotCompiledCode$DataSection")      \
   template(com_oracle_graal_hotspot_HotSpotCompiledCode_Comment,     "com/oracle/graal/hotspot/HotSpotCompiledCode$Comment")          \
   template(com_oracle_graal_hotspot_HotSpotCompiledNmethod,          "com/oracle/graal/hotspot/HotSpotCompiledNmethod")               \
   template(com_oracle_graal_hotspot_HotSpotCompiledRuntimeStub,      "com/oracle/graal/hotspot/HotSpotCompiledRuntimeStub")           \
   template(com_oracle_graal_hotspot_HotSpotForeignCallLinkage,       "com/oracle/graal/hotspot/HotSpotForeignCallLinkage")            \
   template(com_oracle_graal_hotspot_bridge_VMToCompiler,             "com/oracle/graal/hotspot/bridge/VMToCompiler")                  \
   template(com_oracle_graal_hotspot_bridge_CompilerToVMImpl,         "com/oracle/graal/hotspot/bridge/CompilerToVMImpl")              \
+  template(com_oracle_graal_hotspot_data_DataSection,                "com/oracle/graal/hotspot/data/DataSection")                     \
+  template(com_oracle_graal_hotspot_data_DataSectionReference,       "com/oracle/graal/hotspot/data/DataSectionReference")            \
+  template(com_oracle_graal_hotspot_data_MetaspaceData,              "com/oracle/graal/hotspot/data/MetaspaceData")                   \
+  template(com_oracle_graal_hotspot_data_OopData,                    "com/oracle/graal/hotspot/data/OopData")                         \
   template(com_oracle_graal_hotspot_meta_HotSpotCodeInfo,            "com/oracle/graal/hotspot/meta/HotSpotCodeInfo")                 \
   template(com_oracle_graal_hotspot_meta_HotSpotInstalledCode,       "com/oracle/graal/hotspot/meta/HotSpotInstalledCode")            \
   template(com_oracle_graal_hotspot_meta_HotSpotNmethod,             "com/oracle/graal/hotspot/meta/HotSpotNmethod")                  \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon Mar 17 11:40:12 2014 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon Mar 17 11:53:51 2014 +0100
@@ -157,6 +157,27 @@
   return map;
 }
 
+static void record_metadata_reference(oop obj, jlong prim, bool compressed, OopRecorder* oop_recorder) {
+  if (obj->is_a(HotSpotResolvedObjectType::klass())) {
+    Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj));
+    if (compressed) {
+      assert(Klass::decode_klass((narrowKlass) prim) == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim));
+    } else {
+      assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim));
+    }
+    int index = oop_recorder->find_index(klass);
+    TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string());
+  } else if (obj->is_a(HotSpotResolvedJavaMethod::klass())) {
+    Method* method = (Method*) (address) HotSpotResolvedJavaMethod::metaspaceMethod(obj);
+    assert(!compressed, err_msg("unexpected compressed method pointer %s @ %p = %p", method->name()->as_C_string(), method, prim));
+    int index = oop_recorder->find_index(method);
+    TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string());
+  } else {
+    assert(java_lang_String::is_instance(obj),
+        err_msg("unexpected metadata reference (%s) for constant %ld (%p)", obj->klass()->name()->as_C_string(), prim, prim));
+  }
+}
+
 // Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedObjectType.klass()).
 static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) {
   char kind = Kind::typeChar(Constant::kind(constant));
@@ -165,23 +186,15 @@
     oop obj = Constant::object(constant);
     jlong prim = Constant::primitive(constant);
     if (obj != NULL) {
-      if (obj->is_a(HotSpotResolvedObjectType::klass())) {
-        Klass* klass = java_lang_Class::as_Klass(HotSpotResolvedObjectType::javaClass(obj));
-        assert((Klass*) prim == klass, err_msg("%s @ %p != %p", klass->name()->as_C_string(), klass, prim));
-        int index = oop_recorder->find_index(klass);
-        TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), klass->name()->as_C_string());
-      } else if (obj->is_a(HotSpotResolvedJavaMethod::klass())) {
-        Method* method = (Method*) (address) HotSpotResolvedJavaMethod::metaspaceMethod(obj);
-        int index = oop_recorder->find_index(method);
-        TRACE_graal_3("metadata[%d of %d] = %s", index, oop_recorder->metadata_count(), method->name()->as_C_string());
-      } else {
-        assert(java_lang_String::is_instance(obj),
-            err_msg("unexpected annotation type (%s) for constant %ld (%p) of kind %c", obj->klass()->name()->as_C_string(), prim, prim, kind));
-      }
+      record_metadata_reference(obj, prim, false, oop_recorder);
     }
   }
 }
 
+static void record_metadata_in_patch(oop data, OopRecorder* oop_recorder) {
+  record_metadata_reference(MetaspaceData::annotation(data), MetaspaceData::value(data), MetaspaceData::compressed(data), oop_recorder);
+}
+
 ScopeValue* CodeInstaller::get_scope_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) {
   second = NULL;
   if (value == Value::ILLEGAL()) {
@@ -445,8 +458,8 @@
 
   // Pre-calculate the constants section size.  This is required for PC-relative addressing.
   _dataSection = HotSpotCompiledCode::dataSection(compiled_code);
-  guarantee(HotSpotCompiledCode_DataSection::sectionAlignment(_dataSection) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
-  arrayOop data = (arrayOop) HotSpotCompiledCode_DataSection::data(_dataSection);
+  guarantee(DataSection::sectionAlignment(_dataSection) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
+  arrayOop data = (arrayOop) DataSection::data(_dataSection);
   _constants_size = data->length();
   if (_constants_size > 0) {
     _constants_size = align_size_up(_constants_size, _constants->alignment());
@@ -482,30 +495,24 @@
 
   // copy the constant data into the newly created CodeBuffer
   address end_data = _constants->start() + _constants_size;
-  arrayOop data = (arrayOop) HotSpotCompiledCode_DataSection::data(_dataSection);
+  arrayOop data = (arrayOop) DataSection::data(_dataSection);
   memcpy(_constants->start(), data->base(T_BYTE), data->length());
   _constants->set_end(end_data);
 
-  objArrayOop patches = (objArrayOop) HotSpotCompiledCode_DataSection::patches(_dataSection);
+  objArrayOop patches = (objArrayOop) DataSection::patches(_dataSection);
   for (int i = 0; i < patches->length(); i++) {
     oop patch = patches->obj_at(i);
-    oop constant = HotSpotCompiledCode_HotSpotData::constant(patch);
-    oop kind = Constant::kind(constant);
-    char typeChar = Kind::typeChar(kind);
-    switch (typeChar) {
-      case 'f':
-      case 'j':
-      case 'd':
-        record_metadata_in_constant(constant, _oop_recorder);
-        break;
-      case 'a':
-        Handle obj = Constant::object(constant);
-        jobject value = JNIHandles::make_local(obj());
-        int oop_index = _oop_recorder->find_index(value);
+    oop data = CompilationResult_DataPatch::data(patch);
+    if (data->is_a(MetaspaceData::klass())) {
+      record_metadata_in_patch(data, _oop_recorder);
+    } else if (data->is_a(OopData::klass())) {
+      Handle obj = OopData::object(data);
+      jobject value = JNIHandles::make_local(obj());
+      int oop_index = _oop_recorder->find_index(value);
 
-        address dest = _constants->start() + HotSpotCompiledCode_HotSpotData::offset(patch);
-        _constants->relocate(dest, oop_Relocation::spec(oop_index));
-        break;
+      address dest = _constants->start() + CompilationResult_Site::pcOffset(patch);
+      assert(!OopData::compressed(data), err_msg("unexpected compressed oop in data section"));
+      _constants->relocate(dest, oop_Relocation::spec(oop_index));
     }
   }
 
@@ -777,19 +784,16 @@
 }
 
 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
-  oop inlineData = CompilationResult_DataPatch::inlineData(site);
-  if (inlineData != NULL) {
-    oop kind = Constant::kind(inlineData);
-    char typeChar = Kind::typeChar(kind);
-    switch (typeChar) {
-      case 'f':
-      case 'j':
-      case 'd':
-        record_metadata_in_constant(inlineData, _oop_recorder);
-        break;
-    }
+  oop data = CompilationResult_DataPatch::data(site);
+  if (data->is_a(MetaspaceData::klass())) {
+    record_metadata_in_patch(data, _oop_recorder);
+  } else if (data->is_a(OopData::klass())) {
+    pd_patch_OopData(pc_offset, data);
+  } else if (data->is_a(DataSectionReference::klass())) {
+    pd_patch_DataSectionReference(pc_offset, data);
+  } else {
+    fatal("unknown data patch type");
   }
-  CodeInstaller::pd_site_DataPatch(pc_offset, site);
 }
 
 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, oop site) {
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Mon Mar 17 11:40:12 2014 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Mon Mar 17 11:53:51 2014 +0100
@@ -77,7 +77,8 @@
   ExceptionHandlerTable     _exception_handler_table;
 
   jint pd_next_offset(NativeInstruction* inst, jint pc_offset, oop method);
-  void pd_site_DataPatch(int pc_offset, oop site);
+  void pd_patch_OopData(int pc_offset, oop data);
+  void pd_patch_DataSectionReference(int pc_offset, oop data);
   void pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst);
   void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination);
   void pd_relocate_JavaMethod(oop method, jint pc_offset);
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon Mar 17 11:40:12 2014 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon Mar 17 11:53:51 2014 +0100
@@ -79,16 +79,7 @@
     oop_field(HotSpotCompiledCode, sites, "[Lcom/oracle/graal/api/code/CompilationResult$Site;")                                                               \
     oop_field(HotSpotCompiledCode, exceptionHandlers, "[Lcom/oracle/graal/api/code/CompilationResult$ExceptionHandler;")                                       \
     oop_field(HotSpotCompiledCode, comments, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$Comment;")                                                        \
-    oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/HotSpotCompiledCode$DataSection;")                                                  \
-  end_class                                                                                                                                                    \
-  start_class(HotSpotCompiledCode_HotSpotData)                                                                                                                 \
-    int_field(HotSpotCompiledCode_HotSpotData, offset)                                                                                                         \
-    oop_field(HotSpotCompiledCode_HotSpotData, constant, "Lcom/oracle/graal/api/meta/Constant;")                                                               \
-  end_class                                                                                                                                                    \
-  start_class(HotSpotCompiledCode_DataSection)                                                                                                                 \
-    int_field(HotSpotCompiledCode_DataSection, sectionAlignment)                                                                                               \
-    oop_field(HotSpotCompiledCode_DataSection, data, "[B")                                                                                                     \
-    oop_field(HotSpotCompiledCode_DataSection, patches, "[Lcom/oracle/graal/hotspot/HotSpotCompiledCode$HotSpotData;")                                         \
+    oop_field(HotSpotCompiledCode, dataSection, "Lcom/oracle/graal/hotspot/data/DataSection;")                                                                 \
   end_class                                                                                                                                                    \
   start_class(HotSpotCompiledCode_Comment)                                                                                                                     \
     oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;")                                                                                         \
@@ -97,7 +88,7 @@
   start_class(HotSpotCompiledNmethod)                                                                                                                          \
     oop_field(HotSpotCompiledNmethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;")                                                     \
     int_field(HotSpotCompiledNmethod, entryBCI)                                                                                                                \
-    int_field(HotSpotCompiledNmethod, id)                                                                                                                \
+    int_field(HotSpotCompiledNmethod, id)                                                                                                                      \
   end_class                                                                                                                                                    \
   start_class(HotSpotCompiledRuntimeStub)                                                                                                                      \
     oop_field(HotSpotCompiledRuntimeStub, stubName, "Ljava/lang/String;")                                                                                      \
@@ -105,6 +96,23 @@
   start_class(HotSpotForeignCallLinkage)                                                                                                                       \
     long_field(HotSpotForeignCallLinkage, address)                                                                                                             \
   end_class                                                                                                                                                    \
+  start_class(DataSection)                                                                                                                                     \
+    int_field(DataSection, sectionAlignment)                                                                                                                   \
+    oop_field(DataSection, data, "[B")                                                                                                                         \
+    oop_field(DataSection, patches, "[Lcom/oracle/graal/api/code/CompilationResult$DataPatch;")                                                                \
+  end_class                                                                                                                                                    \
+  start_class(DataSectionReference)                                                                                                                            \
+    int_field(DataSectionReference, offset)                                                                                                                    \
+  end_class                                                                                                                                                    \
+  start_class(MetaspaceData)                                                                                                                                   \
+    long_field(MetaspaceData, value)                                                                                                                           \
+    oop_field(MetaspaceData, annotation, "Ljava/lang/Object;")                                                                                                 \
+    boolean_field(MetaspaceData, compressed)                                                                                                                   \
+  end_class                                                                                                                                                    \
+  start_class(OopData)                                                                                                                                         \
+    oop_field(OopData, object, "Ljava/lang/Object;")                                                                                                           \
+    boolean_field(OopData, compressed)                                                                                                                         \
+  end_class                                                                                                                                                    \
   start_class(ExternalCompilationResult)                                                                                                                       \
     long_field(ExternalCompilationResult, entryPoint)                                                                                                          \
   end_class                                                                                                                                                    \
@@ -145,8 +153,7 @@
     oop_field(CompilationResult_Call, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;")                                                                      \
   end_class                                                                                                                                                    \
   start_class(CompilationResult_DataPatch)                                                                                                                     \
-    oop_field(CompilationResult_DataPatch, externalData, "Lcom/oracle/graal/api/code/CompilationResult$Data;")                                                 \
-    oop_field(CompilationResult_DataPatch, inlineData, "Lcom/oracle/graal/api/meta/Constant;")                                                                 \
+    oop_field(CompilationResult_DataPatch, data, "Lcom/oracle/graal/api/code/CompilationResult$Data;")                                                         \
   end_class                                                                                                                                                    \
   start_class(InfopointReason)                                                                                                                                 \
     static_oop_field(InfopointReason, UNKNOWN, "Lcom/oracle/graal/api/code/InfopointReason;")                                                                  \