changeset 10810:4e1db4c9d4c5

Support data patches for values larger than long.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 18 Jul 2013 15:37:02 +0200
parents 438dd12ff25b
children 5fced75a7f57
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java src/cpu/x86/vm/graalCodeInstaller_x86.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 5 files changed, 76 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Thu Jul 18 14:35:12 2013 +0200
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/CompilationResult.java	Thu Jul 18 15:37:02 2013 +0200
@@ -143,6 +143,7 @@
 
         private static final long serialVersionUID = 5771730331604867476L;
         public final Constant constant;
+        public final byte[] rawConstant;
         public final int alignment;
 
         /**
@@ -150,16 +151,29 @@
          */
         public final boolean inlined;
 
+        DataPatch(int pcOffset, byte[] data, int alignment) {
+            this(pcOffset, null, data, alignment, false);
+        }
+
         DataPatch(int pcOffset, Constant data, int alignment, boolean inlined) {
+            this(pcOffset, data, null, alignment, inlined);
+        }
+
+        private DataPatch(int pcOffset, Constant data, byte[] rawData, int alignment, boolean inlined) {
             super(pcOffset);
             this.constant = data;
+            this.rawConstant = rawData;
             this.alignment = alignment;
             this.inlined = inlined;
         }
 
         @Override
         public String toString() {
-            return String.format("%d[<data patch referring to data %s>]", pcOffset, constant);
+            if (constant == null) {
+                return String.format("%d[<data patch referring to %d bytes raw data>]", pcOffset, rawConstant.length);
+            } else {
+                return String.format("%d[<data patch referring to data %s>]", pcOffset, constant);
+            }
         }
     }
 
@@ -372,6 +386,20 @@
     }
 
     /**
+     * Records a reference to the data section in the code section (e.g. to load an integer or
+     * floating point constant).
+     * 
+     * @param codePos the position in the code where the data reference occurs
+     * @param data a byte array containing the raw data that is referenced
+     * @param alignment the alignment requirement of the data or 0 if there is no alignment
+     *            requirement
+     */
+    public void recordDataReference(int codePos, byte[] data, int alignment) {
+        assert codePos >= 0 && data != null && data.length > 0;
+        dataReferences.add(new DataPatch(codePos, data, alignment));
+    }
+
+    /**
      * Records a call in the code array.
      * 
      * @param codePos the position of the call in the code array
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Thu Jul 18 14:35:12 2013 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/asm/TargetMethodAssembler.java	Thu Jul 18 15:37:02 2013 +0200
@@ -165,6 +165,14 @@
         return asm.getPlaceholder();
     }
 
+    public AbstractAddress recordDataReferenceInCode(byte[] data, int alignment) {
+        assert data != null;
+        int pos = asm.codeBuffer.position();
+        Debug.log("Raw data reference in code: pos = %d, data = %s", pos, data.toString());
+        compilationResult.recordDataReference(pos, data, alignment);
+        return asm.getPlaceholder();
+    }
+
     /**
      * 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.
--- a/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Thu Jul 18 14:35:12 2013 +0200
+++ b/src/cpu/x86/vm/graalCodeInstaller_x86.hpp	Thu Jul 18 15:37:02 2013 +0200
@@ -57,14 +57,20 @@
 }
 
 inline void CodeInstaller::pd_site_DataPatch(int pc_offset, oop site) {
-  oop constant = CompilationResult_DataPatch::constant(site);
   int alignment = CompilationResult_DataPatch::alignment(site);
   bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE;
 
-  oop kind = Constant::kind(constant);
-  char typeChar = Kind::typeChar(kind);
+  address pc = _instructions->start() + pc_offset;
 
-  address pc = _instructions->start() + pc_offset;
+  oop constant = CompilationResult_DataPatch::constant(site);
+  char typeChar;
+  if (constant != NULL) {
+    oop kind = Constant::kind(constant);
+    typeChar = Kind::typeChar(kind);
+  } else {
+    assert(!inlined, "cannot inline raw constants");
+    typeChar = '*';
+  }
 
   switch (typeChar) {
     case 'z':
@@ -76,7 +82,8 @@
       break;
     case 'f':
     case 'j':
-    case 'd': {
+    case 'd':
+    case '*': {
       if (inlined) {
         address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
         *((jlong*) operand) = Constant::primitive(constant);
@@ -91,8 +98,16 @@
         // 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);
-        uint64_t value = Constant::primitive(constant);
-        _constants->emit_int64(value);
+        if (constant != NULL) {
+          uint64_t value = Constant::primitive(constant);
+          _constants->emit_int64(value);
+        } else {
+          arrayOop rawConstant = arrayOop(CompilationResult_DataPatch::rawConstant(site));
+          int8_t *ptr = (int8_t*) rawConstant->base(T_BYTE);
+          for (int i = rawConstant->length(); i > 0; i--, ptr++) {
+            _constants->emit_int8(*ptr);
+          }
+        }
 
         long disp = dest - next_instruction;
         assert(disp == (jint) disp, "disp doesn't fit in 32 bits");
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Thu Jul 18 14:35:12 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Thu Jul 18 15:37:02 2013 +0200
@@ -516,7 +516,6 @@
     jint pc_offset = CompilationResult_Site::pcOffset(site);
 
     if (site->is_a(CompilationResult_DataPatch::klass())) {
-      oop constant = CompilationResult_DataPatch::constant(site);
       int alignment = CompilationResult_DataPatch::alignment(site);
       bool inlined = CompilationResult_DataPatch::inlined(site) == JNI_TRUE;
 
@@ -525,7 +524,12 @@
           guarantee(alignment <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin");
           size = align_size_up(size, alignment);
         }
-        size = size + sizeof(int64_t);
+        if (CompilationResult_DataPatch::constant(site) != NULL) {
+          size = size + sizeof(int64_t);
+        } else {
+          arrayOop rawConstant = arrayOop(CompilationResult_DataPatch::rawConstant(site));
+          size = size + rawConstant->length();
+        }
       }
     }
   }
@@ -768,14 +772,16 @@
 
 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, oop site) {
   oop constant = CompilationResult_DataPatch::constant(site);
-  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;
+  if (constant != NULL) {
+    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;
+    }
   }
   CodeInstaller::pd_site_DataPatch(pc_offset, site);
 }
--- a/src/share/vm/graal/graalJavaAccess.hpp	Thu Jul 18 14:35:12 2013 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Thu Jul 18 15:37:02 2013 +0200
@@ -153,6 +153,7 @@
   end_class                                                                                                                                                    \
   start_class(CompilationResult_DataPatch)                                                                                                                     \
     oop_field(CompilationResult_DataPatch, constant, "Lcom/oracle/graal/api/meta/Constant;")                                                                   \
+    oop_field(CompilationResult_DataPatch, rawConstant, "[B")                                                                                                  \
     int_field(CompilationResult_DataPatch, alignment)                                                                                                          \
     boolean_field(CompilationResult_DataPatch, inlined)                                                                                                        \
   end_class                                                                                                                                                    \