1 /* |
1 /* |
2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. |
2 * Copyright 1997-2010 Sun Microsystems, Inc. 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. |
113 |
113 |
114 |
114 |
115 // ---------------------------------------------------------------------------------------------------- |
115 // ---------------------------------------------------------------------------------------------------- |
116 // Implementation of RelocIterator |
116 // Implementation of RelocIterator |
117 |
117 |
118 void RelocIterator::initialize(CodeBlob* cb, address begin, address limit) { |
118 void RelocIterator::initialize(nmethod* nm, address begin, address limit) { |
119 initialize_misc(); |
119 initialize_misc(); |
120 |
120 |
121 if (cb == NULL && begin != NULL) { |
121 if (nm == NULL && begin != NULL) { |
122 // allow CodeBlob to be deduced from beginning address |
122 // allow nmethod to be deduced from beginning address |
123 cb = CodeCache::find_blob(begin); |
123 CodeBlob* cb = CodeCache::find_blob(begin); |
124 } |
124 nm = cb->as_nmethod_or_null(); |
125 assert(cb != NULL, "must be able to deduce nmethod from other arguments"); |
125 } |
126 |
126 assert(nm != NULL, "must be able to deduce nmethod from other arguments"); |
127 _code = cb; |
127 |
128 _current = cb->relocation_begin()-1; |
128 _code = nm; |
129 _end = cb->relocation_end(); |
129 _current = nm->relocation_begin() - 1; |
130 _addr = (address) cb->instructions_begin(); |
130 _end = nm->relocation_end(); |
|
131 _addr = (address) nm->instructions_begin(); |
131 |
132 |
132 assert(!has_current(), "just checking"); |
133 assert(!has_current(), "just checking"); |
133 address code_end = cb->instructions_end(); |
134 address code_end = nm->instructions_end(); |
134 |
135 |
135 assert(begin == NULL || begin >= cb->instructions_begin(), "in bounds"); |
136 assert(begin == NULL || begin >= nm->instructions_begin(), "in bounds"); |
136 // FIX THIS assert(limit == NULL || limit <= code_end, "in bounds"); |
137 // FIX THIS assert(limit == NULL || limit <= code_end, "in bounds"); |
137 set_limits(begin, limit); |
138 set_limits(begin, limit); |
138 } |
139 } |
139 |
140 |
140 |
141 |
774 set_value(value()); |
775 set_value(value()); |
775 } |
776 } |
776 } |
777 } |
777 |
778 |
778 |
779 |
779 RelocIterator virtual_call_Relocation::parse_ic(CodeBlob* &code, address &ic_call, address &first_oop, |
780 RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop, |
780 oop* &oop_addr, bool *is_optimized) { |
781 oop* &oop_addr, bool *is_optimized) { |
781 assert(ic_call != NULL, "ic_call address must be set"); |
782 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 assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input"); |
783 if (code == NULL) { |
784 if (nm == NULL) { |
|
785 CodeBlob* code; |
784 if (ic_call != NULL) { |
786 if (ic_call != NULL) { |
785 code = CodeCache::find_blob(ic_call); |
787 code = CodeCache::find_blob(ic_call); |
786 } else if (first_oop != NULL) { |
788 } else if (first_oop != NULL) { |
787 code = CodeCache::find_blob(first_oop); |
789 code = CodeCache::find_blob(first_oop); |
788 } |
790 } |
789 assert(code != NULL, "address to parse must be in CodeBlob"); |
791 nm = code->as_nmethod_or_null(); |
790 } |
792 assert(nm != NULL, "address to parse must be in nmethod"); |
791 assert(ic_call == NULL || code->contains(ic_call), "must be in CodeBlob"); |
793 } |
792 assert(first_oop == NULL || code->contains(first_oop), "must be in CodeBlob"); |
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"); |
793 |
796 |
794 address oop_limit = NULL; |
797 address oop_limit = NULL; |
795 |
798 |
796 if (ic_call != NULL) { |
799 if (ic_call != NULL) { |
797 // search for the ic_call at the given address |
800 // search for the ic_call at the given address |
798 RelocIterator iter(code, ic_call, ic_call+1); |
801 RelocIterator iter(nm, ic_call, ic_call+1); |
799 bool ret = iter.next(); |
802 bool ret = iter.next(); |
800 assert(ret == true, "relocInfo must exist at this address"); |
803 assert(ret == true, "relocInfo must exist at this address"); |
801 assert(iter.addr() == ic_call, "must find ic_call"); |
804 assert(iter.addr() == ic_call, "must find ic_call"); |
802 if (iter.type() == relocInfo::virtual_call_type) { |
805 if (iter.type() == relocInfo::virtual_call_type) { |
803 virtual_call_Relocation* r = iter.virtual_call_reloc(); |
806 virtual_call_Relocation* r = iter.virtual_call_reloc(); |
812 return iter; |
815 return iter; |
813 } |
816 } |
814 } |
817 } |
815 |
818 |
816 // search for the first_oop, to get its oop_addr |
819 // search for the first_oop, to get its oop_addr |
817 RelocIterator all_oops(code, first_oop); |
820 RelocIterator all_oops(nm, first_oop); |
818 RelocIterator iter = all_oops; |
821 RelocIterator iter = all_oops; |
819 iter.set_limit(first_oop+1); |
822 iter.set_limit(first_oop+1); |
820 bool found_oop = false; |
823 bool found_oop = false; |
821 while (iter.next()) { |
824 while (iter.next()) { |
822 if (iter.type() == relocInfo::oop_type) { |
825 if (iter.type() == relocInfo::oop_type) { |
1173 (*this) = save_this; |
1176 (*this) = save_this; |
1174 } |
1177 } |
1175 |
1178 |
1176 // For the debugger: |
1179 // For the debugger: |
1177 extern "C" |
1180 extern "C" |
1178 void print_blob_locs(CodeBlob* cb) { |
1181 void print_blob_locs(nmethod* nm) { |
1179 cb->print(); |
1182 nm->print(); |
1180 RelocIterator iter(cb); |
1183 RelocIterator iter(nm); |
1181 iter.print(); |
1184 iter.print(); |
1182 } |
1185 } |
1183 extern "C" |
1186 extern "C" |
1184 void print_buf_locs(CodeBuffer* cb) { |
1187 void print_buf_locs(CodeBuffer* cb) { |
1185 FlagSetting fs(PrintRelocations, true); |
1188 FlagSetting fs(PrintRelocations, true); |