1 /*
2 * Copyright 1997-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
98 bool found = false;
99 while (itr->next() && !found) {
100 if (itr->addr() == pc) {
101 assert(itr->type()==old_type, "wrong relocInfo type found");
102 itr->current()->set_type(new_type);
103 found=true;
104 }
105 }
106 assert(found, "no relocInfo found for pc");
107 }
108
109
110 void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type) {
111 change_reloc_info_for_address(itr, pc, old_type, none);
112 }
113
114
115 // ----------------------------------------------------------------------------------------------------
116 // Implementation of RelocIterator
117
118 void RelocIterator::initialize(CodeBlob* cb, address begin, address limit) {
119 initialize_misc();
120
121 if (cb == NULL && begin != NULL) {
122 // allow CodeBlob to be deduced from beginning address
123 cb = CodeCache::find_blob(begin);
124 }
125 assert(cb != NULL, "must be able to deduce nmethod from other arguments");
126
127 _code = cb;
128 _current = cb->relocation_begin()-1;
129 _end = cb->relocation_end();
130 _addr = (address) cb->instructions_begin();
131
132 assert(!has_current(), "just checking");
133 address code_end = cb->instructions_end();
134
135 assert(begin == NULL || begin >= cb->instructions_begin(), "in bounds");
136 // FIX THIS assert(limit == NULL || limit <= code_end, "in bounds");
137 set_limits(begin, limit);
138 }
139
140
141 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
142 initialize_misc();
143
144 _current = cs->locs_start()-1;
145 _end = cs->locs_end();
146 _addr = cs->start();
147 _code = NULL; // Not cb->blob();
148
149 CodeBuffer* cb = cs->outer();
150 assert((int)SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
151 for (int n = 0; n < (int)SECT_LIMIT; n++) {
152 _section_start[n] = cb->code_section(n)->start();
153 }
154
155 assert(!has_current(), "just checking");
737
738 int targetlen = datalen() - 1 - instrlen();
739 jint target_bits = 0;
740 if (targetlen == 0) target_bits = 0;
741 else if (targetlen == 1) target_bits = *(data()+1);
742 else if (targetlen == 2) target_bits = relocInfo::jint_from_data(data()+1);
743 else { ShouldNotReachHere(); }
744
745 _target = internal() ? address_from_scaled_offset(target_bits, addr())
746 : index_to_runtime_address (target_bits);
747 }
748
749
750 //// miscellaneous methods
751 oop* oop_Relocation::oop_addr() {
752 int n = _oop_index;
753 if (n == 0) {
754 // oop is stored in the code stream
755 return (oop*) pd_address_in_code();
756 } else {
757 // oop is stored in table at CodeBlob::oops_begin
758 return code()->oop_addr_at(n);
759 }
760 }
761
762
763 oop oop_Relocation::oop_value() {
764 oop v = *oop_addr();
765 // clean inline caches store a special pseudo-null
766 if (v == (oop)Universe::non_oop_word()) v = NULL;
767 return v;
768 }
769
770
771 void oop_Relocation::fix_oop_relocation() {
772 if (!oop_is_immediate()) {
773 // get the oop from the pool, and re-insert it into the instruction:
774 set_value(value());
775 }
776 }
777
778
779 RelocIterator virtual_call_Relocation::parse_ic(CodeBlob* &code, address &ic_call, address &first_oop,
780 oop* &oop_addr, bool *is_optimized) {
781 assert(ic_call != NULL, "ic_call address must be set");
782 assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input");
783 if (code == NULL) {
784 if (ic_call != NULL) {
785 code = CodeCache::find_blob(ic_call);
786 } else if (first_oop != NULL) {
787 code = CodeCache::find_blob(first_oop);
788 }
789 assert(code != NULL, "address to parse must be in CodeBlob");
790 }
791 assert(ic_call == NULL || code->contains(ic_call), "must be in CodeBlob");
792 assert(first_oop == NULL || code->contains(first_oop), "must be in CodeBlob");
793
794 address oop_limit = NULL;
795
796 if (ic_call != NULL) {
797 // search for the ic_call at the given address
798 RelocIterator iter(code, ic_call, ic_call+1);
799 bool ret = iter.next();
800 assert(ret == true, "relocInfo must exist at this address");
801 assert(iter.addr() == ic_call, "must find ic_call");
802 if (iter.type() == relocInfo::virtual_call_type) {
803 virtual_call_Relocation* r = iter.virtual_call_reloc();
804 first_oop = r->first_oop();
805 oop_limit = r->oop_limit();
806 *is_optimized = false;
807 } else {
808 assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
809 *is_optimized = true;
810 oop_addr = NULL;
811 first_oop = NULL;
812 return iter;
813 }
814 }
815
816 // search for the first_oop, to get its oop_addr
817 RelocIterator all_oops(code, first_oop);
818 RelocIterator iter = all_oops;
819 iter.set_limit(first_oop+1);
820 bool found_oop = false;
821 while (iter.next()) {
822 if (iter.type() == relocInfo::oop_type) {
823 assert(iter.addr() == first_oop, "must find first_oop");
824 oop_addr = iter.oop_reloc()->oop_addr();
825 found_oop = true;
826 break;
827 }
828 }
829 assert(found_oop, "must find first_oop");
830
831 bool did_reset = false;
832 while (ic_call == NULL) {
833 // search forward for the ic_call matching the given first_oop
834 while (iter.next()) {
835 if (iter.type() == relocInfo::virtual_call_type) {
836 virtual_call_Relocation* r = iter.virtual_call_reloc();
837 if (r->first_oop() == first_oop) {
838 ic_call = r->addr();
839 oop_limit = r->oop_limit();
840 break;
841 }
842 }
843 }
844 guarantee(!did_reset, "cannot find ic_call");
845 iter = RelocIterator(code); // search the whole CodeBlob
846 did_reset = true;
847 }
848
849 assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, "");
850 all_oops.set_limit(oop_limit);
851 return all_oops;
852 }
853
854
855 address virtual_call_Relocation::first_oop() {
856 assert(_first_oop != NULL && _first_oop < addr(), "must precede ic_call");
857 return _first_oop;
858 }
859
860
861 address virtual_call_Relocation::oop_limit() {
862 if (_oop_limit == NULL)
863 return addr() + NativeCall::instruction_size;
864 else
865 return _oop_limit;
1158 skip_next = false;
1159
1160 tty->print(" @" INTPTR_FORMAT ": ", scan);
1161 relocInfo* newscan = _current+1;
1162 if (!has_current()) newscan -= 1; // nothing to scan here!
1163 while (scan < newscan) {
1164 tty->print("%04x", *(short*)scan & 0xFFFF);
1165 scan++;
1166 }
1167 tty->cr();
1168
1169 if (!got_next) break;
1170 print_current();
1171 }
1172
1173 (*this) = save_this;
1174 }
1175
1176 // For the debugger:
1177 extern "C"
1178 void print_blob_locs(CodeBlob* cb) {
1179 cb->print();
1180 RelocIterator iter(cb);
1181 iter.print();
1182 }
1183 extern "C"
1184 void print_buf_locs(CodeBuffer* cb) {
1185 FlagSetting fs(PrintRelocations, true);
1186 cb->print();
1187 }
1188 #endif // !PRODUCT
|
1 /*
2 * Copyright 1997-2010 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
98 bool found = false;
99 while (itr->next() && !found) {
100 if (itr->addr() == pc) {
101 assert(itr->type()==old_type, "wrong relocInfo type found");
102 itr->current()->set_type(new_type);
103 found=true;
104 }
105 }
106 assert(found, "no relocInfo found for pc");
107 }
108
109
110 void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type) {
111 change_reloc_info_for_address(itr, pc, old_type, none);
112 }
113
114
115 // ----------------------------------------------------------------------------------------------------
116 // Implementation of RelocIterator
117
118 void RelocIterator::initialize(nmethod* nm, address begin, address limit) {
119 initialize_misc();
120
121 if (nm == NULL && begin != NULL) {
122 // allow nmethod to be deduced from beginning address
123 CodeBlob* cb = CodeCache::find_blob(begin);
124 nm = cb->as_nmethod_or_null();
125 }
126 assert(nm != NULL, "must be able to deduce nmethod from other arguments");
127
128 _code = nm;
129 _current = nm->relocation_begin() - 1;
130 _end = nm->relocation_end();
131 _addr = (address) nm->instructions_begin();
132
133 assert(!has_current(), "just checking");
134 address code_end = nm->instructions_end();
135
136 assert(begin == NULL || begin >= nm->instructions_begin(), "in bounds");
137 // FIX THIS assert(limit == NULL || limit <= code_end, "in bounds");
138 set_limits(begin, limit);
139 }
140
141
142 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) {
143 initialize_misc();
144
145 _current = cs->locs_start()-1;
146 _end = cs->locs_end();
147 _addr = cs->start();
148 _code = NULL; // Not cb->blob();
149
150 CodeBuffer* cb = cs->outer();
151 assert((int)SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal");
152 for (int n = 0; n < (int)SECT_LIMIT; n++) {
153 _section_start[n] = cb->code_section(n)->start();
154 }
155
156 assert(!has_current(), "just checking");
738
739 int targetlen = datalen() - 1 - instrlen();
740 jint target_bits = 0;
741 if (targetlen == 0) target_bits = 0;
742 else if (targetlen == 1) target_bits = *(data()+1);
743 else if (targetlen == 2) target_bits = relocInfo::jint_from_data(data()+1);
744 else { ShouldNotReachHere(); }
745
746 _target = internal() ? address_from_scaled_offset(target_bits, addr())
747 : index_to_runtime_address (target_bits);
748 }
749
750
751 //// miscellaneous methods
752 oop* oop_Relocation::oop_addr() {
753 int n = _oop_index;
754 if (n == 0) {
755 // oop is stored in the code stream
756 return (oop*) pd_address_in_code();
757 } else {
758 // oop is stored in table at nmethod::oops_begin
759 return code()->oop_addr_at(n);
760 }
761 }
762
763
764 oop oop_Relocation::oop_value() {
765 oop v = *oop_addr();
766 // clean inline caches store a special pseudo-null
767 if (v == (oop)Universe::non_oop_word()) v = NULL;
768 return v;
769 }
770
771
772 void oop_Relocation::fix_oop_relocation() {
773 if (!oop_is_immediate()) {
774 // get the oop from the pool, and re-insert it into the instruction:
775 set_value(value());
776 }
777 }
778
779
780 RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop,
781 oop* &oop_addr, bool *is_optimized) {
782 assert(ic_call != NULL, "ic_call address must be set");
783 assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input");
784 if (nm == NULL) {
785 CodeBlob* code;
786 if (ic_call != NULL) {
787 code = CodeCache::find_blob(ic_call);
788 } else if (first_oop != NULL) {
789 code = CodeCache::find_blob(first_oop);
790 }
791 nm = code->as_nmethod_or_null();
792 assert(nm != NULL, "address to parse must be in nmethod");
793 }
794 assert(ic_call == NULL || nm->contains(ic_call), "must be in nmethod");
795 assert(first_oop == NULL || nm->contains(first_oop), "must be in nmethod");
796
797 address oop_limit = NULL;
798
799 if (ic_call != NULL) {
800 // search for the ic_call at the given address
801 RelocIterator iter(nm, ic_call, ic_call+1);
802 bool ret = iter.next();
803 assert(ret == true, "relocInfo must exist at this address");
804 assert(iter.addr() == ic_call, "must find ic_call");
805 if (iter.type() == relocInfo::virtual_call_type) {
806 virtual_call_Relocation* r = iter.virtual_call_reloc();
807 first_oop = r->first_oop();
808 oop_limit = r->oop_limit();
809 *is_optimized = false;
810 } else {
811 assert(iter.type() == relocInfo::opt_virtual_call_type, "must be a virtual call");
812 *is_optimized = true;
813 oop_addr = NULL;
814 first_oop = NULL;
815 return iter;
816 }
817 }
818
819 // search for the first_oop, to get its oop_addr
820 RelocIterator all_oops(nm, first_oop);
821 RelocIterator iter = all_oops;
822 iter.set_limit(first_oop+1);
823 bool found_oop = false;
824 while (iter.next()) {
825 if (iter.type() == relocInfo::oop_type) {
826 assert(iter.addr() == first_oop, "must find first_oop");
827 oop_addr = iter.oop_reloc()->oop_addr();
828 found_oop = true;
829 break;
830 }
831 }
832 assert(found_oop, "must find first_oop");
833
834 bool did_reset = false;
835 while (ic_call == NULL) {
836 // search forward for the ic_call matching the given first_oop
837 while (iter.next()) {
838 if (iter.type() == relocInfo::virtual_call_type) {
839 virtual_call_Relocation* r = iter.virtual_call_reloc();
840 if (r->first_oop() == first_oop) {
841 ic_call = r->addr();
842 oop_limit = r->oop_limit();
843 break;
844 }
845 }
846 }
847 guarantee(!did_reset, "cannot find ic_call");
848 iter = RelocIterator(nm); // search the whole nmethod
849 did_reset = true;
850 }
851
852 assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, "");
853 all_oops.set_limit(oop_limit);
854 return all_oops;
855 }
856
857
858 address virtual_call_Relocation::first_oop() {
859 assert(_first_oop != NULL && _first_oop < addr(), "must precede ic_call");
860 return _first_oop;
861 }
862
863
864 address virtual_call_Relocation::oop_limit() {
865 if (_oop_limit == NULL)
866 return addr() + NativeCall::instruction_size;
867 else
868 return _oop_limit;
1161 skip_next = false;
1162
1163 tty->print(" @" INTPTR_FORMAT ": ", scan);
1164 relocInfo* newscan = _current+1;
1165 if (!has_current()) newscan -= 1; // nothing to scan here!
1166 while (scan < newscan) {
1167 tty->print("%04x", *(short*)scan & 0xFFFF);
1168 scan++;
1169 }
1170 tty->cr();
1171
1172 if (!got_next) break;
1173 print_current();
1174 }
1175
1176 (*this) = save_this;
1177 }
1178
1179 // For the debugger:
1180 extern "C"
1181 void print_blob_locs(nmethod* nm) {
1182 nm->print();
1183 RelocIterator iter(nm);
1184 iter.print();
1185 }
1186 extern "C"
1187 void print_buf_locs(CodeBuffer* cb) {
1188 FlagSetting fs(PrintRelocations, true);
1189 cb->print();
1190 }
1191 #endif // !PRODUCT
|