< prev index next >

src/hotspot/share/code/relocInfo.hpp

Print this page

   1 /*
   2  * Copyright (c) 1997, 2025, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *

 250   friend class RelocIterator;
 251  public:
 252   enum relocType {
 253     none                    =  0, // Used when no relocation should be generated
 254     oop_type                =  1, // embedded oop
 255     virtual_call_type       =  2, // a standard inline cache call for a virtual send
 256     opt_virtual_call_type   =  3, // a virtual call that has been statically bound (i.e., no IC cache)
 257     static_call_type        =  4, // a static send
 258     static_stub_type        =  5, // stub-entry for static send  (takes care of interpreter case)
 259     runtime_call_type       =  6, // call to fixed external routine
 260     external_word_type      =  7, // reference to fixed external address
 261     internal_word_type      =  8, // reference within the current code blob
 262     section_word_type       =  9, // internal, but a cross-section reference
 263     poll_type               = 10, // polling instruction for safepoints
 264     poll_return_type        = 11, // polling instruction for safepoints at return
 265     metadata_type           = 12, // metadata that used to be oops
 266     trampoline_stub_type    = 13, // stub-entry for trampoline
 267     runtime_call_w_cp_type  = 14, // Runtime call which may load its target from the constant pool
 268     data_prefix_tag         = 15, // tag for a prefix (carries data arguments)
 269     post_call_nop_type      = 16, // A tag for post call nop relocations
 270     entry_guard_type        = 17, // A tag for an nmethod entry barrier guard value
 271     barrier_type            = 18, // GC barrier data
 272     type_mask               = 31  // A mask which selects only the above values
 273   };
 274 
 275  private:
 276   unsigned short _value;
 277 
 278   static const enum class RawBitsToken {} RAW_BITS{};
 279 
 280   relocInfo(relocType type, RawBitsToken, int bits)
 281     : _value(checked_cast<unsigned short>((type << nontype_width) + bits)) { }
 282 
 283   static relocType check_relocType(relocType type) NOT_DEBUG({ return type; });
 284 
 285   static void check_offset_and_format(int offset, int format) NOT_DEBUG_RETURN;
 286 
 287   static int compute_bits(int offset, int format) {
 288     check_offset_and_format(offset, format);
 289     return (offset / offset_unit) + (format << offset_width);
 290   }
 291 
 292  public:
 293   relocInfo(relocType type, int offset, int format = 0)
 294     : relocInfo(check_relocType(type), RAW_BITS, compute_bits(offset, format)) {}
 295 
 296   #define APPLY_TO_RELOCATIONS(visitor) \
 297     visitor(oop) \
 298     visitor(metadata) \
 299     visitor(virtual_call) \
 300     visitor(opt_virtual_call) \
 301     visitor(static_call) \
 302     visitor(static_stub) \
 303     visitor(runtime_call) \
 304     visitor(runtime_call_w_cp) \
 305     visitor(external_word) \
 306     visitor(internal_word) \
 307     visitor(poll) \
 308     visitor(poll_return) \
 309     visitor(section_word) \
 310     visitor(trampoline_stub) \
 311     visitor(post_call_nop) \
 312     visitor(entry_guard) \
 313     visitor(barrier) \
 314 
 315 
 316  public:
 317   enum : unsigned short{
 318     value_width             = sizeof(unsigned short) * BitsPerByte,
 319     type_width              = 5,   // == log2(type_mask+1)
 320     nontype_width           = value_width - type_width,
 321     datalen_width           = nontype_width-1,
 322     datalen_tag             = 1 << datalen_width,  // or-ed into _value
 323     datalen_limit           = 1 << datalen_width,
 324     datalen_mask            = (1 << datalen_width)-1
 325   };
 326 
 327   // accessors
 328  public:
 329   relocType  type()       const { return (relocType)((unsigned)_value >> nontype_width); }
 330   int  format()           const { return format_mask==0? 0: format_mask &
 331                                          ((unsigned)_value >> offset_width); }
 332   int  addr_offset()      const { assert(!is_prefix(), "must have offset");

 907       const_verify_data_value(x);
 908     } else {
 909       pd_verify_data_value(x);
 910     }
 911   }
 912 };
 913 
 914 class post_call_nop_Relocation : public Relocation {
 915   friend class RelocationHolder;
 916 
 917 public:
 918   post_call_nop_Relocation() : Relocation(relocInfo::post_call_nop_type) { }
 919 
 920   static RelocationHolder spec() {
 921     return RelocationHolder::construct<post_call_nop_Relocation>();
 922   }
 923 
 924   void copy_into(RelocationHolder& holder) const override;
 925 };
 926 
 927 class entry_guard_Relocation : public Relocation {
 928   friend class RelocationHolder;
 929 
 930 public:
 931   entry_guard_Relocation() : Relocation(relocInfo::entry_guard_type) { }
 932 
 933   static RelocationHolder spec() {
 934     return RelocationHolder::construct<entry_guard_Relocation>();
 935   }
 936 
 937   void copy_into(RelocationHolder& holder) const override;
 938 };
 939 
 940 // A CallRelocation always points at a call instruction.
 941 // It is PC-relative on most machines.
 942 class CallRelocation : public Relocation {
 943  public:
 944   CallRelocation(relocInfo::relocType type) : Relocation(type) { }
 945 
 946   bool is_call() override { return true; }
 947 
 948   address  destination()                    { return pd_call_destination(); }
 949   void     set_destination(address x); // pd_set_call_destination
 950 
 951   void     fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) override;
 952   address  value() override                 { return destination();  }
 953   void     set_value(address x) override    { set_destination(x); }
 954 };
 955 
 956 class oop_Relocation : public DataRelocation {
 957  public:
 958   // an oop in the CodeBlob's oop pool; encoded as [n] or [Nn]
 959   static RelocationHolder spec(int oop_index) {

   1 /*
   2  * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *

 250   friend class RelocIterator;
 251  public:
 252   enum relocType {
 253     none                    =  0, // Used when no relocation should be generated
 254     oop_type                =  1, // embedded oop
 255     virtual_call_type       =  2, // a standard inline cache call for a virtual send
 256     opt_virtual_call_type   =  3, // a virtual call that has been statically bound (i.e., no IC cache)
 257     static_call_type        =  4, // a static send
 258     static_stub_type        =  5, // stub-entry for static send  (takes care of interpreter case)
 259     runtime_call_type       =  6, // call to fixed external routine
 260     external_word_type      =  7, // reference to fixed external address
 261     internal_word_type      =  8, // reference within the current code blob
 262     section_word_type       =  9, // internal, but a cross-section reference
 263     poll_type               = 10, // polling instruction for safepoints
 264     poll_return_type        = 11, // polling instruction for safepoints at return
 265     metadata_type           = 12, // metadata that used to be oops
 266     trampoline_stub_type    = 13, // stub-entry for trampoline
 267     runtime_call_w_cp_type  = 14, // Runtime call which may load its target from the constant pool
 268     data_prefix_tag         = 15, // tag for a prefix (carries data arguments)
 269     post_call_nop_type      = 16, // A tag for post call nop relocations
 270     barrier_type            = 17, // GC barrier data

 271     type_mask               = 31  // A mask which selects only the above values
 272   };
 273 
 274  private:
 275   unsigned short _value;
 276 
 277   static const enum class RawBitsToken {} RAW_BITS{};
 278 
 279   relocInfo(relocType type, RawBitsToken, int bits)
 280     : _value(checked_cast<unsigned short>((type << nontype_width) + bits)) { }
 281 
 282   static relocType check_relocType(relocType type) NOT_DEBUG({ return type; });
 283 
 284   static void check_offset_and_format(int offset, int format) NOT_DEBUG_RETURN;
 285 
 286   static int compute_bits(int offset, int format) {
 287     check_offset_and_format(offset, format);
 288     return (offset / offset_unit) + (format << offset_width);
 289   }
 290 
 291  public:
 292   relocInfo(relocType type, int offset, int format = 0)
 293     : relocInfo(check_relocType(type), RAW_BITS, compute_bits(offset, format)) {}
 294 
 295   #define APPLY_TO_RELOCATIONS(visitor) \
 296     visitor(oop) \
 297     visitor(metadata) \
 298     visitor(virtual_call) \
 299     visitor(opt_virtual_call) \
 300     visitor(static_call) \
 301     visitor(static_stub) \
 302     visitor(runtime_call) \
 303     visitor(runtime_call_w_cp) \
 304     visitor(external_word) \
 305     visitor(internal_word) \
 306     visitor(poll) \
 307     visitor(poll_return) \
 308     visitor(section_word) \
 309     visitor(trampoline_stub) \
 310     visitor(post_call_nop) \

 311     visitor(barrier) \
 312 
 313 
 314  public:
 315   enum : unsigned short{
 316     value_width             = sizeof(unsigned short) * BitsPerByte,
 317     type_width              = 5,   // == log2(type_mask+1)
 318     nontype_width           = value_width - type_width,
 319     datalen_width           = nontype_width-1,
 320     datalen_tag             = 1 << datalen_width,  // or-ed into _value
 321     datalen_limit           = 1 << datalen_width,
 322     datalen_mask            = (1 << datalen_width)-1
 323   };
 324 
 325   // accessors
 326  public:
 327   relocType  type()       const { return (relocType)((unsigned)_value >> nontype_width); }
 328   int  format()           const { return format_mask==0? 0: format_mask &
 329                                          ((unsigned)_value >> offset_width); }
 330   int  addr_offset()      const { assert(!is_prefix(), "must have offset");

 905       const_verify_data_value(x);
 906     } else {
 907       pd_verify_data_value(x);
 908     }
 909   }
 910 };
 911 
 912 class post_call_nop_Relocation : public Relocation {
 913   friend class RelocationHolder;
 914 
 915 public:
 916   post_call_nop_Relocation() : Relocation(relocInfo::post_call_nop_type) { }
 917 
 918   static RelocationHolder spec() {
 919     return RelocationHolder::construct<post_call_nop_Relocation>();
 920   }
 921 
 922   void copy_into(RelocationHolder& holder) const override;
 923 };
 924 













 925 // A CallRelocation always points at a call instruction.
 926 // It is PC-relative on most machines.
 927 class CallRelocation : public Relocation {
 928  public:
 929   CallRelocation(relocInfo::relocType type) : Relocation(type) { }
 930 
 931   bool is_call() override { return true; }
 932 
 933   address  destination()                    { return pd_call_destination(); }
 934   void     set_destination(address x); // pd_set_call_destination
 935 
 936   void     fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) override;
 937   address  value() override                 { return destination();  }
 938   void     set_value(address x) override    { set_destination(x); }
 939 };
 940 
 941 class oop_Relocation : public DataRelocation {
 942  public:
 943   // an oop in the CodeBlob's oop pool; encoded as [n] or [Nn]
 944   static RelocationHolder spec(int oop_index) {
< prev index next >