Mercurial > hg > truffle
comparison src/share/vm/code/relocInfo.cpp @ 1930:2d26b0046e0d
Merge.
author | Thomas Wuerthinger <wuerthinger@ssw.jku.at> |
---|---|
date | Tue, 30 Nov 2010 14:53:30 +0100 |
parents | 0878d7bae69f |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1484:6b7001391c97 | 1930:2d26b0046e0d |
---|---|
1 /* | 1 /* |
2 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. | 2 * Copyright (c) 1997, 2010, 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. |
14 * | 14 * |
15 * You should have received a copy of the GNU General Public License version | 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, | 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. | 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 * | 18 * |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | 20 * or visit www.oracle.com if you need additional information or have any |
21 * have any questions. | 21 * questions. |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 # include "incls/_precompiled.incl" | 25 # include "incls/_precompiled.incl" |
26 # include "incls/_relocInfo.cpp.incl" | 26 # include "incls/_relocInfo.cpp.incl" |
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 = nm->content_begin(); | |
132 | |
133 // Initialize code sections. | |
134 _section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin(); | |
135 _section_start[CodeBuffer::SECT_INSTS ] = nm->insts_begin() ; | |
136 _section_start[CodeBuffer::SECT_STUBS ] = nm->stub_begin() ; | |
137 | |
138 _section_end [CodeBuffer::SECT_CONSTS] = nm->consts_end() ; | |
139 _section_end [CodeBuffer::SECT_INSTS ] = nm->insts_end() ; | |
140 _section_end [CodeBuffer::SECT_STUBS ] = nm->stub_end() ; | |
131 | 141 |
132 assert(!has_current(), "just checking"); | 142 assert(!has_current(), "just checking"); |
133 address code_end = cb->instructions_end(); | 143 assert(begin == NULL || begin >= nm->code_begin(), "in bounds"); |
134 | 144 assert(limit == NULL || limit <= nm->code_end(), "in bounds"); |
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); | 145 set_limits(begin, limit); |
138 } | 146 } |
139 | 147 |
140 | 148 |
141 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) { | 149 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) { |
145 _end = cs->locs_end(); | 153 _end = cs->locs_end(); |
146 _addr = cs->start(); | 154 _addr = cs->start(); |
147 _code = NULL; // Not cb->blob(); | 155 _code = NULL; // Not cb->blob(); |
148 | 156 |
149 CodeBuffer* cb = cs->outer(); | 157 CodeBuffer* cb = cs->outer(); |
150 assert((int)SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal"); | 158 assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal"); |
151 for (int n = 0; n < (int)SECT_LIMIT; n++) { | 159 for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) { |
152 _section_start[n] = cb->code_section(n)->start(); | 160 CodeSection* cs = cb->code_section(n); |
161 _section_start[n] = cs->start(); | |
162 _section_end [n] = cs->end(); | |
153 } | 163 } |
154 | 164 |
155 assert(!has_current(), "just checking"); | 165 assert(!has_current(), "just checking"); |
156 | 166 |
157 assert(begin == NULL || begin >= cs->start(), "in bounds"); | 167 assert(begin == NULL || begin >= cs->start(), "in bounds"); |
163 enum { indexCardSize = 128 }; | 173 enum { indexCardSize = 128 }; |
164 struct RelocIndexEntry { | 174 struct RelocIndexEntry { |
165 jint addr_offset; // offset from header_end of an addr() | 175 jint addr_offset; // offset from header_end of an addr() |
166 jint reloc_offset; // offset from header_end of a relocInfo (prefix) | 176 jint reloc_offset; // offset from header_end of a relocInfo (prefix) |
167 }; | 177 }; |
178 | |
179 | |
180 bool RelocIterator::addr_in_const() const { | |
181 const int n = CodeBuffer::SECT_CONSTS; | |
182 return section_start(n) <= addr() && addr() < section_end(n); | |
183 } | |
168 | 184 |
169 | 185 |
170 static inline int num_cards(int code_size) { | 186 static inline int num_cards(int code_size) { |
171 return (code_size-1) / indexCardSize; | 187 return (code_size-1) / indexCardSize; |
172 } | 188 } |
264 #endif // ASSERT | 280 #endif // ASSERT |
265 if (index_size > 0) { | 281 if (index_size > 0) { |
266 // skip ahead | 282 // skip ahead |
267 RelocIndexEntry* index = (RelocIndexEntry*)_end; | 283 RelocIndexEntry* index = (RelocIndexEntry*)_end; |
268 RelocIndexEntry* index_limit = (RelocIndexEntry*)((address)index + index_size); | 284 RelocIndexEntry* index_limit = (RelocIndexEntry*)((address)index + index_size); |
269 assert(_addr == _code->instructions_begin(), "_addr must be unadjusted"); | 285 assert(_addr == _code->code_begin(), "_addr must be unadjusted"); |
270 int card = (begin - _addr) / indexCardSize; | 286 int card = (begin - _addr) / indexCardSize; |
271 if (card > 0) { | 287 if (card > 0) { |
272 if (index+card-1 < index_limit) index += card-1; | 288 if (index+card-1 < index_limit) index += card-1; |
273 else index = index_limit - 1; | 289 else index = index_limit - 1; |
274 #ifdef ASSERT | 290 #ifdef ASSERT |
359 // The client will see the following relocInfo, whatever that is. | 375 // The client will see the following relocInfo, whatever that is. |
360 // It is the reloc to which the preceding data applies. | 376 // It is the reloc to which the preceding data applies. |
361 } | 377 } |
362 | 378 |
363 | 379 |
364 address RelocIterator::compute_section_start(int n) const { | 380 void RelocIterator::initialize_misc() { |
365 // This routine not only computes a section start, but also | 381 set_has_current(false); |
366 // memoizes it for later. | 382 for (int i = (int) CodeBuffer::SECT_FIRST; i < (int) CodeBuffer::SECT_LIMIT; i++) { |
367 #define CACHE ((RelocIterator*)this)->_section_start[n] | 383 _section_start[i] = NULL; // these will be lazily computed, if needed |
368 CodeBlob* cb = code(); | 384 _section_end [i] = NULL; |
369 guarantee(cb != NULL, "must have a code blob"); | 385 } |
370 if (n == CodeBuffer::SECT_INSTS) | |
371 return CACHE = cb->instructions_begin(); | |
372 assert(cb->is_nmethod(), "only nmethods have these sections"); | |
373 nmethod* nm = (nmethod*) cb; | |
374 address res = NULL; | |
375 switch (n) { | |
376 case CodeBuffer::SECT_STUBS: | |
377 res = nm->stub_begin(); | |
378 break; | |
379 case CodeBuffer::SECT_CONSTS: | |
380 res = nm->consts_begin(); | |
381 break; | |
382 default: | |
383 ShouldNotReachHere(); | |
384 } | |
385 assert(nm->contains(res) || res == nm->instructions_end(), "tame pointer"); | |
386 CACHE = res; | |
387 return res; | |
388 #undef CACHE | |
389 } | 386 } |
390 | 387 |
391 | 388 |
392 Relocation* RelocIterator::reloc() { | 389 Relocation* RelocIterator::reloc() { |
393 // (take the "switch" out-of-line) | 390 // (take the "switch" out-of-line) |
752 int n = _oop_index; | 749 int n = _oop_index; |
753 if (n == 0) { | 750 if (n == 0) { |
754 // oop is stored in the code stream | 751 // oop is stored in the code stream |
755 return (oop*) pd_address_in_code(); | 752 return (oop*) pd_address_in_code(); |
756 } else { | 753 } else { |
757 // oop is stored in table at CodeBlob::oops_begin | 754 // oop is stored in table at nmethod::oops_begin |
758 return code()->oop_addr_at(n); | 755 return code()->oop_addr_at(n); |
759 } | 756 } |
760 } | 757 } |
761 | 758 |
762 | 759 |
774 set_value(value()); | 771 set_value(value()); |
775 } | 772 } |
776 } | 773 } |
777 | 774 |
778 | 775 |
779 RelocIterator virtual_call_Relocation::parse_ic(CodeBlob* &code, address &ic_call, address &first_oop, | 776 RelocIterator virtual_call_Relocation::parse_ic(nmethod* &nm, address &ic_call, address &first_oop, |
780 oop* &oop_addr, bool *is_optimized) { | 777 oop* &oop_addr, bool *is_optimized) { |
781 assert(ic_call != NULL, "ic_call address must be set"); | 778 assert(ic_call != NULL, "ic_call address must be set"); |
782 assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input"); | 779 assert(ic_call != NULL || first_oop != NULL, "must supply a non-null input"); |
783 if (code == NULL) { | 780 if (nm == NULL) { |
781 CodeBlob* code; | |
784 if (ic_call != NULL) { | 782 if (ic_call != NULL) { |
785 code = CodeCache::find_blob(ic_call); | 783 code = CodeCache::find_blob(ic_call); |
786 } else if (first_oop != NULL) { | 784 } else if (first_oop != NULL) { |
787 code = CodeCache::find_blob(first_oop); | 785 code = CodeCache::find_blob(first_oop); |
788 } | 786 } |
789 assert(code != NULL, "address to parse must be in CodeBlob"); | 787 nm = code->as_nmethod_or_null(); |
790 } | 788 assert(nm != NULL, "address to parse must be in nmethod"); |
791 assert(ic_call == NULL || code->contains(ic_call), "must be in CodeBlob"); | 789 } |
792 assert(first_oop == NULL || code->contains(first_oop), "must be in CodeBlob"); | 790 assert(ic_call == NULL || nm->contains(ic_call), "must be in nmethod"); |
791 assert(first_oop == NULL || nm->contains(first_oop), "must be in nmethod"); | |
793 | 792 |
794 address oop_limit = NULL; | 793 address oop_limit = NULL; |
795 | 794 |
796 if (ic_call != NULL) { | 795 if (ic_call != NULL) { |
797 // search for the ic_call at the given address | 796 // search for the ic_call at the given address |
798 RelocIterator iter(code, ic_call, ic_call+1); | 797 RelocIterator iter(nm, ic_call, ic_call+1); |
799 bool ret = iter.next(); | 798 bool ret = iter.next(); |
800 assert(ret == true, "relocInfo must exist at this address"); | 799 assert(ret == true, "relocInfo must exist at this address"); |
801 assert(iter.addr() == ic_call, "must find ic_call"); | 800 assert(iter.addr() == ic_call, "must find ic_call"); |
802 if (iter.type() == relocInfo::virtual_call_type) { | 801 if (iter.type() == relocInfo::virtual_call_type) { |
803 virtual_call_Relocation* r = iter.virtual_call_reloc(); | 802 virtual_call_Relocation* r = iter.virtual_call_reloc(); |
812 return iter; | 811 return iter; |
813 } | 812 } |
814 } | 813 } |
815 | 814 |
816 // search for the first_oop, to get its oop_addr | 815 // search for the first_oop, to get its oop_addr |
817 RelocIterator all_oops(code, first_oop); | 816 RelocIterator all_oops(nm, first_oop); |
818 RelocIterator iter = all_oops; | 817 RelocIterator iter = all_oops; |
819 iter.set_limit(first_oop+1); | 818 iter.set_limit(first_oop+1); |
820 bool found_oop = false; | 819 bool found_oop = false; |
821 while (iter.next()) { | 820 while (iter.next()) { |
822 if (iter.type() == relocInfo::oop_type) { | 821 if (iter.type() == relocInfo::oop_type) { |
840 break; | 839 break; |
841 } | 840 } |
842 } | 841 } |
843 } | 842 } |
844 guarantee(!did_reset, "cannot find ic_call"); | 843 guarantee(!did_reset, "cannot find ic_call"); |
845 iter = RelocIterator(code); // search the whole CodeBlob | 844 iter = RelocIterator(nm); // search the whole nmethod |
846 did_reset = true; | 845 did_reset = true; |
847 } | 846 } |
848 | 847 |
849 assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, ""); | 848 assert(oop_limit != NULL && first_oop != NULL && ic_call != NULL, ""); |
850 all_oops.set_limit(oop_limit); | 849 all_oops.set_limit(oop_limit); |
1173 (*this) = save_this; | 1172 (*this) = save_this; |
1174 } | 1173 } |
1175 | 1174 |
1176 // For the debugger: | 1175 // For the debugger: |
1177 extern "C" | 1176 extern "C" |
1178 void print_blob_locs(CodeBlob* cb) { | 1177 void print_blob_locs(nmethod* nm) { |
1179 cb->print(); | 1178 nm->print(); |
1180 RelocIterator iter(cb); | 1179 RelocIterator iter(nm); |
1181 iter.print(); | 1180 iter.print(); |
1182 } | 1181 } |
1183 extern "C" | 1182 extern "C" |
1184 void print_buf_locs(CodeBuffer* cb) { | 1183 void print_buf_locs(CodeBuffer* cb) { |
1185 FlagSetting fs(PrintRelocations, true); | 1184 FlagSetting fs(PrintRelocations, true); |