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) {
|