changeset 60424:fec7d7b39038

8240669: Devirtualize Relocation::type Reviewed-by: rbackman, thartmann
author redestad
date Thu, 05 Mar 2020 16:07:17 +0100
parents 4923c49ba7b5
children 2d4a9ff1de2e
files src/hotspot/share/code/relocInfo.cpp src/hotspot/share/code/relocInfo.hpp
diffstat 2 files changed, 63 insertions(+), 84 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/share/code/relocInfo.cpp	Thu Mar 12 13:07:21 2020 +0100
+++ b/src/hotspot/share/code/relocInfo.cpp	Thu Mar 05 16:07:17 2020 +0100
@@ -231,7 +231,7 @@
   APPLY_TO_RELOCATIONS(EACH_TYPE);
   #undef EACH_TYPE
   assert(t == relocInfo::none, "must be padding");
-  return new(_rh) Relocation();
+  return new(_rh) Relocation(t);
 }
 
 
@@ -260,12 +260,7 @@
   return (*this);
 }
 
-
-void Relocation::guarantee_size() {
-  guarantee(false, "Make _relocbuf bigger!");
-}
-
-    // some relocations can compute their own values
+// some relocations can compute their own values
 address Relocation::value() {
   ShouldNotReachHere();
   return NULL;
--- a/src/hotspot/share/code/relocInfo.hpp	Thu Mar 12 13:07:21 2020 +0100
+++ b/src/hotspot/share/code/relocInfo.hpp	Thu Mar 05 16:07:17 2020 +0100
@@ -515,9 +515,10 @@
 //   }
 
 class RelocIterator : public StackObj {
+  friend class section_word_Relocation; // for section verification
   enum { SECT_LIMIT = 3 };  // must be equal to CodeBuffer::SECT_LIMIT, checked in ctor
   friend class Relocation;
-  friend class relocInfo;       // for change_reloc_info_for_address only
+  friend class relocInfo;   // for change_reloc_info_for_address only
   typedef relocInfo::relocType relocType;
 
  private:
@@ -637,13 +638,13 @@
   friend class RelocIterator;
 
  private:
-  static void guarantee_size();
-
   // When a relocation has been created by a RelocIterator,
   // this field is non-null.  It allows the relocation to know
   // its context, such as the address to which it applies.
   RelocIterator* _binding;
 
+  relocInfo::relocType _rtype;
+
  protected:
   RelocIterator* binding() const {
     assert(_binding != NULL, "must be bound");
@@ -655,9 +656,7 @@
     assert(_binding != NULL, "must now be bound");
   }
 
-  Relocation() {
-    _binding = NULL;
-  }
+  Relocation(relocInfo::relocType rtype) : _binding(NULL), _rtype(rtype) { }
 
   static RelocationHolder newHolder() {
     return RelocationHolder();
@@ -665,7 +664,7 @@
 
  public:
   void* operator new(size_t size, const RelocationHolder& holder) throw() {
-    if (size > sizeof(holder._relocbuf)) guarantee_size();
+    assert(size <= sizeof(holder._relocbuf), "Make _relocbuf bigger!");
     assert((void* const *)holder.reloc() == &holder._relocbuf[0], "ptrs must agree");
     return holder.reloc();
   }
@@ -792,7 +791,7 @@
   int      format()       const { return binding()->format(); }
 
  public:
-  virtual relocInfo::relocType type()            { return relocInfo::none; }
+  relocInfo::relocType type()              const { return _rtype; }
 
   // is it a call instruction?
   virtual bool is_call()                         { return false; }
@@ -819,7 +818,7 @@
 
 inline RelocationHolder::RelocationHolder() {
   // initialize the vtbl, just to keep things type-safe
-  new(*this) Relocation();
+  new(*this) Relocation(relocInfo::none);
 }
 
 
@@ -830,7 +829,6 @@
   }
 }
 
-
 relocInfo::relocType RelocationHolder::type() const {
   return reloc()->type();
 }
@@ -841,6 +839,8 @@
 // By convention, the "value" does not include a separately reckoned "offset".
 class DataRelocation : public Relocation {
  public:
+  DataRelocation(relocInfo::relocType type) : Relocation(type) {}
+
   bool          is_data()                      { return true; }
 
   // both target and offset must be computed somehow from relocation data
@@ -877,6 +877,8 @@
 // It is PC-relative on most machines.
 class CallRelocation : public Relocation {
  public:
+  CallRelocation(relocInfo::relocType type) : Relocation(type) { }
+
   bool is_call() { return true; }
 
   address  destination()                    { return pd_call_destination(); }
@@ -888,8 +890,6 @@
 };
 
 class oop_Relocation : public DataRelocation {
-  relocInfo::relocType type() { return relocInfo::oop_type; }
-
  public:
   // encode in one of these formats:  [] [n] [n l] [Nn l] [Nn Ll]
   // an oop in the CodeBlob's oop pool
@@ -916,12 +916,11 @@
   jint _oop_index;                  // if > 0, index into CodeBlob::oop_at
   jint _offset;                     // byte offset to apply to the oop itself
 
-  oop_Relocation(int oop_index, int offset) {
-    _oop_index = oop_index; _offset = offset;
-  }
+  oop_Relocation(int oop_index, int offset)
+    : DataRelocation(relocInfo::oop_type), _oop_index(oop_index), _offset(offset) { }
 
   friend class RelocIterator;
-  oop_Relocation() { }
+  oop_Relocation() : DataRelocation(relocInfo::oop_type) {}
 
  public:
   int oop_index() { return _oop_index; }
@@ -947,7 +946,6 @@
 
 // copy of oop_Relocation for now but may delete stuff in both/either
 class metadata_Relocation : public DataRelocation {
-  relocInfo::relocType type() { return relocInfo::metadata_type; }
 
  public:
   // encode in one of these formats:  [] [n] [n l] [Nn l] [Nn Ll]
@@ -971,12 +969,11 @@
   jint _metadata_index;            // if > 0, index into nmethod::metadata_at
   jint _offset;                     // byte offset to apply to the metadata itself
 
-  metadata_Relocation(int metadata_index, int offset) {
-    _metadata_index = metadata_index; _offset = offset;
-  }
+  metadata_Relocation(int metadata_index, int offset)
+    : DataRelocation(relocInfo::metadata_type), _metadata_index(metadata_index), _offset(offset) { }
 
   friend class RelocIterator;
-  metadata_Relocation() { }
+  metadata_Relocation() : DataRelocation(relocInfo::metadata_type) { }
 
   // Fixes a Metadata pointer in the code. Most platforms embeds the
   // Metadata pointer in the code at compile time so this is empty
@@ -1004,7 +1001,6 @@
 
 
 class virtual_call_Relocation : public CallRelocation {
-  relocInfo::relocType type() { return relocInfo::virtual_call_type; }
 
  public:
   // "cached_value" points to the first associated set-oop.
@@ -1020,14 +1016,15 @@
   address _cached_value; // location of set-value instruction
   jint    _method_index; // resolved method for a Java call
 
-  virtual_call_Relocation(address cached_value, int method_index) {
-    _cached_value = cached_value;
-    _method_index = method_index;
+  virtual_call_Relocation(address cached_value, int method_index)
+    : CallRelocation(relocInfo::virtual_call_type),
+      _cached_value(cached_value),
+      _method_index(method_index) {
     assert(cached_value != NULL, "first oop address must be specified");
   }
 
   friend class RelocIterator;
-  virtual_call_Relocation() { }
+  virtual_call_Relocation() : CallRelocation(relocInfo::virtual_call_type) { }
 
  public:
   address cached_value();
@@ -1047,8 +1044,6 @@
 
 
 class opt_virtual_call_Relocation : public CallRelocation {
-  relocInfo::relocType type() { return relocInfo::opt_virtual_call_type; }
-
  public:
   static RelocationHolder spec(int method_index = 0) {
     RelocationHolder rh = newHolder();
@@ -1059,12 +1054,12 @@
  private:
   jint _method_index; // resolved method for a Java call
 
-  opt_virtual_call_Relocation(int method_index) {
-    _method_index = method_index;
-  }
+  opt_virtual_call_Relocation(int method_index)
+    : CallRelocation(relocInfo::opt_virtual_call_type),
+      _method_index(method_index) { }
 
   friend class RelocIterator;
-  opt_virtual_call_Relocation() {}
+  opt_virtual_call_Relocation() : CallRelocation(relocInfo::opt_virtual_call_type) {}
 
  public:
   int     method_index() { return _method_index; }
@@ -1081,8 +1076,6 @@
 
 
 class static_call_Relocation : public CallRelocation {
-  relocInfo::relocType type() { return relocInfo::static_call_type; }
-
  public:
   static RelocationHolder spec(int method_index = 0) {
     RelocationHolder rh = newHolder();
@@ -1093,12 +1086,12 @@
  private:
   jint _method_index; // resolved method for a Java call
 
-  static_call_Relocation(int method_index) {
-    _method_index = method_index;
-  }
+  static_call_Relocation(int method_index)
+    : CallRelocation(relocInfo::static_call_type),
+    _method_index(method_index) { }
 
   friend class RelocIterator;
-  static_call_Relocation() {}
+  static_call_Relocation() : CallRelocation(relocInfo::static_call_type) {}
 
  public:
   int     method_index() { return _method_index; }
@@ -1114,8 +1107,6 @@
 };
 
 class static_stub_Relocation : public Relocation {
-  relocInfo::relocType type() { return relocInfo::static_stub_type; }
-
  public:
   static RelocationHolder spec(address static_call, bool is_aot = false) {
     RelocationHolder rh = newHolder();
@@ -1127,13 +1118,12 @@
   address _static_call;  // location of corresponding static_call
   bool _is_aot;          // trampoline to aot code
 
-  static_stub_Relocation(address static_call, bool is_aot) {
-    _static_call = static_call;
-    _is_aot = is_aot;
-  }
+  static_stub_Relocation(address static_call, bool is_aot)
+    : Relocation(relocInfo::static_stub_type),
+      _static_call(static_call), _is_aot(is_aot) { }
 
   friend class RelocIterator;
-  static_stub_Relocation() { }
+  static_stub_Relocation() : Relocation(relocInfo::static_stub_type) { }
 
  public:
   bool clear_inline_cache();
@@ -1147,7 +1137,6 @@
 };
 
 class runtime_call_Relocation : public CallRelocation {
-  relocInfo::relocType type() { return relocInfo::runtime_call_type; }
 
  public:
   static RelocationHolder spec() {
@@ -1158,15 +1147,13 @@
 
  private:
   friend class RelocIterator;
-  runtime_call_Relocation() { }
+  runtime_call_Relocation() : CallRelocation(relocInfo::runtime_call_type) { }
 
  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();
@@ -1176,7 +1163,10 @@
 
  private:
   friend class RelocIterator;
-  runtime_call_w_cp_Relocation() { _offset = -4; /* <0 = invalid */ }
+  runtime_call_w_cp_Relocation()
+    : CallRelocation(relocInfo::runtime_call_w_cp_type),
+      _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
@@ -1200,8 +1190,6 @@
 // in the code, it can patch it to jump to the trampoline where is
 // sufficient space for a far branch. Needed on PPC.
 class trampoline_stub_Relocation : public Relocation {
-  relocInfo::relocType type() { return relocInfo::trampoline_stub_type; }
-
  public:
   static RelocationHolder spec(address static_call) {
     RelocationHolder rh = newHolder();
@@ -1211,12 +1199,12 @@
  private:
   address _owner;    // Address of the NativeCall that owns the trampoline.
 
-  trampoline_stub_Relocation(address owner) {
-    _owner = owner;
-  }
+  trampoline_stub_Relocation(address owner)
+    : Relocation(relocInfo::trampoline_stub_type),
+      _owner(owner) { }
 
   friend class RelocIterator;
-  trampoline_stub_Relocation() { }
+  trampoline_stub_Relocation() : Relocation(relocInfo::trampoline_stub_type) { }
 
  public:
 
@@ -1231,8 +1219,6 @@
 };
 
 class external_word_Relocation : public DataRelocation {
-  relocInfo::relocType type() { return relocInfo::external_word_type; }
-
  public:
   static RelocationHolder spec(address target) {
     assert(target != NULL, "must not be null");
@@ -1259,12 +1245,11 @@
  private:
   address _target;                  // address in runtime
 
-  external_word_Relocation(address target) {
-    _target = target;
-  }
+  external_word_Relocation(address target)
+    : DataRelocation(relocInfo::external_word_type), _target(target) { }
 
   friend class RelocIterator;
-  external_word_Relocation() { }
+  external_word_Relocation() : DataRelocation(relocInfo::external_word_type) { }
 
  public:
   // data is packed as a well-known address in "1_int" format:  [a] or [Aa]
@@ -1281,7 +1266,6 @@
 };
 
 class internal_word_Relocation : public DataRelocation {
-  relocInfo::relocType type() { return relocInfo::internal_word_type; }
 
  public:
   static RelocationHolder spec(address target) {
@@ -1298,17 +1282,18 @@
     return rh;
   }
 
-  internal_word_Relocation(address target) {
-    _target  = target;
-    _section = -1;  // self-relative
-  }
+  // default section -1 means self-relative
+  internal_word_Relocation(address target, int section = -1,
+    relocInfo::relocType type = relocInfo::internal_word_type)
+    : DataRelocation(type), _target(target), _section(section) { }
 
  protected:
   address _target;                  // address in CodeBlob
   int     _section;                 // section providing base address, if any
 
   friend class RelocIterator;
-  internal_word_Relocation() { }
+  internal_word_Relocation(relocInfo::relocType type = relocInfo::internal_word_type)
+    : DataRelocation(type) { }
 
   // bit-width of LSB field in packed offset, if section >= 0
   enum { section_width = 2 }; // must equal CodeBuffer::sect_bits
@@ -1328,8 +1313,6 @@
 };
 
 class section_word_Relocation : public internal_word_Relocation {
-  relocInfo::relocType type() { return relocInfo::section_word_type; }
-
  public:
   static RelocationHolder spec(address target, int section) {
     RelocationHolder rh = newHolder();
@@ -1337,11 +1320,10 @@
     return rh;
   }
 
-  section_word_Relocation(address target, int section) {
+  section_word_Relocation(address target, int section)
+    : internal_word_Relocation(target, section, relocInfo::section_word_type) {
     assert(target != NULL, "must not be null");
-    assert(section >= 0, "must be a valid section");
-    _target  = target;
-    _section = section;
+    assert(section >= 0 && section < RelocIterator::SECT_LIMIT, "must be a valid section");
   }
 
   //void pack_data_to -- inherited
@@ -1349,18 +1331,20 @@
 
  private:
   friend class RelocIterator;
-  section_word_Relocation() { }
+  section_word_Relocation() : internal_word_Relocation(relocInfo::section_word_type) { }
 };
 
 
 class poll_Relocation : public Relocation {
   bool          is_data()                      { return true; }
-  relocInfo::relocType type() { return relocInfo::poll_type; }
   void     fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest);
+ public:
+  poll_Relocation(relocInfo::relocType type = relocInfo::poll_type) : Relocation(type) { }
 };
 
 class poll_return_Relocation : public poll_Relocation {
-  relocInfo::relocType type() { return relocInfo::poll_return_type; }
+ public:
+  poll_return_Relocation() : poll_Relocation(relocInfo::relocInfo::poll_return_type) { }
 };
 
 // We know all the xxx_Relocation classes, so now we can define these: