< prev index next >

src/hotspot/share/code/relocInfo.hpp

Print this page

 434  protected:
 435   // Derived constant, based on format_width which is PD:
 436   enum {
 437     offset_width       = nontype_width - format_width,
 438     offset_mask        = (1<<offset_width) - 1,
 439     format_mask        = (1<<format_width) - 1
 440   };
 441  public:
 442   enum {
 443 #ifdef _LP64
 444     // for use in format
 445     // format_width must be at least 1 on _LP64
 446     narrow_oop_in_const = 1,
 447 #endif
 448     // Conservatively large estimate of maximum length (in shorts)
 449     // of any relocation record.
 450     // Extended format is length prefix, data words, and tag/offset suffix.
 451     length_limit       = 1 + 1 + (3*BytesPerWord/BytesPerShort) + 1,
 452     have_format        = format_width > 0
 453   };


 454 };
 455 
 456 #define FORWARD_DECLARE_EACH_CLASS(name)              \
 457 class name##_Relocation;
 458 APPLY_TO_RELOCATIONS(FORWARD_DECLARE_EACH_CLASS)
 459 #undef FORWARD_DECLARE_EACH_CLASS
 460 
 461 // Holder for flyweight relocation objects.
 462 // Although the flyweight subclasses are of varying sizes,
 463 // the holder is "one size fits all".
 464 class RelocationHolder {
 465   friend class Relocation;
 466 
 467  private:
 468   // A Relocation is "held" by placement constructing a Relocation into
 469   // _relocbuf. Hence, _relocbuf must accomodate all subclasses of
 470   // Relocation. We also need the Relocation base class to be at the same
 471   // address as the start of the object, e.g. at the address of _relocbuf.
 472   // Both of these requirements are checked (see emplace_relocation).
 473   // The placement of the base class subobject isn't guaranteed by C++, since

 621     if (_limit != nullptr && _addr >= _limit) {
 622       set_has_current(false);
 623       return false;
 624     }
 625 
 626     return true;
 627   }
 628 
 629   // accessors
 630   address      limit()        const { return _limit; }
 631   relocType    type()         const { return current()->type(); }
 632   int          format()       const { return (relocInfo::have_format) ? current()->format() : 0; }
 633   address      addr()         const { return _addr; }
 634   nmethod*     code()         const { return _code; }
 635   short*       data()         const { return _data; }
 636   int          datalen()      const { return _datalen; }
 637   bool     has_current()      const { return _datalen >= 0; }
 638   bool   addr_in_const()      const;
 639 
 640   address section_start(int n) const {
 641     assert(_section_start[n], "must be initialized");
 642     return _section_start[n];
 643   }
 644   address section_end(int n) const {
 645     assert(_section_end[n], "must be initialized");
 646     return _section_end[n];
 647   }
 648 
 649   // The address points to the affected displacement part of the instruction.
 650   // For RISC, this is just the whole instruction.
 651   // For Intel, this is an unaligned 32-bit word.
 652 
 653   // type-specific relocation accessors:  oop_Relocation* oop_reloc(), etc.
 654   #define EACH_TYPE(name)                               \
 655   inline name##_Relocation* name##_reloc();
 656   APPLY_TO_RELOCATIONS(EACH_TYPE)
 657   #undef EACH_TYPE
 658   // generic relocation accessor; switches on type to call the above
 659   Relocation* reloc();
 660 
 661 #ifndef PRODUCT
 662  public:
 663   void print();
 664   void print_current();
 665 #endif
 666 };
 667 
 668 
 669 // A Relocation is a flyweight object allocated within a RelocationHolder.
 670 // It represents the relocation data of relocation record.
 671 // So, the RelocIterator unpacks relocInfos into Relocations.
 672 
 673 class Relocation {
 674   friend class RelocIterator;
 675 
 676  private:
 677   // When a relocation has been created by a RelocIterator,
 678   // this field is non-null.  It allows the relocation to know
 679   // its context, such as the address to which it applies.
 680   RelocIterator* _binding;
 681 
 682   relocInfo::relocType _rtype;
 683 
 684  protected:
 685   RelocIterator* binding() const {

1265 
1266   void copy_into(RelocationHolder& holder) const override;
1267 
1268  private:
1269   address _owner;    // Address of the NativeCall that owns the trampoline.
1270 
1271   trampoline_stub_Relocation(address owner)
1272     : Relocation(relocInfo::trampoline_stub_type),
1273       _owner(owner) { }
1274 
1275   friend class RelocationHolder;
1276   trampoline_stub_Relocation() : Relocation(relocInfo::trampoline_stub_type) { }
1277 
1278  public:
1279 
1280   // Return the address of the NativeCall that owns the trampoline.
1281   address owner() { return _owner; }
1282 
1283   void pack_data_to(CodeSection * dest) override;
1284   void unpack_data() override;



















1285 
1286   // Find the trampoline stub for a call.
1287   static address get_trampoline_for(address call, nmethod* code);
1288 };
1289 
1290 class external_word_Relocation : public DataRelocation {
1291  public:
1292   static RelocationHolder spec(address target) {
1293     assert(target != nullptr, "must not be null");
1294     return RelocationHolder::construct<external_word_Relocation>(target);
1295   }
1296 
1297   // Use this one where all 32/64 bits of the target live in the code stream.
1298   // The target must be an intptr_t, and must be absolute (not relative).
1299   static RelocationHolder spec_for_immediate() {
1300     return RelocationHolder::construct<external_word_Relocation>(nullptr);
1301   }
1302 
1303   void copy_into(RelocationHolder& holder) const override;
1304 

1309     return target != nullptr;
1310   }
1311 
1312  private:
1313   address _target;                  // address in runtime
1314 
1315   external_word_Relocation(address target)
1316     : DataRelocation(relocInfo::external_word_type), _target(target) { }
1317 
1318   friend class RelocationHolder;
1319   external_word_Relocation() : DataRelocation(relocInfo::external_word_type) { }
1320 
1321  public:
1322   // data is packed as a well-known address in "1_int" format:  [a] or [Aa]
1323   // The function runtime_address_to_index is used to turn full addresses
1324   // to short indexes, if they are pre-registered by the stub mechanism.
1325   // If the "a" value is 0 (i.e., _target is nullptr), the address is stored
1326   // in the code stream.  See external_word_Relocation::target().
1327   void pack_data_to(CodeSection* dest) override;
1328   void unpack_data() override;

1329 
1330   void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) override;
1331   address  target();        // if _target==nullptr, fetch addr from code stream
1332   address  value() override { return target(); }
1333 };
1334 
1335 class internal_word_Relocation : public DataRelocation {
1336 
1337  public:
1338   static RelocationHolder spec(address target) {
1339     assert(target != nullptr, "must not be null");
1340     return RelocationHolder::construct<internal_word_Relocation>(target);
1341   }
1342 
1343   // use this one where all the bits of the target can fit in the code stream:
1344   static RelocationHolder spec_for_immediate() {
1345     return RelocationHolder::construct<internal_word_Relocation>(nullptr);
1346   }
1347 
1348   void copy_into(RelocationHolder& holder) const override;

 434  protected:
 435   // Derived constant, based on format_width which is PD:
 436   enum {
 437     offset_width       = nontype_width - format_width,
 438     offset_mask        = (1<<offset_width) - 1,
 439     format_mask        = (1<<format_width) - 1
 440   };
 441  public:
 442   enum {
 443 #ifdef _LP64
 444     // for use in format
 445     // format_width must be at least 1 on _LP64
 446     narrow_oop_in_const = 1,
 447 #endif
 448     // Conservatively large estimate of maximum length (in shorts)
 449     // of any relocation record.
 450     // Extended format is length prefix, data words, and tag/offset suffix.
 451     length_limit       = 1 + 1 + (3*BytesPerWord/BytesPerShort) + 1,
 452     have_format        = format_width > 0
 453   };
 454 
 455   static const char* type_name(relocInfo::relocType t);
 456 };
 457 
 458 #define FORWARD_DECLARE_EACH_CLASS(name)              \
 459 class name##_Relocation;
 460 APPLY_TO_RELOCATIONS(FORWARD_DECLARE_EACH_CLASS)
 461 #undef FORWARD_DECLARE_EACH_CLASS
 462 
 463 // Holder for flyweight relocation objects.
 464 // Although the flyweight subclasses are of varying sizes,
 465 // the holder is "one size fits all".
 466 class RelocationHolder {
 467   friend class Relocation;
 468 
 469  private:
 470   // A Relocation is "held" by placement constructing a Relocation into
 471   // _relocbuf. Hence, _relocbuf must accomodate all subclasses of
 472   // Relocation. We also need the Relocation base class to be at the same
 473   // address as the start of the object, e.g. at the address of _relocbuf.
 474   // Both of these requirements are checked (see emplace_relocation).
 475   // The placement of the base class subobject isn't guaranteed by C++, since

 623     if (_limit != nullptr && _addr >= _limit) {
 624       set_has_current(false);
 625       return false;
 626     }
 627 
 628     return true;
 629   }
 630 
 631   // accessors
 632   address      limit()        const { return _limit; }
 633   relocType    type()         const { return current()->type(); }
 634   int          format()       const { return (relocInfo::have_format) ? current()->format() : 0; }
 635   address      addr()         const { return _addr; }
 636   nmethod*     code()         const { return _code; }
 637   short*       data()         const { return _data; }
 638   int          datalen()      const { return _datalen; }
 639   bool     has_current()      const { return _datalen >= 0; }
 640   bool   addr_in_const()      const;
 641 
 642   address section_start(int n) const {
 643     assert(_section_start[n], "section %d must be initialized", n);
 644     return _section_start[n];
 645   }
 646   address section_end(int n) const {
 647     assert(_section_end[n], "section %d must be initialized", n);
 648     return _section_end[n];
 649   }
 650 
 651   // The address points to the affected displacement part of the instruction.
 652   // For RISC, this is just the whole instruction.
 653   // For Intel, this is an unaligned 32-bit word.
 654 
 655   // type-specific relocation accessors:  oop_Relocation* oop_reloc(), etc.
 656   #define EACH_TYPE(name)                               \
 657   inline name##_Relocation* name##_reloc();
 658   APPLY_TO_RELOCATIONS(EACH_TYPE)
 659   #undef EACH_TYPE
 660   // generic relocation accessor; switches on type to call the above
 661   Relocation* reloc();
 662 

 663  public:
 664   void print_on(outputStream* st);
 665   void print_current_on(outputStream* st);

 666 };
 667 
 668 
 669 // A Relocation is a flyweight object allocated within a RelocationHolder.
 670 // It represents the relocation data of relocation record.
 671 // So, the RelocIterator unpacks relocInfos into Relocations.
 672 
 673 class Relocation {
 674   friend class RelocIterator;
 675 
 676  private:
 677   // When a relocation has been created by a RelocIterator,
 678   // this field is non-null.  It allows the relocation to know
 679   // its context, such as the address to which it applies.
 680   RelocIterator* _binding;
 681 
 682   relocInfo::relocType _rtype;
 683 
 684  protected:
 685   RelocIterator* binding() const {

1265 
1266   void copy_into(RelocationHolder& holder) const override;
1267 
1268  private:
1269   address _owner;    // Address of the NativeCall that owns the trampoline.
1270 
1271   trampoline_stub_Relocation(address owner)
1272     : Relocation(relocInfo::trampoline_stub_type),
1273       _owner(owner) { }
1274 
1275   friend class RelocationHolder;
1276   trampoline_stub_Relocation() : Relocation(relocInfo::trampoline_stub_type) { }
1277 
1278  public:
1279 
1280   // Return the address of the NativeCall that owns the trampoline.
1281   address owner() { return _owner; }
1282 
1283   void pack_data_to(CodeSection * dest) override;
1284   void unpack_data() override;
1285 #if defined(AARCH64)
1286   address    pd_destination     ();
1287   void       pd_set_destination (address x);
1288 #endif
1289   address  destination() {
1290 #if defined(AARCH64)
1291     return pd_destination();
1292 #else
1293     fatal("trampoline_stub_Relocation::destination() unimplemented");
1294     return (address)-1;
1295 #endif
1296   }
1297   void     set_destination(address x) {
1298 #if defined(AARCH64)
1299     pd_set_destination(x);
1300 #else
1301     fatal("trampoline_stub_Relocation::set_destination() unimplemented");
1302 #endif
1303   }
1304 
1305   // Find the trampoline stub for a call.
1306   static address get_trampoline_for(address call, nmethod* code);
1307 };
1308 
1309 class external_word_Relocation : public DataRelocation {
1310  public:
1311   static RelocationHolder spec(address target) {
1312     assert(target != nullptr, "must not be null");
1313     return RelocationHolder::construct<external_word_Relocation>(target);
1314   }
1315 
1316   // Use this one where all 32/64 bits of the target live in the code stream.
1317   // The target must be an intptr_t, and must be absolute (not relative).
1318   static RelocationHolder spec_for_immediate() {
1319     return RelocationHolder::construct<external_word_Relocation>(nullptr);
1320   }
1321 
1322   void copy_into(RelocationHolder& holder) const override;
1323 

1328     return target != nullptr;
1329   }
1330 
1331  private:
1332   address _target;                  // address in runtime
1333 
1334   external_word_Relocation(address target)
1335     : DataRelocation(relocInfo::external_word_type), _target(target) { }
1336 
1337   friend class RelocationHolder;
1338   external_word_Relocation() : DataRelocation(relocInfo::external_word_type) { }
1339 
1340  public:
1341   // data is packed as a well-known address in "1_int" format:  [a] or [Aa]
1342   // The function runtime_address_to_index is used to turn full addresses
1343   // to short indexes, if they are pre-registered by the stub mechanism.
1344   // If the "a" value is 0 (i.e., _target is nullptr), the address is stored
1345   // in the code stream.  See external_word_Relocation::target().
1346   void pack_data_to(CodeSection* dest) override;
1347   void unpack_data() override;
1348   short* pack_data_to(short* p); // Pack address into buffer
1349 
1350   void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) override;
1351   address  target();        // if _target==nullptr, fetch addr from code stream
1352   address  value() override { return target(); }
1353 };
1354 
1355 class internal_word_Relocation : public DataRelocation {
1356 
1357  public:
1358   static RelocationHolder spec(address target) {
1359     assert(target != nullptr, "must not be null");
1360     return RelocationHolder::construct<internal_word_Relocation>(target);
1361   }
1362 
1363   // use this one where all the bits of the target can fit in the code stream:
1364   static RelocationHolder spec_for_immediate() {
1365     return RelocationHolder::construct<internal_word_Relocation>(nullptr);
1366   }
1367 
1368   void copy_into(RelocationHolder& holder) const override;
< prev index next >