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);