Mercurial > hg > graal-jvmci-8
comparison src/share/vm/classfile/stackMapTableFormat.hpp @ 6605:4ee06e614636
7116786: RFE: Detailed information on VerifyErrors
Summary: Provide additional detail in VerifyError messages
Reviewed-by: sspitsyn, acorn
author | kamg |
---|---|
date | Mon, 06 Aug 2012 15:54:45 -0400 |
parents | f95d63e2154a |
children | e4525db27263 |
comparison
equal
deleted
inserted
replaced
6604:c3c2141203e7 | 6605:4ee06e614636 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
133 (address)this < end && | 133 (address)this < end && |
134 (bci_addr() + sizeof(u2) <= end || | 134 (bci_addr() + sizeof(u2) <= end || |
135 !is_object() && !is_uninitialized())); | 135 !is_object() && !is_uninitialized())); |
136 } | 136 } |
137 | 137 |
138 #ifdef ASSERT | |
139 void print_on(outputStream* st) { | 138 void print_on(outputStream* st) { |
140 switch (tag()) { | 139 switch (tag()) { |
141 case ITEM_Top: st->print("Top"); break; | 140 case ITEM_Top: st->print("Top"); break; |
142 case ITEM_Integer: st->print("Integer"); break; | 141 case ITEM_Integer: st->print("Integer"); break; |
143 case ITEM_Float: st->print("Float"); break; | 142 case ITEM_Float: st->print("Float"); break; |
152 st->print("Object[#%d]", cpool_index()); break; | 151 st->print("Object[#%d]", cpool_index()); break; |
153 default: | 152 default: |
154 assert(false, "Bad verification_type_info"); | 153 assert(false, "Bad verification_type_info"); |
155 } | 154 } |
156 } | 155 } |
157 #endif | |
158 }; | 156 }; |
159 | 157 |
160 #define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \ | 158 #define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \ |
161 macro(same_frame, arg1, arg2) \ | 159 macro(same_frame, arg1, arg2) \ |
162 macro(same_frame_extended, arg1, arg2) \ | 160 macro(same_frame_extended, arg1, arg2) \ |
163 macro(same_frame_1_stack_item_frame, arg1, arg2) \ | 161 macro(same_locals_1_stack_item_frame, arg1, arg2) \ |
164 macro(same_frame_1_stack_item_extended, arg1, arg2) \ | 162 macro(same_locals_1_stack_item_extended, arg1, arg2) \ |
165 macro(chop_frame, arg1, arg2) \ | 163 macro(chop_frame, arg1, arg2) \ |
166 macro(append_frame, arg1, arg2) \ | 164 macro(append_frame, arg1, arg2) \ |
167 macro(full_frame, arg1, arg2) | 165 macro(full_frame, arg1, arg2) |
168 | 166 |
169 #define SM_FORWARD_DECL(type, arg1, arg2) class type; | 167 #define SM_FORWARD_DECL(type, arg1, arg2) class type; |
201 | 199 |
202 // This method must be used when reading unverified data in order to ensure | 200 // This method must be used when reading unverified data in order to ensure |
203 // that we don't read past a particular memory limit. It returns false | 201 // that we don't read past a particular memory limit. It returns false |
204 // if any part of the data structure is outside the specified memory bounds. | 202 // if any part of the data structure is outside the specified memory bounds. |
205 inline bool verify(address start, address end) const; | 203 inline bool verify(address start, address end) const; |
206 #ifdef ASSERT | 204 |
207 inline void print_on(outputStream* st) const; | 205 inline void print_on(outputStream* st, int current_offset) const; |
208 #endif | |
209 | 206 |
210 // Create as_xxx and is_xxx methods for the subtypes | 207 // Create as_xxx and is_xxx methods for the subtypes |
211 #define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \ | 208 #define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \ |
212 inline stackmap_frame_type* as_##stackmap_frame_type() const; \ | 209 inline stackmap_frame_type* as_##stackmap_frame_type() const; \ |
213 bool is_##stackmap_frame_type() { \ | 210 bool is_##stackmap_frame_type() { \ |
261 | 258 |
262 bool verify_subtype(address start, address end) const { | 259 bool verify_subtype(address start, address end) const { |
263 return true; | 260 return true; |
264 } | 261 } |
265 | 262 |
266 #ifdef ASSERT | 263 void print_on(outputStream* st, int current_offset = -1) const { |
267 void print_on(outputStream* st) const { | 264 st->print("same_frame(@%d)", offset_delta() + current_offset); |
268 st->print("same_frame(%d)", offset_delta()); | 265 } |
269 } | |
270 #endif | |
271 }; | 266 }; |
272 | 267 |
273 class same_frame_extended : public stack_map_frame { | 268 class same_frame_extended : public stack_map_frame { |
274 private: | 269 private: |
275 enum { _frame_id = 251 }; | 270 enum { _frame_id = 251 }; |
309 | 304 |
310 bool verify_subtype(address start, address end) const { | 305 bool verify_subtype(address start, address end) const { |
311 return frame_type_addr() + size() <= end; | 306 return frame_type_addr() + size() <= end; |
312 } | 307 } |
313 | 308 |
314 #ifdef ASSERT | 309 void print_on(outputStream* st, int current_offset = -1) const { |
315 void print_on(outputStream* st) const { | 310 st->print("same_frame_extended(@%d)", offset_delta() + current_offset); |
316 st->print("same_frame_extended(%d)", offset_delta()); | 311 } |
317 } | 312 }; |
318 #endif | 313 |
319 }; | 314 class same_locals_1_stack_item_frame : public stack_map_frame { |
320 | |
321 class same_frame_1_stack_item_frame : public stack_map_frame { | |
322 private: | 315 private: |
323 address type_addr() const { return frame_type_addr() + sizeof(u1); } | 316 address type_addr() const { return frame_type_addr() + sizeof(u1); } |
324 | 317 |
325 static int frame_type_to_offset_delta(u1 frame_type) { | 318 static int frame_type_to_offset_delta(u1 frame_type) { |
326 return frame_type - 63; } | 319 return frame_type - 63; } |
330 public: | 323 public: |
331 static bool is_frame_type(u1 tag) { | 324 static bool is_frame_type(u1 tag) { |
332 return tag >= 64 && tag < 128; | 325 return tag >= 64 && tag < 128; |
333 } | 326 } |
334 | 327 |
335 static same_frame_1_stack_item_frame* at(address addr) { | 328 static same_locals_1_stack_item_frame* at(address addr) { |
336 assert(is_frame_type(*addr), "Wrong frame id"); | 329 assert(is_frame_type(*addr), "Wrong frame id"); |
337 return (same_frame_1_stack_item_frame*)addr; | 330 return (same_locals_1_stack_item_frame*)addr; |
338 } | 331 } |
339 | 332 |
340 static same_frame_1_stack_item_frame* create_at( | 333 static same_locals_1_stack_item_frame* create_at( |
341 address addr, int offset_delta, verification_type_info* vti) { | 334 address addr, int offset_delta, verification_type_info* vti) { |
342 same_frame_1_stack_item_frame* sm = (same_frame_1_stack_item_frame*)addr; | 335 same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr; |
343 sm->set_offset_delta(offset_delta); | 336 sm->set_offset_delta(offset_delta); |
344 if (vti != NULL) { | 337 if (vti != NULL) { |
345 sm->set_type(vti); | 338 sm->set_type(vti); |
346 } | 339 } |
347 return sm; | 340 return sm; |
380 | 373 |
381 bool verify_subtype(address start, address end) const { | 374 bool verify_subtype(address start, address end) const { |
382 return types()->verify(start, end); | 375 return types()->verify(start, end); |
383 } | 376 } |
384 | 377 |
385 #ifdef ASSERT | 378 void print_on(outputStream* st, int current_offset = -1) const { |
386 void print_on(outputStream* st) const { | 379 st->print("same_locals_1_stack_item_frame(@%d,", |
387 st->print("same_frame_1_stack_item_frame(%d,", offset_delta()); | 380 offset_delta() + current_offset); |
388 types()->print_on(st); | 381 types()->print_on(st); |
389 st->print(")"); | 382 st->print(")"); |
390 } | 383 } |
391 #endif | 384 }; |
392 }; | 385 |
393 | 386 class same_locals_1_stack_item_extended : public stack_map_frame { |
394 class same_frame_1_stack_item_extended : public stack_map_frame { | |
395 private: | 387 private: |
396 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); } | 388 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); } |
397 address type_addr() const { return offset_delta_addr() + sizeof(u2); } | 389 address type_addr() const { return offset_delta_addr() + sizeof(u2); } |
398 | 390 |
399 enum { _frame_id = 247 }; | 391 enum { _frame_id = 247 }; |
401 public: | 393 public: |
402 static bool is_frame_type(u1 tag) { | 394 static bool is_frame_type(u1 tag) { |
403 return tag == _frame_id; | 395 return tag == _frame_id; |
404 } | 396 } |
405 | 397 |
406 static same_frame_1_stack_item_extended* at(address addr) { | 398 static same_locals_1_stack_item_extended* at(address addr) { |
407 assert(is_frame_type(*addr), "Wrong frame id"); | 399 assert(is_frame_type(*addr), "Wrong frame id"); |
408 return (same_frame_1_stack_item_extended*)addr; | 400 return (same_locals_1_stack_item_extended*)addr; |
409 } | 401 } |
410 | 402 |
411 static same_frame_1_stack_item_extended* create_at( | 403 static same_locals_1_stack_item_extended* create_at( |
412 address addr, int offset_delta, verification_type_info* vti) { | 404 address addr, int offset_delta, verification_type_info* vti) { |
413 same_frame_1_stack_item_extended* sm = | 405 same_locals_1_stack_item_extended* sm = |
414 (same_frame_1_stack_item_extended*)addr; | 406 (same_locals_1_stack_item_extended*)addr; |
415 sm->set_frame_type(_frame_id); | 407 sm->set_frame_type(_frame_id); |
416 sm->set_offset_delta(offset_delta); | 408 sm->set_offset_delta(offset_delta); |
417 if (vti != NULL) { | 409 if (vti != NULL) { |
418 sm->set_type(vti); | 410 sm->set_type(vti); |
419 } | 411 } |
446 | 438 |
447 bool verify_subtype(address start, address end) const { | 439 bool verify_subtype(address start, address end) const { |
448 return type_addr() < end && types()->verify(start, end); | 440 return type_addr() < end && types()->verify(start, end); |
449 } | 441 } |
450 | 442 |
451 #ifdef ASSERT | 443 void print_on(outputStream* st, int current_offset = -1) const { |
452 void print_on(outputStream* st) const { | 444 st->print("same_locals_1_stack_item_extended(@%d,", |
453 st->print("same_frame_1_stack_item_extended(%d,", offset_delta()); | 445 offset_delta() + current_offset); |
454 types()->print_on(st); | 446 types()->print_on(st); |
455 st->print(")"); | 447 st->print(")"); |
456 } | 448 } |
457 #endif | |
458 }; | 449 }; |
459 | 450 |
460 class chop_frame : public stack_map_frame { | 451 class chop_frame : public stack_map_frame { |
461 private: | 452 private: |
462 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); } | 453 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); } |
515 | 506 |
516 bool verify_subtype(address start, address end) const { | 507 bool verify_subtype(address start, address end) const { |
517 return frame_type_addr() + size() <= end; | 508 return frame_type_addr() + size() <= end; |
518 } | 509 } |
519 | 510 |
520 #ifdef ASSERT | 511 void print_on(outputStream* st, int current_offset = -1) const { |
521 void print_on(outputStream* st) const { | 512 st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops()); |
522 st->print("chop_frame(%d,%d)", offset_delta(), chops()); | 513 } |
523 } | |
524 #endif | |
525 }; | 514 }; |
526 | 515 |
527 class append_frame : public stack_map_frame { | 516 class append_frame : public stack_map_frame { |
528 private: | 517 private: |
529 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); } | 518 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); } |
616 } | 605 } |
617 } | 606 } |
618 return false; | 607 return false; |
619 } | 608 } |
620 | 609 |
621 #ifdef ASSERT | 610 void print_on(outputStream* st, int current_offset = -1) const { |
622 void print_on(outputStream* st) const { | 611 st->print("append_frame(@%d,", offset_delta() + current_offset); |
623 st->print("append_frame(%d,", offset_delta()); | |
624 verification_type_info* vti = types(); | 612 verification_type_info* vti = types(); |
625 for (int i = 0; i < number_of_types(); ++i) { | 613 for (int i = 0; i < number_of_types(); ++i) { |
626 vti->print_on(st); | 614 vti->print_on(st); |
627 if (i != number_of_types() - 1) { | 615 if (i != number_of_types() - 1) { |
628 st->print(","); | 616 st->print(","); |
629 } | 617 } |
630 vti = vti->next(); | 618 vti = vti->next(); |
631 } | 619 } |
632 st->print(")"); | 620 st->print(")"); |
633 } | 621 } |
634 #endif | |
635 }; | 622 }; |
636 | 623 |
637 class full_frame : public stack_map_frame { | 624 class full_frame : public stack_map_frame { |
638 private: | 625 private: |
639 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); } | 626 address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); } |
772 vti = vti->next(); | 759 vti = vti->next(); |
773 } | 760 } |
774 return true; | 761 return true; |
775 } | 762 } |
776 | 763 |
777 #ifdef ASSERT | 764 void print_on(outputStream* st, int current_offset = -1) const { |
778 void print_on(outputStream* st) const { | 765 st->print("full_frame(@%d,{", offset_delta() + current_offset); |
779 st->print("full_frame(%d,{", offset_delta()); | |
780 verification_type_info* vti = locals(); | 766 verification_type_info* vti = locals(); |
781 for (int i = 0; i < num_locals(); ++i) { | 767 for (int i = 0; i < num_locals(); ++i) { |
782 vti->print_on(st); | 768 vti->print_on(st); |
783 if (i != num_locals() - 1) { | 769 if (i != num_locals() - 1) { |
784 st->print(","); | 770 st->print(","); |
796 } | 782 } |
797 vti = vti->next(); | 783 vti = vti->next(); |
798 } | 784 } |
799 st->print("})"); | 785 st->print("})"); |
800 } | 786 } |
801 #endif | |
802 }; | 787 }; |
803 | 788 |
804 #define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \ | 789 #define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \ |
805 stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \ | 790 stack_frame_type* item_##stack_frame_type = as_##stack_frame_type(); \ |
806 if (item_##stack_frame_type != NULL) { \ | 791 if (item_##stack_frame_type != NULL) { \ |
850 VIRTUAL_DISPATCH, verify_subtype, (start, end)); | 835 VIRTUAL_DISPATCH, verify_subtype, (start, end)); |
851 } | 836 } |
852 return false; | 837 return false; |
853 } | 838 } |
854 | 839 |
855 #ifdef ASSERT | 840 void stack_map_frame::print_on(outputStream* st, int offs = -1) const { |
856 void stack_map_frame::print_on(outputStream* st) const { | 841 FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs)); |
857 FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st)); | |
858 } | 842 } |
859 #endif | |
860 | 843 |
861 #undef VIRTUAL_DISPATCH | 844 #undef VIRTUAL_DISPATCH |
862 #undef VOID_VIRTUAL_DISPATCH | 845 #undef VOID_VIRTUAL_DISPATCH |
863 | 846 |
864 #define AS_SUBTYPE_DEF(stack_frame_type, arg1, arg2) \ | 847 #define AS_SUBTYPE_DEF(stack_frame_type, arg1, arg2) \ |
871 } | 854 } |
872 | 855 |
873 FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x) | 856 FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x) |
874 #undef AS_SUBTYPE_DEF | 857 #undef AS_SUBTYPE_DEF |
875 | 858 |
859 class stack_map_table { | |
860 private: | |
861 address number_of_entries_addr() const { | |
862 return (address)this; | |
863 } | |
864 address entries_addr() const { | |
865 return number_of_entries_addr() + sizeof(u2); | |
866 } | |
867 | |
868 protected: | |
869 // No constructors - should be 'private', but GCC issues a warning if it is | |
870 stack_map_table() {} | |
871 stack_map_table(const stack_map_table&) {} | |
872 | |
873 public: | |
874 | |
875 static stack_map_table* at(address addr) { | |
876 return (stack_map_table*)addr; | |
877 } | |
878 | |
879 u2 number_of_entries() const { | |
880 return Bytes::get_Java_u2(number_of_entries_addr()); | |
881 } | |
882 stack_map_frame* entries() const { | |
883 return stack_map_frame::at(entries_addr()); | |
884 } | |
885 | |
886 void set_number_of_entries(u2 num) { | |
887 Bytes::put_Java_u2(number_of_entries_addr(), num); | |
888 } | |
889 }; | |
890 | |
876 class stack_map_table_attribute { | 891 class stack_map_table_attribute { |
877 private: | 892 private: |
878 address name_index_addr() const { | 893 address name_index_addr() const { |
879 return (address)this; } | 894 return (address)this; } |
880 address attribute_length_addr() const { | 895 address attribute_length_addr() const { |
881 return name_index_addr() + sizeof(u2); } | 896 return name_index_addr() + sizeof(u2); } |
882 address number_of_entries_addr() const { | 897 address stack_map_table_addr() const { |
883 return attribute_length_addr() + sizeof(u4); } | 898 return attribute_length_addr() + sizeof(u4); } |
884 address entries_addr() const { | |
885 return number_of_entries_addr() + sizeof(u2); } | |
886 | 899 |
887 protected: | 900 protected: |
888 // No constructors - should be 'private', but GCC issues a warning if it is | 901 // No constructors - should be 'private', but GCC issues a warning if it is |
889 stack_map_table_attribute() {} | 902 stack_map_table_attribute() {} |
890 stack_map_table_attribute(const stack_map_table_attribute&) {} | 903 stack_map_table_attribute(const stack_map_table_attribute&) {} |
894 static stack_map_table_attribute* at(address addr) { | 907 static stack_map_table_attribute* at(address addr) { |
895 return (stack_map_table_attribute*)addr; | 908 return (stack_map_table_attribute*)addr; |
896 } | 909 } |
897 | 910 |
898 u2 name_index() const { | 911 u2 name_index() const { |
899 return Bytes::get_Java_u2(name_index_addr()); } | 912 return Bytes::get_Java_u2(name_index_addr()); } |
900 u4 attribute_length() const { | 913 u4 attribute_length() const { |
901 return Bytes::get_Java_u4(attribute_length_addr()); } | 914 return Bytes::get_Java_u4(attribute_length_addr()); } |
902 u2 number_of_entries() const { | 915 stack_map_table* table() const { |
903 return Bytes::get_Java_u2(number_of_entries_addr()); } | 916 return stack_map_table::at(stack_map_table_addr()); |
904 stack_map_frame* entries() const { | |
905 return stack_map_frame::at(entries_addr()); | |
906 } | |
907 | |
908 static size_t header_size() { | |
909 return sizeof(u2) + sizeof(u4); | |
910 } | 917 } |
911 | 918 |
912 void set_name_index(u2 idx) { | 919 void set_name_index(u2 idx) { |
913 Bytes::put_Java_u2(name_index_addr(), idx); | 920 Bytes::put_Java_u2(name_index_addr(), idx); |
914 } | 921 } |
915 void set_attribute_length(u4 len) { | 922 void set_attribute_length(u4 len) { |
916 Bytes::put_Java_u4(attribute_length_addr(), len); | 923 Bytes::put_Java_u4(attribute_length_addr(), len); |
917 } | 924 } |
918 void set_number_of_entries(u2 num) { | 925 }; |
919 Bytes::put_Java_u2(number_of_entries_addr(), num); | 926 |
920 } | 927 #undef FOR_EACH_STACKMAP_FRAME_TYPE |
921 }; | |
922 | 928 |
923 #endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP | 929 #endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP |