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 *
23 */
24
25 #include "code/codeCache.hpp"
26 #include "code/compiledIC.hpp"
27 #include "code/nmethod.hpp"
28 #include "code/relocInfo.hpp"
29 #include "memory/resourceArea.hpp"
30 #include "memory/universe.hpp"
31 #include "oops/compressedOops.inline.hpp"
32 #include "oops/oop.inline.hpp"
33 #include "runtime/flags/flagSetting.hpp"
34 #include "runtime/stubCodeGenerator.hpp"
35 #include "utilities/align.hpp"
36 #include "utilities/checkedCast.hpp"
37 #include "utilities/copy.hpp"
38
39 #include <new>
40 #include <type_traits>
41
42 const RelocationHolder RelocationHolder::none; // its type is relocInfo::none
43
44
45 // Implementation of relocInfo
46
47 #ifdef ASSERT
48 relocInfo::relocType relocInfo::check_relocType(relocType type) {
138 _current = nm->relocation_begin() - 1;
139 _end = nm->relocation_end();
140 }
141 _addr = nm->content_begin();
142
143 // Initialize code sections.
144 _section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin();
145 _section_start[CodeBuffer::SECT_INSTS ] = nm->insts_begin() ;
146 _section_start[CodeBuffer::SECT_STUBS ] = nm->stub_begin() ;
147
148 _section_end [CodeBuffer::SECT_CONSTS] = nm->consts_end() ;
149 _section_end [CodeBuffer::SECT_INSTS ] = nm->insts_end() ;
150 _section_end [CodeBuffer::SECT_STUBS ] = nm->stub_end() ;
151
152 assert(!has_current(), "just checking");
153 assert(begin == nullptr || begin >= nm->code_begin(), "in bounds");
154 assert(limit == nullptr || limit <= nm->code_end(), "in bounds");
155 set_limits(begin, limit);
156 }
157
158
159 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
160 initialize_misc();
161 assert(((cs->locs_start() != nullptr) && (cs->locs_end() != nullptr)), "valid start and end pointer");
162 _current = cs->locs_start() - 1;
163 _end = cs->locs_end();
164 _addr = cs->start();
165 _code = nullptr; // Not cb->blob();
166
167 CodeBuffer* cb = cs->outer();
168 assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
169 for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
170 CodeSection* cs = cb->code_section(n);
171 _section_start[n] = cs->start();
172 _section_end [n] = cs->end();
173 }
174
175 assert(!has_current(), "just checking");
176
177 assert(begin == nullptr || begin >= cs->start(), "in bounds");
178 assert(limit == nullptr || limit <= cs->end(), "in bounds");
179 set_limits(begin, limit);
180 }
181
182 bool RelocIterator::addr_in_const() const {
183 const int n = CodeBuffer::SECT_CONSTS;
184 return section_start(n) <= addr() && addr() < section_end(n);
185 }
186
187
188 void RelocIterator::set_limits(address begin, address limit) {
189 _limit = limit;
190
191 // the limit affects this next stuff:
192 if (begin != nullptr) {
193 relocInfo* backup;
194 address backup_addr;
195 while (true) {
196 backup = _current;
197 backup_addr = _addr;
198 if (!next() || addr() >= begin) break;
199 }
200 // At this point, either we are at the first matching record,
201 // or else there is no such record, and !has_current().
202 // In either case, revert to the immediately preceding state.
203 _current = backup;
454 jint offset = unpack_1_int();
455 _static_call = address_from_scaled_offset(offset, base);
456 }
457
458 void trampoline_stub_Relocation::pack_data_to(CodeSection* dest ) {
459 short* p = (short*) dest->locs_end();
460 CodeSection* insts = dest->outer()->insts();
461 normalize_address(_owner, insts);
462 p = pack_1_int_to(p, scaled_offset(_owner, insts->start()));
463 dest->set_locs_end((relocInfo*) p);
464 }
465
466 void trampoline_stub_Relocation::unpack_data() {
467 address base = binding()->section_start(CodeBuffer::SECT_INSTS);
468 _owner = address_from_scaled_offset(unpack_1_int(), base);
469 }
470
471 void external_word_Relocation::pack_data_to(CodeSection* dest) {
472 short* p = (short*) dest->locs_end();
473 int index = ExternalsRecorder::find_index(_target);
474 p = pack_1_int_to(p, index);
475 dest->set_locs_end((relocInfo*) p);
476 }
477
478
479 void external_word_Relocation::unpack_data() {
480 int index = unpack_1_int();
481 _target = ExternalsRecorder::at(index);
482 }
483
484
485 void internal_word_Relocation::pack_data_to(CodeSection* dest) {
486 short* p = (short*) dest->locs_end();
487 normalize_address(_target, dest, true);
488
489 // Check whether my target address is valid within this section.
490 // If not, strengthen the relocation type to point to another section.
491 int sindex = _section;
492 if (sindex == CodeBuffer::SECT_NONE && _target != nullptr
493 && (!dest->allocates(_target) || _target == dest->locs_point())) {
494 sindex = dest->outer()->section_index_of(_target);
495 guarantee(sindex != CodeBuffer::SECT_NONE, "must belong somewhere");
496 relocInfo* base = dest->locs_end() - 1;
497 assert(base->type() == this->type(), "sanity");
498 // Change the written type, to be section_word_type instead.
727
728 return nullptr;
729 }
730
731 void static_stub_Relocation::clear_inline_cache() {
732 // Call stub is only used when calling the interpreted code.
733 // It does not really need to be cleared, except that we want to clean out the methodoop.
734 CompiledDirectCall::set_stub_to_clean(this);
735 }
736
737
738 void external_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
739 if (_target != nullptr) {
740 // Probably this reference is absolute, not relative, so the following is
741 // probably a no-op.
742 set_value(_target);
743 }
744 // If target is nullptr, this is an absolute embedded reference to an external
745 // location, which means there is nothing to fix here. In either case, the
746 // resulting target should be an "external" address.
747 postcond(src->section_index_of(target()) == CodeBuffer::SECT_NONE);
748 postcond(dest->section_index_of(target()) == CodeBuffer::SECT_NONE);
749 }
750
751
752 address external_word_Relocation::target() {
753 address target = _target;
754 if (target == nullptr) {
755 target = pd_get_address_from_code();
756 }
757 return target;
758 }
759
760
761 void internal_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
762 address target = _target;
763 if (target == nullptr) {
764 target = new_addr_for(this->target(), src, dest);
765 }
766 set_value(target);
767 }
768
769
770 address internal_word_Relocation::target() {
771 address target = _target;
772 if (target == nullptr) {
773 if (addr_in_const()) {
774 target = *(address*)addr();
775 } else {
776 target = pd_get_address_from_code();
777 }
778 }
779 return target;
780 }
781
782 //---------------------------------------------------------------------------------
783 // Non-product code
784
785 #ifndef PRODUCT
786
787 static const char* reloc_type_string(relocInfo::relocType t) {
788 switch (t) {
789 #define EACH_CASE(name) \
790 case relocInfo::name##_type: \
791 return #name;
792
793 APPLY_TO_RELOCATIONS(EACH_CASE);
794 #undef EACH_CASE
795
796 case relocInfo::none:
797 return "none";
798 case relocInfo::data_prefix_tag:
799 return "prefix";
800 default:
801 return "UNKNOWN RELOC TYPE";
802 }
803 }
804
805
806 void RelocIterator::print_current() {
807 if (!has_current()) {
808 tty->print_cr("(no relocs)");
809 return;
810 }
811 tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d",
812 p2i(_current), type(), reloc_type_string((relocInfo::relocType) type()), p2i(_addr), _current->addr_offset());
813 if (current()->format() != 0)
814 tty->print(" format=%d", current()->format());
815 if (datalen() == 1) {
816 tty->print(" data=%d", data()[0]);
817 } else if (datalen() > 0) {
818 tty->print(" data={");
819 for (int i = 0; i < datalen(); i++) {
820 tty->print("%04x", data()[i] & 0xFFFF);
821 }
822 tty->print("}");
823 }
824 tty->print("]");
825 switch (type()) {
826 case relocInfo::oop_type:
827 {
828 oop_Relocation* r = oop_reloc();
829 oop* oop_addr = nullptr;
830 oop raw_oop = nullptr;
831 oop oop_value = nullptr;
832 if (code() != nullptr || r->oop_is_immediate()) {
833 oop_addr = r->oop_addr();
834 raw_oop = *oop_addr;
835 oop_value = r->oop_value();
836 }
837 tty->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT "]",
838 p2i(oop_addr), p2i(raw_oop));
839 // Do not print the oop by default--we want this routine to
840 // work even during GC or other inconvenient times.
841 if (WizardMode && oop_value != nullptr) {
842 tty->print("oop_value=" INTPTR_FORMAT ": ", p2i(oop_value));
843 if (oopDesc::is_oop(oop_value)) {
844 oop_value->print_value_on(tty);
845 }
846 }
847 break;
848 }
849 case relocInfo::metadata_type:
850 {
851 metadata_Relocation* r = metadata_reloc();
852 Metadata** metadata_addr = nullptr;
853 Metadata* raw_metadata = nullptr;
854 Metadata* metadata_value = nullptr;
855 if (code() != nullptr || r->metadata_is_immediate()) {
856 metadata_addr = r->metadata_addr();
857 raw_metadata = *metadata_addr;
858 metadata_value = r->metadata_value();
859 }
860 tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT "]",
861 p2i(metadata_addr), p2i(raw_metadata));
862 if (metadata_value != nullptr) {
863 tty->print("metadata_value=" INTPTR_FORMAT ": ", p2i(metadata_value));
864 metadata_value->print_value_on(tty);
865 }
866 break;
867 }
868 case relocInfo::external_word_type:
869 case relocInfo::internal_word_type:
870 case relocInfo::section_word_type:
871 {
872 DataRelocation* r = (DataRelocation*) reloc();
873 tty->print(" | [target=" INTPTR_FORMAT "]", p2i(r->value())); //value==target
874 break;
875 }
876 case relocInfo::static_call_type:
877 {
878 static_call_Relocation* r = (static_call_Relocation*) reloc();
879 tty->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
880 p2i(r->destination()), p2i(r->method_value()));
881 CodeBlob* cb = CodeCache::find_blob(r->destination());
882 if (cb != nullptr) {
883 tty->print(" Blob::%s", cb->name());
884 }
885 break;
886 }
887 case relocInfo::runtime_call_type:
888 case relocInfo::runtime_call_w_cp_type:
889 {
890 CallRelocation* r = (CallRelocation*) reloc();
891 address dest = r->destination();
892 tty->print(" | [destination=" INTPTR_FORMAT "]", p2i(dest));
893 if (StubRoutines::contains(dest)) {
894 StubCodeDesc* desc = StubCodeDesc::desc_for(dest);
895 if (desc == nullptr) {
896 desc = StubCodeDesc::desc_for(dest + frame::pc_return_offset);
897 }
898 if (desc != nullptr) {
899 tty->print(" Stub::%s", desc->name());
900 }
901 } else {
902 CodeBlob* cb = CodeCache::find_blob(dest);
903 if (cb != nullptr) {
904 tty->print(" %s", cb->name());
905 } else {
906 ResourceMark rm;
907 const int buflen = 1024;
908 char* buf = NEW_RESOURCE_ARRAY(char, buflen);
909 int offset;
910 if (os::dll_address_to_function_name(dest, buf, buflen, &offset)) {
911 tty->print(" %s", buf);
912 if (offset != 0) {
913 tty->print("+%d", offset);
914 }
915 }
916 }
917 }
918 break;
919 }
920 case relocInfo::virtual_call_type:
921 {
922 virtual_call_Relocation* r = (virtual_call_Relocation*) reloc();
923 tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
924 p2i(r->destination()), p2i(r->cached_value()), p2i(r->method_value()));
925 CodeBlob* cb = CodeCache::find_blob(r->destination());
926 if (cb != nullptr) {
927 tty->print(" Blob::%s", cb->name());
928 }
929 break;
930 }
931 case relocInfo::static_stub_type:
932 {
933 static_stub_Relocation* r = (static_stub_Relocation*) reloc();
934 tty->print(" | [static_call=" INTPTR_FORMAT "]", p2i(r->static_call()));
935 break;
936 }
937 case relocInfo::trampoline_stub_type:
938 {
939 trampoline_stub_Relocation* r = (trampoline_stub_Relocation*) reloc();
940 tty->print(" | [trampoline owner=" INTPTR_FORMAT "]", p2i(r->owner()));
941 break;
942 }
943 case relocInfo::opt_virtual_call_type:
944 {
945 opt_virtual_call_Relocation* r = (opt_virtual_call_Relocation*) reloc();
946 tty->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
947 p2i(r->destination()), p2i(r->method_value()));
948 CodeBlob* cb = CodeCache::find_blob(r->destination());
949 if (cb != nullptr) {
950 tty->print(" Blob::%s", cb->name());
951 }
952 break;
953 }
954 default:
955 break;
956 }
957 tty->cr();
958 }
959
960
961 void RelocIterator::print() {
962 RelocIterator save_this = (*this);
963 relocInfo* scan = _current;
964 if (!has_current()) scan += 1; // nothing to scan here!
965
966 bool skip_next = has_current();
967 bool got_next;
968 while (true) {
969 got_next = (skip_next || next());
970 skip_next = false;
971
972 tty->print(" @" INTPTR_FORMAT ": ", p2i(scan));
973 relocInfo* newscan = _current+1;
974 if (!has_current()) newscan -= 1; // nothing to scan here!
975 while (scan < newscan) {
976 tty->print("%04x", *(short*)scan & 0xFFFF);
977 scan++;
978 }
979 tty->cr();
980
981 if (!got_next) break;
982 print_current();
983 }
984
985 (*this) = save_this;
986 }
987
988 // For the debugger:
989 extern "C"
990 void print_blob_locs(nmethod* nm) {
991 nm->print();
992 RelocIterator iter(nm);
993 iter.print();
994 }
995 extern "C"
996 void print_buf_locs(CodeBuffer* cb) {
997 FlagSetting fs(PrintRelocations, true);
998 cb->print();
999 }
1000 #endif // !PRODUCT
|
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 *
23 */
24
25 #include "ci/ciUtilities.hpp"
26 #include "code/codeCache.hpp"
27 #include "code/compiledIC.hpp"
28 #include "code/nmethod.hpp"
29 #include "code/relocInfo.hpp"
30 #include "code/SCCache.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "memory/universe.hpp"
33 #include "oops/compressedOops.inline.hpp"
34 #include "oops/oop.inline.hpp"
35 #include "runtime/flags/flagSetting.hpp"
36 #include "runtime/stubCodeGenerator.hpp"
37 #include "utilities/align.hpp"
38 #include "utilities/checkedCast.hpp"
39 #include "utilities/copy.hpp"
40
41 #include <new>
42 #include <type_traits>
43
44 const RelocationHolder RelocationHolder::none; // its type is relocInfo::none
45
46
47 // Implementation of relocInfo
48
49 #ifdef ASSERT
50 relocInfo::relocType relocInfo::check_relocType(relocType type) {
140 _current = nm->relocation_begin() - 1;
141 _end = nm->relocation_end();
142 }
143 _addr = nm->content_begin();
144
145 // Initialize code sections.
146 _section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin();
147 _section_start[CodeBuffer::SECT_INSTS ] = nm->insts_begin() ;
148 _section_start[CodeBuffer::SECT_STUBS ] = nm->stub_begin() ;
149
150 _section_end [CodeBuffer::SECT_CONSTS] = nm->consts_end() ;
151 _section_end [CodeBuffer::SECT_INSTS ] = nm->insts_end() ;
152 _section_end [CodeBuffer::SECT_STUBS ] = nm->stub_end() ;
153
154 assert(!has_current(), "just checking");
155 assert(begin == nullptr || begin >= nm->code_begin(), "in bounds");
156 assert(limit == nullptr || limit <= nm->code_end(), "in bounds");
157 set_limits(begin, limit);
158 }
159
160 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
161 initialize_misc();
162 assert(((cs->locs_start() != nullptr) && (cs->locs_end() != nullptr)), "valid start and end pointer");
163 _current = cs->locs_start() - 1;
164 _end = cs->locs_end();
165 _addr = cs->start();
166 _code = nullptr; // Not cb->blob();
167
168 CodeBuffer* cb = cs->outer();
169 assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
170 for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
171 CodeSection* cs = cb->code_section(n);
172 _section_start[n] = cs->start();
173 _section_end [n] = cs->end();
174 }
175
176 assert(!has_current(), "just checking");
177
178 assert(begin == nullptr || begin >= cs->start(), "in bounds");
179 assert(limit == nullptr || limit <= cs->end(), "in bounds");
180 set_limits(begin, limit);
181 }
182
183 bool RelocIterator::addr_in_const() const {
184 const int n = CodeBuffer::SECT_CONSTS;
185 if (_section_start[n] == nullptr) {
186 return false;
187 }
188 return section_start(n) <= addr() && addr() < section_end(n);
189 }
190
191
192 void RelocIterator::set_limits(address begin, address limit) {
193 _limit = limit;
194
195 // the limit affects this next stuff:
196 if (begin != nullptr) {
197 relocInfo* backup;
198 address backup_addr;
199 while (true) {
200 backup = _current;
201 backup_addr = _addr;
202 if (!next() || addr() >= begin) break;
203 }
204 // At this point, either we are at the first matching record,
205 // or else there is no such record, and !has_current().
206 // In either case, revert to the immediately preceding state.
207 _current = backup;
458 jint offset = unpack_1_int();
459 _static_call = address_from_scaled_offset(offset, base);
460 }
461
462 void trampoline_stub_Relocation::pack_data_to(CodeSection* dest ) {
463 short* p = (short*) dest->locs_end();
464 CodeSection* insts = dest->outer()->insts();
465 normalize_address(_owner, insts);
466 p = pack_1_int_to(p, scaled_offset(_owner, insts->start()));
467 dest->set_locs_end((relocInfo*) p);
468 }
469
470 void trampoline_stub_Relocation::unpack_data() {
471 address base = binding()->section_start(CodeBuffer::SECT_INSTS);
472 _owner = address_from_scaled_offset(unpack_1_int(), base);
473 }
474
475 void external_word_Relocation::pack_data_to(CodeSection* dest) {
476 short* p = (short*) dest->locs_end();
477 int index = ExternalsRecorder::find_index(_target);
478 // Use 4 bytes to store index to be able patch it when
479 // updating relocations in SCCReader::read_relocations().
480 p = add_jint(p, index);
481 dest->set_locs_end((relocInfo*) p);
482 }
483
484 void external_word_Relocation::unpack_data() {
485 int index = unpack_1_int();
486 _target = ExternalsRecorder::at(index);
487 }
488
489
490 void internal_word_Relocation::pack_data_to(CodeSection* dest) {
491 short* p = (short*) dest->locs_end();
492 normalize_address(_target, dest, true);
493
494 // Check whether my target address is valid within this section.
495 // If not, strengthen the relocation type to point to another section.
496 int sindex = _section;
497 if (sindex == CodeBuffer::SECT_NONE && _target != nullptr
498 && (!dest->allocates(_target) || _target == dest->locs_point())) {
499 sindex = dest->outer()->section_index_of(_target);
500 guarantee(sindex != CodeBuffer::SECT_NONE, "must belong somewhere");
501 relocInfo* base = dest->locs_end() - 1;
502 assert(base->type() == this->type(), "sanity");
503 // Change the written type, to be section_word_type instead.
732
733 return nullptr;
734 }
735
736 void static_stub_Relocation::clear_inline_cache() {
737 // Call stub is only used when calling the interpreted code.
738 // It does not really need to be cleared, except that we want to clean out the methodoop.
739 CompiledDirectCall::set_stub_to_clean(this);
740 }
741
742
743 void external_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
744 if (_target != nullptr) {
745 // Probably this reference is absolute, not relative, so the following is
746 // probably a no-op.
747 set_value(_target);
748 }
749 // If target is nullptr, this is an absolute embedded reference to an external
750 // location, which means there is nothing to fix here. In either case, the
751 // resulting target should be an "external" address.
752 #ifdef ASSERT
753 if (SCCache::is_on()) {
754 // SCA needs relocation info for card table base which may point to CodeCache
755 if (is_card_table_address(target())) {
756 return;
757 }
758 }
759 #endif
760 postcond(src->section_index_of(target()) == CodeBuffer::SECT_NONE);
761 postcond(dest->section_index_of(target()) == CodeBuffer::SECT_NONE);
762 }
763
764
765 address external_word_Relocation::target() {
766 address target = _target;
767 if (target == nullptr) {
768 target = pd_get_address_from_code();
769 }
770 return target;
771 }
772
773
774 void internal_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
775 address target = _target;
776 if (target == nullptr) {
777 target = new_addr_for(this->target(), src, dest);
778 }
779 set_value(target);
780 }
781
782 void internal_word_Relocation::fix_relocation_after_aot_load(address orig_base_addr, address current_base_addr) {
783 address target = _target;
784 if (target == nullptr) {
785 target = this->target();
786 target = current_base_addr + (target - orig_base_addr);
787 }
788 set_value(target);
789 }
790
791 address internal_word_Relocation::target() {
792 address target = _target;
793 if (target == nullptr) {
794 if (addr_in_const()) {
795 target = *(address*)addr();
796 } else {
797 target = pd_get_address_from_code();
798 }
799 }
800 return target;
801 }
802
803 const char* relocInfo::type_name(relocInfo::relocType t) {
804 switch (t) {
805 #define EACH_CASE(name) \
806 case relocInfo::name##_type: \
807 return #name;
808
809 APPLY_TO_RELOCATIONS(EACH_CASE);
810 #undef EACH_CASE
811
812 case relocInfo::none:
813 return "none";
814 case relocInfo::data_prefix_tag:
815 return "prefix";
816 default:
817 return "UNKNOWN RELOC TYPE";
818 }
819 }
820
821
822 void RelocIterator::print_current_on(outputStream* st) {
823 if (!has_current()) {
824 st->print_cr("(no relocs)");
825 return;
826 }
827 st->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d",
828 p2i(_current), type(), relocInfo::type_name(type()), p2i(_addr), _current->addr_offset());
829 if (current()->format() != 0)
830 st->print(" format=%d", current()->format());
831 if (datalen() == 1) {
832 st->print(" data=%d", data()[0]);
833 } else if (datalen() > 0) {
834 st->print(" data={");
835 for (int i = 0; i < datalen(); i++) {
836 st->print("%04x", data()[i] & 0xFFFF);
837 }
838 st->print("}");
839 }
840 st->print("]");
841 switch (type()) {
842 case relocInfo::oop_type:
843 {
844 oop_Relocation* r = oop_reloc();
845 oop* oop_addr = nullptr;
846 oop raw_oop = nullptr;
847 oop oop_value = nullptr;
848 if (code() != nullptr || r->oop_is_immediate()) {
849 oop_addr = r->oop_addr();
850 raw_oop = *oop_addr;
851 oop_value = r->oop_value();
852 }
853 st->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " index=%d]",
854 p2i(oop_addr), p2i(raw_oop), r->oop_index());
855 // Do not print the oop by default--we want this routine to
856 // work even during GC or other inconvenient times.
857 if (WizardMode && oop_value != nullptr) {
858 st->print("oop_value=" INTPTR_FORMAT ": ", p2i(oop_value));
859 if (oopDesc::is_oop(oop_value)) {
860 oop_value->print_value_on(st);
861 }
862 }
863 break;
864 }
865 case relocInfo::metadata_type:
866 {
867 metadata_Relocation* r = metadata_reloc();
868 Metadata** metadata_addr = nullptr;
869 Metadata* raw_metadata = nullptr;
870 Metadata* metadata_value = nullptr;
871 if (code() != nullptr || r->metadata_is_immediate()) {
872 metadata_addr = r->metadata_addr();
873 raw_metadata = *metadata_addr;
874 metadata_value = r->metadata_value();
875 }
876 st->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " index=%d]",
877 p2i(metadata_addr), p2i(raw_metadata), r->metadata_index());
878 if (metadata_value != nullptr) {
879 st->print("metadata_value=" INTPTR_FORMAT ": ", p2i(metadata_value));
880 metadata_value->print_value_on(st);
881 }
882 break;
883 }
884 case relocInfo::external_word_type:
885 case relocInfo::internal_word_type:
886 case relocInfo::section_word_type:
887 {
888 DataRelocation* r = (DataRelocation*) reloc();
889 st->print(" | [target=" INTPTR_FORMAT "]", p2i(r->value())); //value==target
890 break;
891 }
892 case relocInfo::static_call_type:
893 {
894 static_call_Relocation* r = (static_call_Relocation*) reloc();
895 st->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
896 p2i(r->destination()), p2i(r->method_value()));
897 CodeBlob* cb = CodeCache::find_blob(r->destination());
898 if (cb != nullptr) {
899 st->print(" Blob::%s", cb->name());
900 }
901 break;
902 }
903 case relocInfo::runtime_call_type:
904 case relocInfo::runtime_call_w_cp_type:
905 {
906 CallRelocation* r = (CallRelocation*) reloc();
907 address dest = r->destination();
908 st->print(" | [destination=" INTPTR_FORMAT "]", p2i(dest));
909 if (StubRoutines::contains(dest)) {
910 StubCodeDesc* desc = StubCodeDesc::desc_for(dest);
911 if (desc == nullptr) {
912 desc = StubCodeDesc::desc_for(dest + frame::pc_return_offset);
913 }
914 if (desc != nullptr) {
915 st->print(" Stub::%s", desc->name());
916 }
917 } else {
918 CodeBlob* cb = CodeCache::find_blob(dest);
919 if (cb != nullptr) {
920 st->print(" Blob::%s", cb->name());
921 } else {
922 ResourceMark rm;
923 const int buflen = 1024;
924 char* buf = NEW_RESOURCE_ARRAY(char, buflen);
925 int offset;
926 if (os::dll_address_to_function_name(dest, buf, buflen, &offset)) {
927 st->print(" %s", buf);
928 if (offset != 0) {
929 st->print("+%d", offset);
930 }
931 }
932 }
933 }
934 break;
935 }
936 case relocInfo::virtual_call_type:
937 {
938 virtual_call_Relocation* r = (virtual_call_Relocation*) reloc();
939 st->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
940 p2i(r->destination()), p2i(r->cached_value()), p2i(r->method_value()));
941 CodeBlob* cb = CodeCache::find_blob(r->destination());
942 if (cb != nullptr) {
943 st->print(" Blob::%s", cb->name());
944 }
945 break;
946 }
947 case relocInfo::static_stub_type:
948 {
949 static_stub_Relocation* r = (static_stub_Relocation*) reloc();
950 st->print(" | [static_call=" INTPTR_FORMAT "]", p2i(r->static_call()));
951 break;
952 }
953 case relocInfo::trampoline_stub_type:
954 {
955 trampoline_stub_Relocation* r = (trampoline_stub_Relocation*) reloc();
956 st->print(" | [trampoline owner=" INTPTR_FORMAT "]", p2i(r->owner()));
957 break;
958 }
959 case relocInfo::opt_virtual_call_type:
960 {
961 opt_virtual_call_Relocation* r = (opt_virtual_call_Relocation*) reloc();
962 st->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
963 p2i(r->destination()), p2i(r->method_value()));
964 CodeBlob* cb = CodeCache::find_blob(r->destination());
965 if (cb != nullptr) {
966 st->print(" Blob::%s", cb->name());
967 }
968 break;
969 }
970 default:
971 break;
972 }
973 st->cr();
974 }
975
976
977 void RelocIterator::print_on(outputStream* st) {
978 RelocIterator save_this = (*this);
979 relocInfo* scan = _current;
980 if (!has_current()) scan += 1; // nothing to scan here!
981
982 bool skip_next = has_current();
983 bool got_next;
984 while (true) {
985 got_next = (skip_next || next());
986 skip_next = false;
987
988 st->print(" @" INTPTR_FORMAT ": ", p2i(scan));
989 relocInfo* newscan = _current+1;
990 if (!has_current()) newscan -= 1; // nothing to scan here!
991 while (scan < newscan) {
992 st->print("%04x", *(short*)scan & 0xFFFF);
993 scan++;
994 }
995 st->cr();
996
997 if (!got_next) break;
998 print_current_on(st);
999 }
1000
1001 (*this) = save_this;
1002 }
1003
1004 //---------------------------------------------------------------------------------
1005 // Non-product code
1006
1007 #ifndef PRODUCT
1008
1009 // For the debugger:
1010 extern "C"
1011 void print_blob_locs(nmethod* nm) {
1012 nm->print();
1013 RelocIterator iter(nm);
1014 iter.print_on(tty);
1015 }
1016 extern "C"
1017 void print_buf_locs(CodeBuffer* cb) {
1018 FlagSetting fs(PrintRelocations, true);
1019 cb->print_on(tty);
1020 }
1021 #endif // !PRODUCT
|