1 /*
2 * Copyright (c) 2010, 2023, 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 *
140 switch (tag()) {
141 case ITEM_Top: st->print("Top"); break;
142 case ITEM_Integer: st->print("Integer"); break;
143 case ITEM_Float: st->print("Float"); break;
144 case ITEM_Double: st->print("Double"); break;
145 case ITEM_Long: st->print("Long"); break;
146 case ITEM_Null: st->print("Null"); break;
147 case ITEM_UninitializedThis:
148 st->print("UninitializedThis"); break;
149 case ITEM_Uninitialized:
150 st->print("Uninitialized[#%d]", bci()); break;
151 case ITEM_Object:
152 st->print("Object[#%d]", cpool_index()); break;
153 default:
154 st->print("BAD:%d", tag()); break;
155 }
156 }
157 };
158
159 #define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \
160 macro(same_frame, arg1, arg2) \
161 macro(same_frame_extended, arg1, arg2) \
162 macro(same_locals_1_stack_item_frame, arg1, arg2) \
163 macro(same_locals_1_stack_item_extended, arg1, arg2) \
164 macro(chop_frame, arg1, arg2) \
165 macro(append_frame, arg1, arg2) \
166 macro(full_frame, arg1, arg2)
167
168 #define SM_FORWARD_DECL(type, arg1, arg2) class type;
169 FOR_EACH_STACKMAP_FRAME_TYPE(SM_FORWARD_DECL, x, x)
170 #undef SM_FORWARD_DECL
171
172 class stack_map_frame {
173 NONCOPYABLE(stack_map_frame);
174
175 protected:
176 address frame_type_addr() const { return (address)this; }
177
178 // No constructors - should be 'private', but GCC issues a warning if it is
179 stack_map_frame() {}
204 // if any part of the data structure is outside the specified memory bounds.
205 inline bool verify(address start, address end) const;
206
207 inline void print_on(outputStream* st, int current_offset) const;
208 inline void print_truncated(outputStream* st, int current_offset) const;
209
210 // Create as_xxx and is_xxx methods for the subtypes
211 #define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
212 inline stackmap_frame_type* as_##stackmap_frame_type() const; \
213 bool is_##stackmap_frame_type() { \
214 return as_##stackmap_frame_type() != nullptr; \
215 }
216
217 FOR_EACH_STACKMAP_FRAME_TYPE(FRAME_TYPE_DECL, x, x)
218 #undef FRAME_TYPE_DECL
219 };
220
221 class same_frame : public stack_map_frame {
222 private:
223 static int frame_type_to_offset_delta(u1 frame_type) {
224 return frame_type + 1; }
225 static u1 offset_delta_to_frame_type(int offset_delta) {
226 return checked_cast<u1>(offset_delta - 1); }
227
228 public:
229
230 static bool is_frame_type(u1 tag) {
231 return tag < 64;
232 }
233
234 static same_frame* at(address addr) {
235 assert(is_frame_type(*addr), "Wrong frame id");
236 return (same_frame*)addr;
237 }
238
239 static same_frame* create_at(address addr, int offset_delta) {
240 same_frame* sm = (same_frame*)addr;
241 sm->set_offset_delta(offset_delta);
242 return sm;
243 }
244
245 static size_t calculate_size() { return sizeof(u1); }
246
310 bool is_valid_offset(int offset) const { return true; }
311
312 bool verify_subtype(address start, address end) const {
313 return frame_type_addr() + size() <= end;
314 }
315
316 void print_on(outputStream* st, int current_offset = -1) const {
317 st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
318 }
319
320 void print_truncated(outputStream* st, int current_offset = -1) const {
321 print_on(st, current_offset);
322 }
323 };
324
325 class same_locals_1_stack_item_frame : public stack_map_frame {
326 private:
327 address type_addr() const { return frame_type_addr() + sizeof(u1); }
328
329 static int frame_type_to_offset_delta(u1 frame_type) {
330 return frame_type - 63; }
331 static u1 offset_delta_to_frame_type(int offset_delta) {
332 return (u1)(offset_delta + 63); }
333
334 public:
335 static bool is_frame_type(u1 tag) {
336 return tag >= 64 && tag < 128;
337 }
338
339 static same_locals_1_stack_item_frame* at(address addr) {
340 assert(is_frame_type(*addr), "Wrong frame id");
341 return (same_locals_1_stack_item_frame*)addr;
342 }
343
344 static same_locals_1_stack_item_frame* create_at(
345 address addr, int offset_delta, verification_type_info* vti) {
346 same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr;
347 sm->set_offset_delta(offset_delta);
348 if (vti != nullptr) {
349 sm->set_type(vti);
350 }
351 return sm;
352 }
382 return is_frame_type(offset_delta_to_frame_type(offset_delta));
383 }
384
385 bool verify_subtype(address start, address end) const {
386 return types()->verify(start, end);
387 }
388
389 void print_on(outputStream* st, int current_offset = -1) const {
390 st->print("same_locals_1_stack_item_frame(@%d,",
391 offset_delta() + current_offset);
392 types()->print_on(st);
393 st->print(")");
394 }
395
396 void print_truncated(outputStream* st, int current_offset = -1) const {
397 st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.",
398 offset_delta() + current_offset);
399 }
400 };
401
402 class same_locals_1_stack_item_extended : public stack_map_frame {
403 private:
404 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
405 address type_addr() const { return offset_delta_addr() + sizeof(u2); }
406
407 enum { _frame_id = 247 };
408
409 public:
410 static bool is_frame_type(u1 tag) {
411 return tag == _frame_id;
412 }
413
414 static same_locals_1_stack_item_extended* at(address addr) {
415 assert(is_frame_type(*addr), "Wrong frame id");
416 return (same_locals_1_stack_item_extended*)addr;
417 }
418
419 static same_locals_1_stack_item_extended* create_at(
420 address addr, int offset_delta, verification_type_info* vti) {
421 same_locals_1_stack_item_extended* sm =
640 if (i != number_of_types() - 1) {
641 st->print(",");
642 }
643 vti = vti->next();
644 }
645 st->print(")");
646 }
647
648 void print_truncated(outputStream* st, int current_offset = -1) const {
649 st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.",
650 offset_delta() + current_offset);
651 }
652 };
653
654 class full_frame : public stack_map_frame {
655 private:
656 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
657 address num_locals_addr() const { return offset_delta_addr() + sizeof(u2); }
658 address locals_addr() const { return num_locals_addr() + sizeof(u2); }
659 address stack_slots_addr(address end_of_locals) const {
660 return end_of_locals; }
661 address stack_addr(address end_of_locals) const {
662 return stack_slots_addr(end_of_locals) + sizeof(u2); }
663
664 enum { _frame_id = 255 };
665
666 public:
667 static bool is_frame_type(u1 tag) {
668 return tag == _frame_id;
669 }
670
671 static full_frame* at(address addr) {
672 assert(is_frame_type(*addr), "Wrong frame id");
673 return (full_frame*)addr;
674 }
675
676 static full_frame* create_at(
677 address addr, int offset_delta, int num_locals,
678 verification_type_info* locals,
679 int stack_slots, verification_type_info* stack) {
680 full_frame* sm = (full_frame*)addr;
681 sm->set_frame_type(_frame_id);
682 sm->set_offset_delta(offset_delta);
913
914 static stack_map_table* at(address addr) {
915 return (stack_map_table*)addr;
916 }
917
918 u2 number_of_entries() const {
919 return Bytes::get_Java_u2(number_of_entries_addr());
920 }
921 stack_map_frame* entries() const {
922 return stack_map_frame::at(entries_addr());
923 }
924
925 void set_number_of_entries(u2 num) {
926 Bytes::put_Java_u2(number_of_entries_addr(), num);
927 }
928 };
929
930 class stack_map_table_attribute {
931 private:
932 address name_index_addr() const {
933 return (address)this; }
934 address attribute_length_addr() const {
935 return name_index_addr() + sizeof(u2); }
936 address stack_map_table_addr() const {
937 return attribute_length_addr() + sizeof(u4); }
938 NONCOPYABLE(stack_map_table_attribute);
939
940 protected:
941 // No constructors - should be 'private', but GCC issues a warning if it is
942 stack_map_table_attribute() {}
943
944 public:
945
946 static stack_map_table_attribute* at(address addr) {
947 return (stack_map_table_attribute*)addr;
948 }
949
950 u2 name_index() const {
951 return Bytes::get_Java_u2(name_index_addr()); }
952 u4 attribute_length() const {
953 return Bytes::get_Java_u4(attribute_length_addr()); }
954 stack_map_table* table() const {
955 return stack_map_table::at(stack_map_table_addr());
956 }
957
958 void set_name_index(u2 idx) {
959 Bytes::put_Java_u2(name_index_addr(), idx);
960 }
961 void set_attribute_length(u4 len) {
962 Bytes::put_Java_u4(attribute_length_addr(), len);
963 }
964 };
965
966 #undef FOR_EACH_STACKMAP_FRAME_TYPE
967
968 #endif // SHARE_CLASSFILE_STACKMAPTABLEFORMAT_HPP
|
1 /*
2 * Copyright (c) 2010, 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 *
140 switch (tag()) {
141 case ITEM_Top: st->print("Top"); break;
142 case ITEM_Integer: st->print("Integer"); break;
143 case ITEM_Float: st->print("Float"); break;
144 case ITEM_Double: st->print("Double"); break;
145 case ITEM_Long: st->print("Long"); break;
146 case ITEM_Null: st->print("Null"); break;
147 case ITEM_UninitializedThis:
148 st->print("UninitializedThis"); break;
149 case ITEM_Uninitialized:
150 st->print("Uninitialized[#%d]", bci()); break;
151 case ITEM_Object:
152 st->print("Object[#%d]", cpool_index()); break;
153 default:
154 st->print("BAD:%d", tag()); break;
155 }
156 }
157 };
158
159 #define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \
160 macro(early_larval, arg1, arg2) \
161 macro(same_frame, arg1, arg2) \
162 macro(same_frame_extended, arg1, arg2) \
163 macro(same_locals_1_stack_item_frame, arg1, arg2) \
164 macro(same_locals_1_stack_item_extended, arg1, arg2) \
165 macro(chop_frame, arg1, arg2) \
166 macro(append_frame, arg1, arg2) \
167 macro(full_frame, arg1, arg2)
168
169 #define SM_FORWARD_DECL(type, arg1, arg2) class type;
170 FOR_EACH_STACKMAP_FRAME_TYPE(SM_FORWARD_DECL, x, x)
171 #undef SM_FORWARD_DECL
172
173 class stack_map_frame {
174 NONCOPYABLE(stack_map_frame);
175
176 protected:
177 address frame_type_addr() const { return (address)this; }
178
179 // No constructors - should be 'private', but GCC issues a warning if it is
180 stack_map_frame() {}
205 // if any part of the data structure is outside the specified memory bounds.
206 inline bool verify(address start, address end) const;
207
208 inline void print_on(outputStream* st, int current_offset) const;
209 inline void print_truncated(outputStream* st, int current_offset) const;
210
211 // Create as_xxx and is_xxx methods for the subtypes
212 #define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
213 inline stackmap_frame_type* as_##stackmap_frame_type() const; \
214 bool is_##stackmap_frame_type() { \
215 return as_##stackmap_frame_type() != nullptr; \
216 }
217
218 FOR_EACH_STACKMAP_FRAME_TYPE(FRAME_TYPE_DECL, x, x)
219 #undef FRAME_TYPE_DECL
220 };
221
222 class same_frame : public stack_map_frame {
223 private:
224 static int frame_type_to_offset_delta(u1 frame_type) {
225 return frame_type + 1;
226 }
227 static u1 offset_delta_to_frame_type(int offset_delta) {
228 return checked_cast<u1>(offset_delta - 1);
229 }
230
231 public:
232
233 static bool is_frame_type(u1 tag) {
234 return tag < 64;
235 }
236
237 static same_frame* at(address addr) {
238 assert(is_frame_type(*addr), "Wrong frame id");
239 return (same_frame*)addr;
240 }
241
242 static same_frame* create_at(address addr, int offset_delta) {
243 same_frame* sm = (same_frame*)addr;
244 sm->set_offset_delta(offset_delta);
245 return sm;
246 }
247
248 static size_t calculate_size() { return sizeof(u1); }
249
313 bool is_valid_offset(int offset) const { return true; }
314
315 bool verify_subtype(address start, address end) const {
316 return frame_type_addr() + size() <= end;
317 }
318
319 void print_on(outputStream* st, int current_offset = -1) const {
320 st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
321 }
322
323 void print_truncated(outputStream* st, int current_offset = -1) const {
324 print_on(st, current_offset);
325 }
326 };
327
328 class same_locals_1_stack_item_frame : public stack_map_frame {
329 private:
330 address type_addr() const { return frame_type_addr() + sizeof(u1); }
331
332 static int frame_type_to_offset_delta(u1 frame_type) {
333 return frame_type - 63;
334 }
335 static u1 offset_delta_to_frame_type(int offset_delta) {
336 return (u1)(offset_delta + 63);
337 }
338
339 public:
340 static bool is_frame_type(u1 tag) {
341 return tag >= 64 && tag < 128;
342 }
343
344 static same_locals_1_stack_item_frame* at(address addr) {
345 assert(is_frame_type(*addr), "Wrong frame id");
346 return (same_locals_1_stack_item_frame*)addr;
347 }
348
349 static same_locals_1_stack_item_frame* create_at(
350 address addr, int offset_delta, verification_type_info* vti) {
351 same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr;
352 sm->set_offset_delta(offset_delta);
353 if (vti != nullptr) {
354 sm->set_type(vti);
355 }
356 return sm;
357 }
387 return is_frame_type(offset_delta_to_frame_type(offset_delta));
388 }
389
390 bool verify_subtype(address start, address end) const {
391 return types()->verify(start, end);
392 }
393
394 void print_on(outputStream* st, int current_offset = -1) const {
395 st->print("same_locals_1_stack_item_frame(@%d,",
396 offset_delta() + current_offset);
397 types()->print_on(st);
398 st->print(")");
399 }
400
401 void print_truncated(outputStream* st, int current_offset = -1) const {
402 st->print("same_locals_1_stack_item_frame(@%d), output truncated, Stackmap exceeds table size.",
403 offset_delta() + current_offset);
404 }
405 };
406
407 class early_larval : public stack_map_frame {
408 private:
409 static int frame_type_to_offset_delta(u1 frame_type) {
410 return 0;
411 }
412 static u1 offset_delta_to_frame_type(int offset_delta) {
413 return checked_cast<u1>(246);
414 }
415
416 address num_unset_fields_addr() const { return frame_type_addr() + sizeof(u1); }
417 int number_of_unset_fields() const { return Bytes::get_Java_u2(num_unset_fields_addr()); }
418
419 // EARLY_LARVAL frames wrap regular stack map frames
420 stack_map_frame* nested_frame() const { return (stack_map_frame*)(frame_type_addr() + calculate_size(number_of_unset_fields())); }
421
422 public:
423 static bool is_frame_type(u1 tag) {
424 return tag == 246;
425 }
426
427 static early_larval* at(address addr) {
428 assert(is_frame_type(*addr), "Wrong frame id");
429 return (early_larval*)addr;
430 }
431
432 static early_larval* create_at(address addr, int offset_delta) {
433 early_larval* sm = (early_larval*)addr;
434 return sm;
435 }
436
437 static size_t calculate_size(u2 num_unset_fields) { return sizeof(u1) + sizeof(u2) + (sizeof(u2) * num_unset_fields); }
438
439 size_t size() const { return calculate_size(number_of_unset_fields()) + nested_frame()->size(); }
440 int offset_delta() const { return nested_frame()->offset_delta(); }
441
442 void set_offset_delta(int offset_delta) {
443 assert(offset_delta == 0, "early_larval should not have an offset");
444 set_frame_type(offset_delta_to_frame_type(offset_delta));
445 }
446
447 int number_of_types() const { return 0; }
448 verification_type_info* types() const { return nullptr; }
449
450 bool is_valid_offset(int offset_delta) const {
451 return is_frame_type(offset_delta_to_frame_type(offset_delta));
452 }
453
454 bool verify_subtype(address start, address end) const {
455 return nested_frame()->verify(start, end);
456 }
457
458 void print_on(outputStream* st, int current_offset = -1) const {
459 st->print("early_larval(%d unset fields: ", number_of_unset_fields());
460 st->print("[ ");
461 address addr = num_unset_fields_addr() + sizeof(u2);
462 for (int i = 0; i < number_of_unset_fields(); i++) {
463 st->print("%u ", Bytes::get_Java_u2(addr + (i * sizeof(u2))));
464 }
465 st->print_cr("])");
466 st->print("\t");
467 nested_frame()->print_on(st, current_offset);
468 }
469
470 void print_truncated(outputStream* st, int current_offset = -1) const {
471 // If we fail to verify, we may have a nested early_larval
472 st->print("early_larval(%d unset fields), output truncated, Stackmap exceeds table size.", number_of_unset_fields());
473 }
474 };
475
476 class same_locals_1_stack_item_extended : public stack_map_frame {
477 private:
478 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
479 address type_addr() const { return offset_delta_addr() + sizeof(u2); }
480
481 enum { _frame_id = 247 };
482
483 public:
484 static bool is_frame_type(u1 tag) {
485 return tag == _frame_id;
486 }
487
488 static same_locals_1_stack_item_extended* at(address addr) {
489 assert(is_frame_type(*addr), "Wrong frame id");
490 return (same_locals_1_stack_item_extended*)addr;
491 }
492
493 static same_locals_1_stack_item_extended* create_at(
494 address addr, int offset_delta, verification_type_info* vti) {
495 same_locals_1_stack_item_extended* sm =
714 if (i != number_of_types() - 1) {
715 st->print(",");
716 }
717 vti = vti->next();
718 }
719 st->print(")");
720 }
721
722 void print_truncated(outputStream* st, int current_offset = -1) const {
723 st->print("append_frame(@%d), output truncated, Stackmap exceeds table size.",
724 offset_delta() + current_offset);
725 }
726 };
727
728 class full_frame : public stack_map_frame {
729 private:
730 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
731 address num_locals_addr() const { return offset_delta_addr() + sizeof(u2); }
732 address locals_addr() const { return num_locals_addr() + sizeof(u2); }
733 address stack_slots_addr(address end_of_locals) const {
734 return end_of_locals;
735 }
736 address stack_addr(address end_of_locals) const {
737 return stack_slots_addr(end_of_locals) + sizeof(u2);
738 }
739
740 enum { _frame_id = 255 };
741
742 public:
743 static bool is_frame_type(u1 tag) {
744 return tag == _frame_id;
745 }
746
747 static full_frame* at(address addr) {
748 assert(is_frame_type(*addr), "Wrong frame id");
749 return (full_frame*)addr;
750 }
751
752 static full_frame* create_at(
753 address addr, int offset_delta, int num_locals,
754 verification_type_info* locals,
755 int stack_slots, verification_type_info* stack) {
756 full_frame* sm = (full_frame*)addr;
757 sm->set_frame_type(_frame_id);
758 sm->set_offset_delta(offset_delta);
989
990 static stack_map_table* at(address addr) {
991 return (stack_map_table*)addr;
992 }
993
994 u2 number_of_entries() const {
995 return Bytes::get_Java_u2(number_of_entries_addr());
996 }
997 stack_map_frame* entries() const {
998 return stack_map_frame::at(entries_addr());
999 }
1000
1001 void set_number_of_entries(u2 num) {
1002 Bytes::put_Java_u2(number_of_entries_addr(), num);
1003 }
1004 };
1005
1006 class stack_map_table_attribute {
1007 private:
1008 address name_index_addr() const {
1009 return (address)this;
1010 }
1011 address attribute_length_addr() const {
1012 return name_index_addr() + sizeof(u2);
1013 }
1014 address stack_map_table_addr() const {
1015 return attribute_length_addr() + sizeof(u4);
1016 }
1017 NONCOPYABLE(stack_map_table_attribute);
1018
1019 protected:
1020 // No constructors - should be 'private', but GCC issues a warning if it is
1021 stack_map_table_attribute() {}
1022
1023 public:
1024
1025 static stack_map_table_attribute* at(address addr) {
1026 return (stack_map_table_attribute*)addr;
1027 }
1028
1029 u2 name_index() const {
1030 return Bytes::get_Java_u2(name_index_addr());
1031 }
1032 u4 attribute_length() const {
1033 return Bytes::get_Java_u4(attribute_length_addr());
1034 }
1035 stack_map_table* table() const {
1036 return stack_map_table::at(stack_map_table_addr());
1037 }
1038
1039 void set_name_index(u2 idx) {
1040 Bytes::put_Java_u2(name_index_addr(), idx);
1041 }
1042 void set_attribute_length(u4 len) {
1043 Bytes::put_Java_u4(attribute_length_addr(), len);
1044 }
1045 };
1046
1047 #undef FOR_EACH_STACKMAP_FRAME_TYPE
1048
1049 #endif // SHARE_CLASSFILE_STACKMAPTABLEFORMAT_HPP
|