changeset 6996:eec373d34caf

added support for annotated Constants and used it to track Klass* values in Graal and register them in the metadata section of a nmethod during code installation
author Doug Simon <doug.simon@oracle.com>
date Tue, 20 Nov 2012 22:49:27 +0100
parents edb2d7ed9a01
children b3a647ae5032
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.meta/src/com/oracle/graal/api/meta/Constant.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 10 files changed, 153 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Tue Nov 20 22:35:20 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CodeCacheProvider.java	Tue Nov 20 22:49:27 2012 +0100
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.api.code;
 
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
 import com.oracle.graal.api.code.RuntimeCall.Descriptor;
 import com.oracle.graal.api.meta.*;
 
@@ -93,4 +94,11 @@
      * @return the encoded value as an integer
      */
     int encodeDeoptActionAndReason(DeoptimizationAction action, DeoptimizationReason reason);
+
+    /**
+     * Determines if a {@link DataPatch} should be created for a given {@linkplain Constant#getPrimitiveAnnotation() annotated}
+     * primitive constant that part of a {@link CompilationResult}. A data patch is always
+     * created for an object constant.
+     */
+    boolean needsDataPatch(Constant constant);
 }
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Tue Nov 20 22:35:20 2012 +0100
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Tue Nov 20 22:49:27 2012 +0100
@@ -136,10 +136,16 @@
         public final Constant constant;
         public final int alignment;
 
-        DataPatch(int pcOffset, Constant data, int alignment) {
+        /**
+         * Determines if the data is encoded inline or is loaded from a separate data area.
+         */
+        public final boolean inlined;
+
+        DataPatch(int pcOffset, Constant data, int alignment, boolean inlined) {
             super(pcOffset);
             this.constant = data;
             this.alignment = alignment;
+            this.inlined = inlined;
         }
 
         @Override
@@ -387,10 +393,11 @@
      * @param codePos the position in the code where the data reference occurs
      * @param data the data that is referenced
      * @param alignment the alignment requirement of the data or 0 if there is no alignment requirement
+     * @param inlined specifies if the data is encoded inline or is loaded from a separate data area
      */
-    public void recordDataReference(int codePos, Constant data, int alignment) {
+    public void recordDataReference(int codePos, Constant data, int alignment, boolean inlined) {
         assert codePos >= 0 && data != null;
-        getDataReferences().add(new DataPatch(codePos, data, alignment));
+        getDataReferences().add(new DataPatch(codePos, data, alignment, inlined));
     }
 
     /**
--- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Tue Nov 20 22:35:20 2012 +0100
+++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Constant.java	Tue Nov 20 22:49:27 2012 +0100
@@ -63,7 +63,8 @@
     }
 
     /**
-     * The boxed object value. This is ignored iff {@code !kind.isObject()}.
+     * The boxed object value if {@code !kind.isObject()} otherwise the (possibly null)
+     * {@link #getPrimitiveAnnotation() annotation} for a primitive value.
      */
     private final Object object;
 
@@ -75,7 +76,7 @@
     private final long primitive;
 
     /**
-     * Create a new constant represented by the specified object reference.
+     * Creates a constant represented by the specified object reference.
      * @param object the value of this constant
      */
     private Constant(Object object) {
@@ -85,18 +86,36 @@
     }
 
     /**
-     * Create a new constant represented by the specified primitive.
+     * Creates a constant represented by the specified primitive.
      *
      * @param kind the type of this constant
      * @param primitive the value of this constant
      */
     public Constant(Kind kind, long primitive) {
         super(kind);
+        assert !kind.isObject();
         this.object = null;
         this.primitive = primitive;
     }
 
     /**
+     * Creates an annotated primitive constant. An annotation enables a {@linkplain MetaAccessProvider provider} to
+     * associate some extra semantic or debugging information with a primitive. An annotated primitive constant
+     * is never {@linkplain #equals(Object) equal} to a non-annotated constant.
+     *
+     * @param kind the type of this constant
+     * @param primitive the value of this constant
+     * @param annotation an arbitrary non-null object
+     */
+    public Constant(Kind kind, long primitive, Object annotation) {
+        super(kind);
+        assert !kind.isObject();
+        assert annotation != null;
+        this.object = annotation;
+        this.primitive = primitive;
+    }
+
+    /**
      * Checks whether this constant is non-null.
      *
      * @return {@code true} if this constant is a primitive, or an object constant that is not null
@@ -125,7 +144,11 @@
 
     @Override
     public String toString() {
-        return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]";
+        String annotationSuffix = "";
+        if (!getKind().isObject() && getPrimitiveAnnotation() != null) {
+            annotationSuffix = "{" + getPrimitiveAnnotation() + "}";
+        }
+        return getKind().getJavaName() + "[" + getKind().format(asBoxedValue()) + (getKind() != Kind.Object ? "|0x" + Long.toHexString(primitive) : "") + "]" + annotationSuffix;
     }
 
     /**
@@ -140,15 +163,15 @@
             case Boolean:
                 return asInt() == 0 ? Boolean.FALSE : Boolean.TRUE;
             case Short:
-                return (short) asInt();
+                return (short) primitive;
             case Char:
-                return (char) asInt();
+                return (char) primitive;
             case Jsr:
                 return (int) primitive;
             case Int:
-                return asInt();
+                return (int) primitive;
             case Long:
-                return asLong();
+                return primitive;
             case Float:
                 return asFloat();
             case Double:
@@ -167,7 +190,7 @@
         if (getKind().isObject()) {
             return object == other.object;
         }
-        return primitive == other.primitive;
+        return primitive == other.primitive && getPrimitiveAnnotation() == other.getPrimitiveAnnotation();
     }
 
     /**
@@ -276,6 +299,15 @@
     }
 
     /**
+     * Gets the annotation (if any) associated with this constant.
+     *
+     * @return null if this constant is not primitive or has no annotation
+     */
+    public Object getPrimitiveAnnotation() {
+        return getKind().isObject() ? null : object;
+    }
+
+    /**
      * Computes the hashcode of this constant.
      *
      * @return a suitable hashcode for this constant
@@ -289,8 +321,8 @@
     }
 
     /**
-     * Checks whether this constant equals another object. This is only true if the other object is a constant and has
-     * the same value.
+     * Checks whether this constant equals another object. This is only true if the other object is a constant that has
+     * the same {@linkplain #getKind() kind}, value and {@link #getPrimitiveAnnotation() annotation}.
      *
      * @param o the object to compare equality
      * @return {@code true} if this constant is equivalent to the specified object
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Tue Nov 20 22:35:20 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaType.java	Tue Nov 20 22:49:27 2012 +0100
@@ -403,8 +403,7 @@
 
     @Override
     public Constant klass() {
-        Kind wordKind = HotSpotGraalRuntime.getInstance().getTarget().wordKind;
-        return wordKind.isLong() ? Constant.forLong(metaspaceKlass) : Constant.forInt((int) metaspaceKlass);
+        return new Constant(HotSpotGraalRuntime.getInstance().getTarget().wordKind, metaspaceKlass, this);
     }
 
     public boolean isPrimaryType() {
@@ -419,12 +418,4 @@
     public long prototypeMarkWord() {
         return HotSpotGraalRuntime.getInstance().getCompilerToVM().getPrototypeMarkWord(this);
     }
-
-    public long address() {
-        return metaspaceKlass;
-    }
-
-    public String symbol() {
-        return javaMirror.getName();
-    }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Nov 20 22:35:20 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java	Tue Nov 20 22:49:27 2012 +0100
@@ -733,4 +733,8 @@
             default: throw GraalInternalError.shouldNotReachHere();
         }
     }
+
+    public boolean needsDataPatch(Constant constant) {
+        return constant.getPrimitiveAnnotation() instanceof HotSpotResolvedJavaType;
+    }
 }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Tue Nov 20 22:35:20 2012 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64ControlFlow.java	Tue Nov 20 22:49:27 2012 +0100
@@ -155,7 +155,12 @@
             if (key.getKind() == Kind.Int) {
                 Register intKey = asIntReg(key);
                 for (int i = 0; i < keyConstants.length; i++) {
-                    masm.cmpl(intKey, tasm.asIntConst(keyConstants[i]));
+                    if (tasm.runtime.needsDataPatch(keyConstants[i])) {
+                        tasm.recordDataReferenceInCode(keyConstants[i], 0, true);
+                    }
+                    long lc = keyConstants[i].asLong();
+                    assert NumUtil.isInt(lc);
+                    masm.cmpl(intKey, (int) lc);
                     masm.jcc(ConditionFlag.equal, keyTargets[i].label());
                 }
             } else if (key.getKind() == Kind.Long) {
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Tue Nov 20 22:35:20 2012 +0100
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Move.java	Tue Nov 20 22:49:27 2012 +0100
@@ -296,12 +296,19 @@
         switch (input.getKind().getStackKind()) {
             case Jsr:
             case Int:
+                if (tasm.runtime.needsDataPatch(input)) {
+                    tasm.recordDataReferenceInCode(input, 0, true);
+                }
                 // Do not optimize with an XOR as this instruction may be between
                 // a CMP and a Jcc in which case the XOR will modify the condition
                 // flags and interfere with the Jcc.
-                masm.movl(asRegister(result), tasm.asIntConst(input));
+                masm.movl(asRegister(result), input.asInt());
+
                 break;
             case Long:
+                if (tasm.runtime.needsDataPatch(input)) {
+                    tasm.recordDataReferenceInCode(input, 0, true);
+                }
                 // Do not optimize with an XOR as this instruction may be between
                 // a CMP and a Jcc in which case the XOR will modify the condition
                 // flags and interfere with the Jcc.
@@ -310,6 +317,7 @@
             case Float:
                 // This is *not* the same as 'constant == 0.0f' in the case where constant is -0.0f
                 if (Float.floatToRawIntBits(input.asFloat()) == Float.floatToRawIntBits(0.0f)) {
+                    assert !tasm.runtime.needsDataPatch(input);
                     masm.xorps(asFloatReg(result), asFloatReg(result));
                 } else {
                     masm.movflt(asFloatReg(result), tasm.asFloatConstRef(input));
@@ -318,6 +326,7 @@
             case Double:
                 // This is *not* the same as 'constant == 0.0d' in the case where constant is -0.0d
                 if (Double.doubleToRawLongBits(input.asDouble()) == Double.doubleToRawLongBits(0.0d)) {
+                    assert !tasm.runtime.needsDataPatch(input);
                     masm.xorpd(asDoubleReg(result), asDoubleReg(result));
                 } else {
                     masm.movdbl(asDoubleReg(result), tasm.asDoubleConstRef(input));
@@ -330,10 +339,10 @@
                 if (input.isNull()) {
                     masm.movq(asRegister(result), 0x0L);
                 } else if (tasm.target.inlineObjects) {
-                    tasm.recordDataReferenceInCode(input, 0);
+                    tasm.recordDataReferenceInCode(input, 0, true);
                     masm.movq(asRegister(result), 0xDEADDEADDEADDEADL);
                 } else {
-                    masm.movq(asRegister(result), tasm.recordDataReferenceInCode(input, 0));
+                    masm.movq(asRegister(result), tasm.recordDataReferenceInCode(input, 0, false));
                 }
                 break;
             default:
@@ -342,6 +351,7 @@
     }
 
     private static void const2stack(TargetMethodAssembler tasm, AMD64MacroAssembler masm, Value result, Constant input) {
+        assert !tasm.runtime.needsDataPatch(input);
         switch (input.getKind().getStackKind()) {
             case Jsr:
             case Int:    masm.movl(tasm.asAddress(result), input.asInt()); break;
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Tue Nov 20 22:35:20 2012 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Tue Nov 20 22:49:27 2012 +0100
@@ -163,11 +163,11 @@
         targetMethod.recordSafepoint(pos, debugInfo);
     }
 
-    public Address recordDataReferenceInCode(Constant data, int alignment) {
+    public Address recordDataReferenceInCode(Constant data, int alignment, boolean inlined) {
         assert data != null;
         int pos = asm.codeBuffer.position();
         Debug.log("Data reference in code: pos = %d, data = %s", pos, data.toString());
-        targetMethod.recordDataReference(pos, data, alignment);
+        targetMethod.recordDataReference(pos, data, alignment, inlined);
         return Address.Placeholder;
     }
 
@@ -175,15 +175,16 @@
         return lastSafepointPos;
     }
 
-
     /**
-     * Returns the integer value of any constants that can be represented by a 32-bit integer value,
+     * Returns the integer value of any constant that can be represented by a 32-bit integer value,
      * including long constants that fit into the 32-bit range.
      */
     public int asIntConst(Value value) {
         assert (value.getKind().getStackKind() == Kind.Int || value.getKind() == Kind.Jsr || value.getKind() == Kind.Long) && isConstant(value);
-        long c = ((Constant) value).asLong();
-        if (!(NumUtil.isInt(c))) {
+        Constant constant = (Constant) value;
+        assert !runtime.needsDataPatch(constant) : constant + " should be in a DataPatch";
+        long c = constant.asLong();
+        if (!NumUtil.isInt(c)) {
             throw GraalInternalError.shouldNotReachHere();
         }
         return (int) c;
@@ -198,7 +199,7 @@
 
     public Address asFloatConstRef(Value value, int alignment) {
         assert value.getKind() == Kind.Float && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, alignment);
+        return recordDataReferenceInCode((Constant) value, alignment, false);
     }
 
     /**
@@ -210,7 +211,7 @@
 
     public Address asDoubleConstRef(Value value, int alignment) {
         assert value.getKind() == Kind.Double && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, alignment);
+        return recordDataReferenceInCode((Constant) value, alignment, false);
     }
 
     /**
@@ -218,7 +219,7 @@
      */
     public Address asLongConstRef(Value value) {
         assert value.getKind() == Kind.Long && isConstant(value);
-        return recordDataReferenceInCode((Constant) value, 8);
+        return recordDataReferenceInCode((Constant) value, 8, false);
     }
 
     public Address asIntAddr(Value value) {
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Tue Nov 20 22:35:20 2012 +0100
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Nov 20 22:49:27 2012 +0100
@@ -102,7 +102,28 @@
   return map;
 }
 
-static ScopeValue* get_hotspot_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second) {
+// Records any Metadata values embedded in a Constant (e.g., the value returned by HotSpotResolvedJavaType.klass()).
+static void record_metadata_in_constant(oop constant, OopRecorder* oop_recorder) {
+  char kind = Kind::typeChar(Constant::kind(constant));
+  char wordKind = 'j';
+  if (kind == wordKind) {
+    oop obj = Constant::object(constant);
+    jlong prim = Constant::primitive(constant);
+    if (obj != NULL) {
+      if (obj->is_a(HotSpotResolvedJavaType::klass())) {
+        Klass* klass = (Klass*) (address) HotSpotResolvedJavaType::metaspaceKlass(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 {
+        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));
+      }
+    }
+  }
+}
+
+static ScopeValue* get_hotspot_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, OopRecorder* oop_recorder) {
   second = NULL;
   if (value == Value::ILLEGAL()) {
     return new LocationValue(Location::new_stk_loc(Location::invalid, 0));
@@ -157,7 +178,7 @@
     }
     return value;
   } else if (value->is_a(Constant::klass())){
-    oop obj = Constant::object(value);
+    record_metadata_in_constant(value, oop_recorder);
     jlong prim = Constant::primitive(value);
     if (type == T_INT || type == T_FLOAT || type == T_SHORT || type == T_CHAR || type == T_BOOLEAN || type == T_BYTE) {
       return new ConstantIntValue(*(jint*)&prim);
@@ -195,7 +216,7 @@
     arrayOop values = (arrayOop) VirtualObject::values(value);
     for (jint i = 0; i < values->length(); i++) {
       ScopeValue* cur_second = NULL;
-      ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second);
+      ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], total_frame_size, objects, cur_second, oop_recorder);
       
       if (isLongArray && cur_second == NULL) {
         // we're trying to put ints into a long array... this isn't really valid, but it's used for some optimizations.
@@ -222,14 +243,14 @@
   return NULL;
 }
 
-static MonitorValue* get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects) {
+static MonitorValue* get_monitor_value(oop value, int total_frame_size, GrowableArray<ScopeValue*>* objects, OopRecorder* oop_recorder) {
   guarantee(value->is_a(code_MonitorValue::klass()), "Monitors must be of type MonitorValue");
 
   ScopeValue* second = NULL;
-  ScopeValue* owner_value = get_hotspot_value(code_MonitorValue::owner(value), total_frame_size, objects, second);
+  ScopeValue* owner_value = get_hotspot_value(code_MonitorValue::owner(value), total_frame_size, objects, second, oop_recorder);
   assert(second == NULL, "monitor cannot occupy two stack slots");
 
-  ScopeValue* lock_data_value = get_hotspot_value(code_MonitorValue::lockData(value), total_frame_size, objects, second);
+  ScopeValue* lock_data_value = get_hotspot_value(code_MonitorValue::lockData(value), total_frame_size, objects, second, oop_recorder);
   assert(second == lock_data_value, "monitor is LONG value that occupies two stack slots");
   assert(lock_data_value->is_location(), "invalid monitor location");
   Location lock_data_loc = ((LocationValue*)lock_data_value)->location();
@@ -482,19 +503,19 @@
     oop value = ((oop*) values->base(T_OBJECT))[i];
 
     if (i < local_count) {
-      ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second);
+      ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second, _oop_recorder);
       if (second != NULL) {
         locals->append(second);
       }
       locals->append(first);
     } else if (i < local_count + expression_count) {
-      ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second);
+      ScopeValue* first = get_hotspot_value(value, _total_frame_size, objects, second, _oop_recorder);
       if (second != NULL) {
         expressions->append(second);
       }
       expressions->append(first);
     } else {
-      monitors->append(get_monitor_value(value, _total_frame_size, objects));
+      monitors->append(get_monitor_value(value, _total_frame_size, objects, _oop_recorder));
     }
     if (second != NULL) {
       i++;
@@ -601,7 +622,7 @@
       jump->set_jump_destination(VmIds::getStub(global_stub));
       _instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
     }
-    TRACE_graal_3("relocating (stub)  at %016x", inst);
+    TRACE_graal_3("relocating (stub)  at %p", inst);
   } else { // method != NULL
     assert(hotspot_method != NULL, "unexpected JavaMethod");
     assert(debug_info != NULL, "debug info expected");
@@ -659,6 +680,7 @@
 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
   oop constant = CompilationResult_DataPatch::constant(site);
   int alignment = CompilationResult_DataPatch::alignment(site);
+  bool inlined = CompilationResult_DataPatch::inlined(site);
   oop kind = Constant::kind(constant);
 
   address instruction = _instructions->start() + pc_offset;
@@ -675,24 +697,30 @@
     case 'f':
     case 'j':
     case 'd': {
-      address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
-      address next_instruction = Assembler::locate_next_instruction(instruction);
-      int size = _constants->size();
-      if (alignment > 0) {
-        guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
-        size = align_size_up(size, alignment);
+      record_metadata_in_constant(constant, _oop_recorder);
+      if (inlined) {
+        address operand = Assembler::locate_operand(instruction, Assembler::imm_operand);
+        *((jlong*) operand) = Constant::primitive(constant);
+      } else {
+        address operand = Assembler::locate_operand(instruction, Assembler::disp32_operand);
+        address next_instruction = Assembler::locate_next_instruction(instruction);
+        int size = _constants->size();
+        if (alignment > 0) {
+          guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
+          size = align_size_up(size, alignment);
+        }
+        // we don't care if this is a long/double/etc., the primitive field contains the right bits
+        address dest = _constants->start() + size;
+        _constants->set_end(dest + BytesPerLong);
+        *(jlong*) dest = Constant::primitive(constant);
+
+        long disp = dest - next_instruction;
+        assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
+        *((jint*) operand) = (jint) disp;
+
+        _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
+        TRACE_graal_3("relocating (%c) at %p/%p with destination at %p (%d)", typeChar, instruction, operand, dest, size);
       }
-      // we don't care if this is a long/double/etc., the primitive field contains the right bits
-      address dest = _constants->start() + size;
-      _constants->set_end(dest + BytesPerLong);
-      *(jlong*) dest = Constant::primitive(constant);
-
-      long disp = dest - next_instruction;
-      assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
-      *((jint*) operand) = (jint) disp;
-
-      _instructions->relocate(instruction, section_word_Relocation::spec((address) dest, CodeBuffer::SECT_CONSTS), Assembler::disp32_operand);
-      TRACE_graal_3("relocating (%c) at %016x/%016x with destination at %016x (%d)", typeChar, instruction, operand, dest, size);
       break;
     }
     case 'a': {
@@ -702,11 +730,11 @@
       jobject value = JNIHandles::make_local(obj());
       *((jobject*) operand) = value;
       _instructions->relocate(instruction, oop_Relocation::spec_for_immediate(), Assembler::imm_operand);
-      TRACE_graal_3("relocating (oop constant) at %016x/%016x", instruction, operand);
+      TRACE_graal_3("relocating (oop constant) at %p/%p", instruction, operand);
       break;
     }
     default:
-      fatal("unexpected Kind in DataPatch");
+      fatal(err_msg("unexpected Kind (%d) in DataPatch", typeChar));
       break;
   }
 }
--- a/src/share/vm/graal/graalJavaAccess.hpp	Tue Nov 20 22:35:20 2012 +0100
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Tue Nov 20 22:49:27 2012 +0100
@@ -127,6 +127,7 @@
   start_class(CompilationResult_DataPatch)                                                                                                                     \
     oop_field(CompilationResult_DataPatch, constant, "Lcom/oracle/graal/api/meta/Constant;")                                                                   \
     int_field(CompilationResult_DataPatch, alignment)                                                                                                          \
+    boolean_field(CompilationResult_DataPatch, inlined)                                                                                                           \
   end_class                                                                                                                                                    \
   start_class(CompilationResult_Safepoint)                                                                                                                     \
     oop_field(CompilationResult_Safepoint, debugInfo, "Lcom/oracle/graal/api/code/DebugInfo;")                                                                 \