changeset 12251:a0cf41abef5d

8167184: [s390] Extend relocations for pc-relative instructions. Reviewed-by: kvn
author goetz
date Wed, 05 Oct 2016 15:20:35 +0200
parents c1715eaaa820
children 2844bdfd7a99
files src/share/vm/asm/codeBuffer.cpp src/share/vm/code/codeBlob.hpp src/share/vm/code/nmethod.cpp src/share/vm/code/relocInfo.cpp src/share/vm/code/relocInfo.hpp
diffstat 5 files changed, 61 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/asm/codeBuffer.cpp	Thu Sep 22 18:29:15 2016 +0200
+++ b/src/share/vm/asm/codeBuffer.cpp	Wed Oct 05 15:20:35 2016 +0200
@@ -747,6 +747,10 @@
   CodeBuffer dest(dest_blob);
   assert(dest_blob->content_size() >= total_content_size(), "good sizing");
   this->compute_final_layout(&dest);
+
+  // Set beginning of constant table before relocating.
+  dest_blob->set_ctable_begin(dest.consts()->start());
+
   relocate_code_to(&dest);
 
   // transfer strings and comments from buffer to blob
@@ -940,6 +944,9 @@
     }
   }
 
+  // Needs to be initialized when calling fix_relocation_after_move.
+  cb.blob()->set_ctable_begin(cb.consts()->start());
+
   // Move all the code and relocations to the new blob:
   relocate_code_to(&cb);
 
--- a/src/share/vm/code/codeBlob.hpp	Thu Sep 22 18:29:15 2016 +0200
+++ b/src/share/vm/code/codeBlob.hpp	Wed Oct 05 15:20:35 2016 +0200
@@ -30,6 +30,7 @@
 #include "compiler/oopMap.hpp"
 #include "runtime/frame.hpp"
 #include "runtime/handles.hpp"
+#include "utilities/macros.hpp"
 
 // CodeBlob Types
 // Used in the CodeCache to assign CodeBlobs to different CodeHeaps
@@ -95,6 +96,7 @@
   bool                _caller_must_gc_arguments;
   CodeStrings         _strings;
   const char*         _name;
+  S390_ONLY(int       _ctable_offset;)
 
   CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
   CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
@@ -140,6 +142,12 @@
   address code_end() const            { return _code_end; }
   address data_end() const            { return _data_end;      }
 
+  // This field holds the beginning of the const section in the old code buffer.
+  // It is needed to fix relocations of pc-relative loads when resizing the
+  // the constant pool or moving it.
+  S390_ONLY(address ctable_begin() const { return header_begin() + _ctable_offset; })
+  void set_ctable_begin(address ctable) { S390_ONLY(_ctable_offset = ctable - header_begin();) }
+
   // Sizes
   int size() const                               { return _size; }
   int header_size() const                        { return _header_size; }
--- a/src/share/vm/code/nmethod.cpp	Thu Sep 22 18:29:15 2016 +0200
+++ b/src/share/vm/code/nmethod.cpp	Wed Oct 05 15:20:35 2016 +0200
@@ -682,6 +682,7 @@
     // Section offsets
     _consts_offset           = content_offset()      + code_buffer->total_offset_of(code_buffer->consts());
     _stub_offset             = content_offset()      + code_buffer->total_offset_of(code_buffer->stubs());
+    set_ctable_begin(header_begin() + _consts_offset);
 
 #if INCLUDE_JVMCI
     _jvmci_installed_code = installed_code();
@@ -2177,6 +2178,7 @@
         //verify_interrupt_point(iter.addr());
         break;
       case relocInfo::runtime_call_type:
+      case relocInfo::runtime_call_w_cp_type:
         address destination = iter.reloc()->value();
         // Right now there is no way to find out which entries support
         // an interrupt point.  It would be nice if we had this
@@ -2435,10 +2437,11 @@
           st.print(")");
           return st.as_string();
         }
-        case relocInfo::runtime_call_type: {
+        case relocInfo::runtime_call_type:
+        case relocInfo::runtime_call_w_cp_type: {
           stringStream st;
           st.print("runtime_call");
-          runtime_call_Relocation* r = iter.runtime_call_reloc();
+          CallRelocation* r = (CallRelocation*)iter.reloc();
           address dest = r->destination();
           CodeBlob* cb = CodeCache::find_blob(dest);
           if (cb != NULL) {
--- a/src/share/vm/code/relocInfo.cpp	Thu Sep 22 18:29:15 2016 +0200
+++ b/src/share/vm/code/relocInfo.cpp	Wed Oct 05 15:20:35 2016 +0200
@@ -552,6 +552,14 @@
   _cached_value = x0==0? NULL: address_from_scaled_offset(x0, point);
 }
 
+void runtime_call_w_cp_Relocation::pack_data_to(CodeSection * dest) {
+  short* p = pack_1_int_to((short *)dest->locs_end(), (jint)(_offset >> 2));
+  dest->set_locs_end((relocInfo*) p);
+}
+
+void runtime_call_w_cp_Relocation::unpack_data() {
+  _offset = unpack_1_int() << 2;
+}
 
 void static_stub_Relocation::pack_data_to(CodeSection* dest) {
   short* p = (short*) dest->locs_end();
@@ -1017,6 +1025,7 @@
       break;
     }
   case relocInfo::runtime_call_type:
+  case relocInfo::runtime_call_w_cp_type:
     {
       CallRelocation* r = (CallRelocation*) reloc();
       tty->print(" | [destination=" INTPTR_FORMAT "]", p2i(r->destination()));
--- a/src/share/vm/code/relocInfo.hpp	Thu Sep 22 18:29:15 2016 +0200
+++ b/src/share/vm/code/relocInfo.hpp	Wed Oct 05 15:20:35 2016 +0200
@@ -270,7 +270,7 @@
     poll_return_type        = 11, // polling instruction for safepoints at return
     metadata_type           = 12, // metadata that used to be oops
     trampoline_stub_type    = 13, // stub-entry for trampoline
-    yet_unused_type_1       = 14, // Still unused
+    runtime_call_w_cp_type  = 14, // Runtime call which may load its target from the constant pool
     data_prefix_tag         = 15, // tag for a prefix (carries data arguments)
     type_mask               = 15  // A mask which selects only the above values
   };
@@ -305,6 +305,7 @@
     visitor(static_call) \
     visitor(static_stub) \
     visitor(runtime_call) \
+    visitor(runtime_call_w_cp) \
     visitor(external_word) \
     visitor(internal_word) \
     visitor(poll) \
@@ -827,8 +828,6 @@
   // ic_call_type is not always posisition dependent (depending on the state of the cache)). However, this is
   // probably a reasonable assumption, since empty caches simplifies code reloacation.
   virtual void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { }
-
-  void print();
 };
 
 
@@ -1175,6 +1174,36 @@
  public:
 };
 
+
+class runtime_call_w_cp_Relocation : public CallRelocation {
+  relocInfo::relocType type() { return relocInfo::runtime_call_w_cp_type; }
+
+ public:
+  static RelocationHolder spec() {
+    RelocationHolder rh = newHolder();
+    new(rh) runtime_call_w_cp_Relocation();
+    return rh;
+  }
+
+ private:
+  friend class RelocIterator;
+  runtime_call_w_cp_Relocation() { _offset = -4; /* <0 = invalid */ }
+  // On z/Architecture, runtime calls are either a sequence
+  // of two instructions (load destination of call from constant pool + do call)
+  // or a pc-relative call. The pc-relative call is faster, but it can only
+  // be used if the destination of the call is not too far away.
+  // In order to be able to patch a pc-relative call back into one using
+  // the constant pool, we have to remember the location of the call's destination
+  // in the constant pool.
+  int _offset;
+
+ public:
+  void set_constant_pool_offset(int offset) { _offset = offset; }
+  int get_constant_pool_offset() { return _offset; }
+  void pack_data_to(CodeSection * dest);
+  void unpack_data();
+};
+
 // Trampoline Relocations.
 // A trampoline allows to encode a small branch in the code, even if there
 // is the chance that this branch can not reach all possible code locations.