Mercurial > hg > truffle
annotate src/share/vm/code/relocInfo.cpp @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | 55fb97c4c58d |
children | abec000618bf |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
11041
diff
changeset
|
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
7199
cd3d6a6b95d9
8003240: x86: move MacroAssembler into separate file
twisti
parents:
6725
diff
changeset
|
26 #include "code/codeCache.hpp" |
1972 | 27 #include "code/compiledIC.hpp" |
28 #include "code/nmethod.hpp" | |
29 #include "code/relocInfo.hpp" | |
30 #include "memory/resourceArea.hpp" | |
31 #include "runtime/stubCodeGenerator.hpp" | |
32 #include "utilities/copy.hpp" | |
0 | 33 |
34 | |
35 const RelocationHolder RelocationHolder::none; // its type is relocInfo::none | |
36 | |
37 | |
38 // Implementation of relocInfo | |
39 | |
40 #ifdef ASSERT | |
41 relocInfo::relocInfo(relocType t, int off, int f) { | |
42 assert(t != data_prefix_tag, "cannot build a prefix this way"); | |
43 assert((t & type_mask) == t, "wrong type"); | |
44 assert((f & format_mask) == f, "wrong format"); | |
45 assert(off >= 0 && off < offset_limit(), "offset out off bounds"); | |
46 assert((off & (offset_unit-1)) == 0, "misaligned offset"); | |
47 (*this) = relocInfo(t, RAW_BITS, off, f); | |
48 } | |
49 #endif | |
50 | |
51 void relocInfo::initialize(CodeSection* dest, Relocation* reloc) { | |
52 relocInfo* data = this+1; // here's where the data might go | |
53 dest->set_locs_end(data); // sync end: the next call may read dest.locs_end | |
54 reloc->pack_data_to(dest); // maybe write data into locs, advancing locs_end | |
55 relocInfo* data_limit = dest->locs_end(); | |
56 if (data_limit > data) { | |
57 relocInfo suffix = (*this); | |
58 data_limit = this->finish_prefix((short*) data_limit); | |
59 // Finish up with the suffix. (Hack note: pack_data_to might edit this.) | |
60 *data_limit = suffix; | |
61 dest->set_locs_end(data_limit+1); | |
62 } | |
63 } | |
64 | |
65 relocInfo* relocInfo::finish_prefix(short* prefix_limit) { | |
66 assert(sizeof(relocInfo) == sizeof(short), "change this code"); | |
67 short* p = (short*)(this+1); | |
68 assert(prefix_limit >= p, "must be a valid span of data"); | |
69 int plen = prefix_limit - p; | |
70 if (plen == 0) { | |
71 debug_only(_value = 0xFFFF); | |
72 return this; // no data: remove self completely | |
73 } | |
74 if (plen == 1 && fits_into_immediate(p[0])) { | |
75 (*this) = immediate_relocInfo(p[0]); // move data inside self | |
76 return this+1; | |
77 } | |
78 // cannot compact, so just update the count and return the limit pointer | |
79 (*this) = prefix_relocInfo(plen); // write new datalen | |
80 assert(data() + datalen() == prefix_limit, "pointers must line up"); | |
81 return (relocInfo*)prefix_limit; | |
82 } | |
83 | |
84 | |
85 void relocInfo::set_type(relocType t) { | |
86 int old_offset = addr_offset(); | |
87 int old_format = format(); | |
88 (*this) = relocInfo(t, old_offset, old_format); | |
89 assert(type()==(int)t, "sanity check"); | |
90 assert(addr_offset()==old_offset, "sanity check"); | |
91 assert(format()==old_format, "sanity check"); | |
92 } | |
93 | |
94 | |
95 void relocInfo::set_format(int f) { | |
96 int old_offset = addr_offset(); | |
97 assert((f & format_mask) == f, "wrong format"); | |
98 _value = (_value & ~(format_mask << offset_width)) | (f << offset_width); | |
99 assert(addr_offset()==old_offset, "sanity check"); | |
100 } | |
101 | |
102 | |
103 void relocInfo::change_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type, relocType new_type) { | |
104 bool found = false; | |
105 while (itr->next() && !found) { | |
106 if (itr->addr() == pc) { | |
107 assert(itr->type()==old_type, "wrong relocInfo type found"); | |
108 itr->current()->set_type(new_type); | |
109 found=true; | |
110 } | |
111 } | |
112 assert(found, "no relocInfo found for pc"); | |
113 } | |
114 | |
115 | |
116 void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type) { | |
117 change_reloc_info_for_address(itr, pc, old_type, none); | |
118 } | |
119 | |
120 | |
121 // ---------------------------------------------------------------------------------------------------- | |
122 // Implementation of RelocIterator | |
123 | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
124 void RelocIterator::initialize(nmethod* nm, address begin, address limit) { |
0 | 125 initialize_misc(); |
126 | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
127 if (nm == NULL && begin != NULL) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
128 // allow nmethod to be deduced from beginning address |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
129 CodeBlob* cb = CodeCache::find_blob(begin); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
130 nm = cb->as_nmethod_or_null(); |
0 | 131 } |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
132 assert(nm != NULL, "must be able to deduce nmethod from other arguments"); |
0 | 133 |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
134 _code = nm; |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
135 _current = nm->relocation_begin() - 1; |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
136 _end = nm->relocation_end(); |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
137 _addr = nm->content_begin(); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
138 |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
139 // Initialize code sections. |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
140 _section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin(); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
141 _section_start[CodeBuffer::SECT_INSTS ] = nm->insts_begin() ; |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
142 _section_start[CodeBuffer::SECT_STUBS ] = nm->stub_begin() ; |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
143 |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
144 _section_end [CodeBuffer::SECT_CONSTS] = nm->consts_end() ; |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
145 _section_end [CodeBuffer::SECT_INSTS ] = nm->insts_end() ; |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
146 _section_end [CodeBuffer::SECT_STUBS ] = nm->stub_end() ; |
0 | 147 |
148 assert(!has_current(), "just checking"); | |
1748 | 149 assert(begin == NULL || begin >= nm->code_begin(), "in bounds"); |
150 assert(limit == NULL || limit <= nm->code_end(), "in bounds"); | |
0 | 151 set_limits(begin, limit); |
152 } | |
153 | |
154 | |
155 RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) { | |
156 initialize_misc(); | |
157 | |
158 _current = cs->locs_start()-1; | |
159 _end = cs->locs_end(); | |
160 _addr = cs->start(); | |
161 _code = NULL; // Not cb->blob(); | |
162 | |
163 CodeBuffer* cb = cs->outer(); | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
164 assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal"); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
165 for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) { |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
166 CodeSection* cs = cb->code_section(n); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
167 _section_start[n] = cs->start(); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
168 _section_end [n] = cs->end(); |
0 | 169 } |
170 | |
171 assert(!has_current(), "just checking"); | |
172 | |
173 assert(begin == NULL || begin >= cs->start(), "in bounds"); | |
174 assert(limit == NULL || limit <= cs->end(), "in bounds"); | |
175 set_limits(begin, limit); | |
176 } | |
177 | |
178 | |
179 enum { indexCardSize = 128 }; | |
180 struct RelocIndexEntry { | |
181 jint addr_offset; // offset from header_end of an addr() | |
182 jint reloc_offset; // offset from header_end of a relocInfo (prefix) | |
183 }; | |
184 | |
185 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
186 bool RelocIterator::addr_in_const() const { |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
187 const int n = CodeBuffer::SECT_CONSTS; |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
188 return section_start(n) <= addr() && addr() < section_end(n); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
189 } |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
190 |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
191 |
0 | 192 static inline int num_cards(int code_size) { |
193 return (code_size-1) / indexCardSize; | |
194 } | |
195 | |
196 | |
197 int RelocIterator::locs_and_index_size(int code_size, int locs_size) { | |
198 if (!UseRelocIndex) return locs_size; // no index | |
199 code_size = round_to(code_size, oopSize); | |
200 locs_size = round_to(locs_size, oopSize); | |
201 int index_size = num_cards(code_size) * sizeof(RelocIndexEntry); | |
202 // format of indexed relocs: | |
203 // relocation_begin: relocInfo ... | |
204 // index: (addr,reloc#) ... | |
205 // indexSize :relocation_end | |
206 return locs_size + index_size + BytesPerInt; | |
207 } | |
208 | |
209 | |
210 void RelocIterator::create_index(relocInfo* dest_begin, int dest_count, relocInfo* dest_end) { | |
211 address relocation_begin = (address)dest_begin; | |
212 address relocation_end = (address)dest_end; | |
213 int total_size = relocation_end - relocation_begin; | |
214 int locs_size = dest_count * sizeof(relocInfo); | |
215 if (!UseRelocIndex) { | |
216 Copy::fill_to_bytes(relocation_begin + locs_size, total_size-locs_size, 0); | |
217 return; | |
218 } | |
219 int index_size = total_size - locs_size - BytesPerInt; // find out how much space is left | |
220 int ncards = index_size / sizeof(RelocIndexEntry); | |
221 assert(total_size == locs_size + index_size + BytesPerInt, "checkin'"); | |
222 assert(index_size >= 0 && index_size % sizeof(RelocIndexEntry) == 0, "checkin'"); | |
223 jint* index_size_addr = (jint*)relocation_end - 1; | |
224 | |
225 assert(sizeof(jint) == BytesPerInt, "change this code"); | |
226 | |
227 *index_size_addr = index_size; | |
228 if (index_size != 0) { | |
229 assert(index_size > 0, "checkin'"); | |
230 | |
231 RelocIndexEntry* index = (RelocIndexEntry *)(relocation_begin + locs_size); | |
232 assert(index == (RelocIndexEntry*)index_size_addr - ncards, "checkin'"); | |
233 | |
234 // walk over the relocations, and fill in index entries as we go | |
235 RelocIterator iter; | |
236 const address initial_addr = NULL; | |
237 relocInfo* const initial_current = dest_begin - 1; // biased by -1 like elsewhere | |
238 | |
239 iter._code = NULL; | |
240 iter._addr = initial_addr; | |
241 iter._limit = (address)(intptr_t)(ncards * indexCardSize); | |
242 iter._current = initial_current; | |
243 iter._end = dest_begin + dest_count; | |
244 | |
245 int i = 0; | |
246 address next_card_addr = (address)indexCardSize; | |
247 int addr_offset = 0; | |
248 int reloc_offset = 0; | |
249 while (true) { | |
250 // Checkpoint the iterator before advancing it. | |
251 addr_offset = iter._addr - initial_addr; | |
252 reloc_offset = iter._current - initial_current; | |
253 if (!iter.next()) break; | |
254 while (iter.addr() >= next_card_addr) { | |
255 index[i].addr_offset = addr_offset; | |
256 index[i].reloc_offset = reloc_offset; | |
257 i++; | |
258 next_card_addr += indexCardSize; | |
259 } | |
260 } | |
261 while (i < ncards) { | |
262 index[i].addr_offset = addr_offset; | |
263 index[i].reloc_offset = reloc_offset; | |
264 i++; | |
265 } | |
266 } | |
267 } | |
268 | |
269 | |
270 void RelocIterator::set_limits(address begin, address limit) { | |
271 int index_size = 0; | |
272 if (UseRelocIndex && _code != NULL) { | |
273 index_size = ((jint*)_end)[-1]; | |
274 _end = (relocInfo*)( (address)_end - index_size - BytesPerInt ); | |
275 } | |
276 | |
277 _limit = limit; | |
278 | |
279 // the limit affects this next stuff: | |
280 if (begin != NULL) { | |
281 #ifdef ASSERT | |
282 // In ASSERT mode we do not actually use the index, but simply | |
283 // check that its contents would have led us to the right answer. | |
284 address addrCheck = _addr; | |
285 relocInfo* infoCheck = _current; | |
286 #endif // ASSERT | |
287 if (index_size > 0) { | |
288 // skip ahead | |
289 RelocIndexEntry* index = (RelocIndexEntry*)_end; | |
290 RelocIndexEntry* index_limit = (RelocIndexEntry*)((address)index + index_size); | |
1748 | 291 assert(_addr == _code->code_begin(), "_addr must be unadjusted"); |
0 | 292 int card = (begin - _addr) / indexCardSize; |
293 if (card > 0) { | |
294 if (index+card-1 < index_limit) index += card-1; | |
295 else index = index_limit - 1; | |
296 #ifdef ASSERT | |
297 addrCheck = _addr + index->addr_offset; | |
298 infoCheck = _current + index->reloc_offset; | |
299 #else | |
300 // Advance the iterator immediately to the last valid state | |
301 // for the previous card. Calling "next" will then advance | |
302 // it to the first item on the required card. | |
303 _addr += index->addr_offset; | |
304 _current += index->reloc_offset; | |
305 #endif // ASSERT | |
306 } | |
307 } | |
308 | |
309 relocInfo* backup; | |
310 address backup_addr; | |
311 while (true) { | |
312 backup = _current; | |
313 backup_addr = _addr; | |
314 #ifdef ASSERT | |
315 if (backup == infoCheck) { | |
316 assert(backup_addr == addrCheck, "must match"); addrCheck = NULL; infoCheck = NULL; | |
317 } else { | |
318 assert(addrCheck == NULL || backup_addr <= addrCheck, "must not pass addrCheck"); | |
319 } | |
320 #endif // ASSERT | |
321 if (!next() || addr() >= begin) break; | |
322 } | |
323 assert(addrCheck == NULL || addrCheck == backup_addr, "must have matched addrCheck"); | |
324 assert(infoCheck == NULL || infoCheck == backup, "must have matched infoCheck"); | |
325 // At this point, either we are at the first matching record, | |
326 // or else there is no such record, and !has_current(). | |
327 // In either case, revert to the immediatly preceding state. | |
328 _current = backup; | |
329 _addr = backup_addr; | |
330 set_has_current(false); | |
331 } | |
332 } | |
333 | |
334 | |
335 void RelocIterator::set_limit(address limit) { | |
336 address code_end = (address)code() + code()->size(); | |
337 assert(limit == NULL || limit <= code_end, "in bounds"); | |
338 _limit = limit; | |
339 } | |
340 | |
341 // All the strange bit-encodings are in here. | |
342 // The idea is to encode relocation data which are small integers | |
343 // very efficiently (a single extra halfword). Larger chunks of | |
344 // relocation data need a halfword header to hold their size. | |
345 void RelocIterator::advance_over_prefix() { | |
346 if (_current->is_datalen()) { | |
347 _data = (short*) _current->data(); | |
348 _datalen = _current->datalen(); | |
349 _current += _datalen + 1; // skip the embedded data & header | |
350 } else { | |
351 _databuf = _current->immediate(); | |
352 _data = &_databuf; | |
353 _datalen = 1; | |
354 _current++; // skip the header | |
355 } | |
356 // The client will see the following relocInfo, whatever that is. | |
357 // It is the reloc to which the preceding data applies. | |
358 } | |
359 | |
360 | |
1762
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
361 void RelocIterator::initialize_misc() { |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
362 set_has_current(false); |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
363 for (int i = (int) CodeBuffer::SECT_FIRST; i < (int) CodeBuffer::SECT_LIMIT; i++) { |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
364 _section_start[i] = NULL; // these will be lazily computed, if needed |
0878d7bae69f
6961697: move nmethod constants section before instruction section
twisti
parents:
1748
diff
changeset
|
365 _section_end [i] = NULL; |
0 | 366 } |
367 } | |
368 | |
369 | |
370 Relocation* RelocIterator::reloc() { | |
371 // (take the "switch" out-of-line) | |
372 relocInfo::relocType t = type(); | |
373 if (false) {} | |
374 #define EACH_TYPE(name) \ | |
375 else if (t == relocInfo::name##_type) { \ | |
376 return name##_reloc(); \ | |
377 } | |
378 APPLY_TO_RELOCATIONS(EACH_TYPE); | |
379 #undef EACH_TYPE | |
380 assert(t == relocInfo::none, "must be padding"); | |
381 return new(_rh) Relocation(); | |
382 } | |
383 | |
384 | |
385 //////// Methods for flyweight Relocation types | |
386 | |
387 | |
388 RelocationHolder RelocationHolder::plus(int offset) const { | |
389 if (offset != 0) { | |
390 switch (type()) { | |
391 case relocInfo::none: | |
392 break; | |
393 case relocInfo::oop_type: | |
394 { | |
395 oop_Relocation* r = (oop_Relocation*)reloc(); | |
396 return oop_Relocation::spec(r->oop_index(), r->offset() + offset); | |
397 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
398 case relocInfo::metadata_type: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
399 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
400 metadata_Relocation* r = (metadata_Relocation*)reloc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
401 return metadata_Relocation::spec(r->metadata_index(), r->offset() + offset); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
402 } |
0 | 403 default: |
404 ShouldNotReachHere(); | |
405 } | |
406 } | |
407 return (*this); | |
408 } | |
409 | |
410 | |
411 void Relocation::guarantee_size() { | |
412 guarantee(false, "Make _relocbuf bigger!"); | |
413 } | |
414 | |
415 // some relocations can compute their own values | |
416 address Relocation::value() { | |
417 ShouldNotReachHere(); | |
418 return NULL; | |
419 } | |
420 | |
421 | |
422 void Relocation::set_value(address x) { | |
423 ShouldNotReachHere(); | |
424 } | |
425 | |
426 | |
427 RelocationHolder Relocation::spec_simple(relocInfo::relocType rtype) { | |
428 if (rtype == relocInfo::none) return RelocationHolder::none; | |
429 relocInfo ri = relocInfo(rtype, 0); | |
430 RelocIterator itr; | |
431 itr.set_current(ri); | |
432 itr.reloc(); | |
433 return itr._rh; | |
434 } | |
435 | |
436 int32_t Relocation::runtime_address_to_index(address runtime_address) { | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
437 assert(!is_reloc_index((intptr_t)runtime_address), "must not look like an index"); |
0 | 438 |
439 if (runtime_address == NULL) return 0; | |
440 | |
441 StubCodeDesc* p = StubCodeDesc::desc_for(runtime_address); | |
442 if (p != NULL && p->begin() == runtime_address) { | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
443 assert(is_reloc_index(p->index()), "there must not be too many stubs"); |
0 | 444 return (int32_t)p->index(); |
445 } else { | |
446 // Known "miscellaneous" non-stub pointers: | |
447 // os::get_polling_page(), SafepointSynchronize::address_of_state() | |
448 if (PrintRelocations) { | |
449 tty->print_cr("random unregistered address in relocInfo: " INTPTR_FORMAT, runtime_address); | |
450 } | |
451 #ifndef _LP64 | |
452 return (int32_t) (intptr_t)runtime_address; | |
453 #else | |
454 // didn't fit return non-index | |
455 return -1; | |
456 #endif /* _LP64 */ | |
457 } | |
458 } | |
459 | |
460 | |
461 address Relocation::index_to_runtime_address(int32_t index) { | |
462 if (index == 0) return NULL; | |
463 | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
464 if (is_reloc_index(index)) { |
0 | 465 StubCodeDesc* p = StubCodeDesc::desc_for_index(index); |
466 assert(p != NULL, "there must be a stub for this index"); | |
467 return p->begin(); | |
468 } else { | |
469 #ifndef _LP64 | |
470 // this only works on 32bit machines | |
471 return (address) ((intptr_t) index); | |
472 #else | |
473 fatal("Relocation::index_to_runtime_address, int32_t not pointer sized"); | |
474 return NULL; | |
475 #endif /* _LP64 */ | |
476 } | |
477 } | |
478 | |
479 address Relocation::old_addr_for(address newa, | |
480 const CodeBuffer* src, CodeBuffer* dest) { | |
481 int sect = dest->section_index_of(newa); | |
482 guarantee(sect != CodeBuffer::SECT_NONE, "lost track of this address"); | |
483 address ostart = src->code_section(sect)->start(); | |
484 address nstart = dest->code_section(sect)->start(); | |
485 return ostart + (newa - nstart); | |
486 } | |
487 | |
488 address Relocation::new_addr_for(address olda, | |
489 const CodeBuffer* src, CodeBuffer* dest) { | |
490 debug_only(const CodeBuffer* src0 = src); | |
491 int sect = CodeBuffer::SECT_NONE; | |
492 // Look for olda in the source buffer, and all previous incarnations | |
493 // if the source buffer has been expanded. | |
494 for (; src != NULL; src = src->before_expand()) { | |
495 sect = src->section_index_of(olda); | |
496 if (sect != CodeBuffer::SECT_NONE) break; | |
497 } | |
498 guarantee(sect != CodeBuffer::SECT_NONE, "lost track of this address"); | |
499 address ostart = src->code_section(sect)->start(); | |
500 address nstart = dest->code_section(sect)->start(); | |
501 return nstart + (olda - ostart); | |
502 } | |
503 | |
504 void Relocation::normalize_address(address& addr, const CodeSection* dest, bool allow_other_sections) { | |
505 address addr0 = addr; | |
506 if (addr0 == NULL || dest->allocates2(addr0)) return; | |
507 CodeBuffer* cb = dest->outer(); | |
508 addr = new_addr_for(addr0, cb, cb); | |
509 assert(allow_other_sections || dest->contains2(addr), | |
510 "addr must be in required section"); | |
511 } | |
512 | |
513 | |
514 void CallRelocation::set_destination(address x) { | |
515 pd_set_call_destination(x); | |
516 } | |
517 | |
518 void CallRelocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { | |
519 // Usually a self-relative reference to an external routine. | |
520 // On some platforms, the reference is absolute (not self-relative). | |
521 // The enhanced use of pd_call_destination sorts this all out. | |
522 address orig_addr = old_addr_for(addr(), src, dest); | |
523 address callee = pd_call_destination(orig_addr); | |
524 // Reassert the callee address, this time in the new copy of the code. | |
525 pd_set_call_destination(callee); | |
526 } | |
527 | |
528 | |
529 //// pack/unpack methods | |
530 | |
531 void oop_Relocation::pack_data_to(CodeSection* dest) { | |
532 short* p = (short*) dest->locs_end(); | |
533 p = pack_2_ints_to(p, _oop_index, _offset); | |
534 dest->set_locs_end((relocInfo*) p); | |
535 } | |
536 | |
537 | |
538 void oop_Relocation::unpack_data() { | |
539 unpack_2_ints(_oop_index, _offset); | |
540 } | |
541 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
542 void metadata_Relocation::pack_data_to(CodeSection* dest) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
543 short* p = (short*) dest->locs_end(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
544 p = pack_2_ints_to(p, _metadata_index, _offset); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
545 dest->set_locs_end((relocInfo*) p); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
546 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
547 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
548 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
549 void metadata_Relocation::unpack_data() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
550 unpack_2_ints(_metadata_index, _offset); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
551 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
552 |
0 | 553 |
554 void virtual_call_Relocation::pack_data_to(CodeSection* dest) { | |
555 short* p = (short*) dest->locs_end(); | |
556 address point = dest->locs_point(); | |
557 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
558 normalize_address(_cached_value, dest); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
559 jint x0 = scaled_offset_null_special(_cached_value, point); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
560 p = pack_1_int_to(p, x0); |
0 | 561 dest->set_locs_end((relocInfo*) p); |
562 } | |
563 | |
564 | |
565 void virtual_call_Relocation::unpack_data() { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
566 jint x0 = unpack_1_int(); |
0 | 567 address point = addr(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
568 _cached_value = x0==0? NULL: address_from_scaled_offset(x0, point); |
0 | 569 } |
570 | |
571 | |
572 void static_stub_Relocation::pack_data_to(CodeSection* dest) { | |
573 short* p = (short*) dest->locs_end(); | |
574 CodeSection* insts = dest->outer()->insts(); | |
575 normalize_address(_static_call, insts); | |
576 p = pack_1_int_to(p, scaled_offset(_static_call, insts->start())); | |
577 dest->set_locs_end((relocInfo*) p); | |
578 } | |
579 | |
580 void static_stub_Relocation::unpack_data() { | |
581 address base = binding()->section_start(CodeBuffer::SECT_INSTS); | |
582 _static_call = address_from_scaled_offset(unpack_1_int(), base); | |
583 } | |
584 | |
585 | |
586 void external_word_Relocation::pack_data_to(CodeSection* dest) { | |
587 short* p = (short*) dest->locs_end(); | |
588 int32_t index = runtime_address_to_index(_target); | |
589 #ifndef _LP64 | |
590 p = pack_1_int_to(p, index); | |
591 #else | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
592 if (is_reloc_index(index)) { |
0 | 593 p = pack_2_ints_to(p, index, 0); |
594 } else { | |
595 jlong t = (jlong) _target; | |
596 int32_t lo = low(t); | |
597 int32_t hi = high(t); | |
598 p = pack_2_ints_to(p, lo, hi); | |
599 DEBUG_ONLY(jlong t1 = jlong_from(hi, lo)); | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
600 assert(!is_reloc_index(t1) && (address) t1 == _target, "not symmetric"); |
0 | 601 } |
602 #endif /* _LP64 */ | |
603 dest->set_locs_end((relocInfo*) p); | |
604 } | |
605 | |
606 | |
607 void external_word_Relocation::unpack_data() { | |
608 #ifndef _LP64 | |
609 _target = index_to_runtime_address(unpack_1_int()); | |
610 #else | |
611 int32_t lo, hi; | |
612 unpack_2_ints(lo, hi); | |
613 jlong t = jlong_from(hi, lo);; | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
614 if (is_reloc_index(t)) { |
0 | 615 _target = index_to_runtime_address(t); |
616 } else { | |
617 _target = (address) t; | |
618 } | |
619 #endif /* _LP64 */ | |
620 } | |
621 | |
622 | |
623 void internal_word_Relocation::pack_data_to(CodeSection* dest) { | |
624 short* p = (short*) dest->locs_end(); | |
625 normalize_address(_target, dest, true); | |
626 | |
627 // Check whether my target address is valid within this section. | |
628 // If not, strengthen the relocation type to point to another section. | |
629 int sindex = _section; | |
630 if (sindex == CodeBuffer::SECT_NONE && _target != NULL | |
631 && (!dest->allocates(_target) || _target == dest->locs_point())) { | |
632 sindex = dest->outer()->section_index_of(_target); | |
633 guarantee(sindex != CodeBuffer::SECT_NONE, "must belong somewhere"); | |
634 relocInfo* base = dest->locs_end() - 1; | |
635 assert(base->type() == this->type(), "sanity"); | |
636 // Change the written type, to be section_word_type instead. | |
637 base->set_type(relocInfo::section_word_type); | |
638 } | |
639 | |
640 // Note: An internal_word relocation cannot refer to its own instruction, | |
641 // because we reserve "0" to mean that the pointer itself is embedded | |
642 // in the code stream. We use a section_word relocation for such cases. | |
643 | |
644 if (sindex == CodeBuffer::SECT_NONE) { | |
645 assert(type() == relocInfo::internal_word_type, "must be base class"); | |
646 guarantee(_target == NULL || dest->allocates2(_target), "must be within the given code section"); | |
647 jint x0 = scaled_offset_null_special(_target, dest->locs_point()); | |
648 assert(!(x0 == 0 && _target != NULL), "correct encoding of null target"); | |
649 p = pack_1_int_to(p, x0); | |
650 } else { | |
651 assert(_target != NULL, "sanity"); | |
652 CodeSection* sect = dest->outer()->code_section(sindex); | |
653 guarantee(sect->allocates2(_target), "must be in correct section"); | |
654 address base = sect->start(); | |
655 jint offset = scaled_offset(_target, base); | |
656 assert((uint)sindex < (uint)CodeBuffer::SECT_LIMIT, "sanity"); | |
657 assert(CodeBuffer::SECT_LIMIT <= (1 << section_width), "section_width++"); | |
658 p = pack_1_int_to(p, (offset << section_width) | sindex); | |
659 } | |
660 | |
661 dest->set_locs_end((relocInfo*) p); | |
662 } | |
663 | |
664 | |
665 void internal_word_Relocation::unpack_data() { | |
666 jint x0 = unpack_1_int(); | |
667 _target = x0==0? NULL: address_from_scaled_offset(x0, addr()); | |
668 _section = CodeBuffer::SECT_NONE; | |
669 } | |
670 | |
671 | |
672 void section_word_Relocation::unpack_data() { | |
673 jint x = unpack_1_int(); | |
674 jint offset = (x >> section_width); | |
675 int sindex = (x & ((1<<section_width)-1)); | |
676 address base = binding()->section_start(sindex); | |
677 | |
678 _section = sindex; | |
679 _target = address_from_scaled_offset(offset, base); | |
680 } | |
681 | |
682 //// miscellaneous methods | |
683 oop* oop_Relocation::oop_addr() { | |
684 int n = _oop_index; | |
685 if (n == 0) { | |
686 // oop is stored in the code stream | |
687 return (oop*) pd_address_in_code(); | |
688 } else { | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
689 // oop is stored in table at nmethod::oops_begin |
0 | 690 return code()->oop_addr_at(n); |
691 } | |
692 } | |
693 | |
694 | |
695 oop oop_Relocation::oop_value() { | |
696 oop v = *oop_addr(); | |
697 // clean inline caches store a special pseudo-null | |
698 if (v == (oop)Universe::non_oop_word()) v = NULL; | |
699 return v; | |
700 } | |
701 | |
702 | |
703 void oop_Relocation::fix_oop_relocation() { | |
704 if (!oop_is_immediate()) { | |
705 // get the oop from the pool, and re-insert it into the instruction: | |
706 set_value(value()); | |
707 } | |
708 } | |
709 | |
710 | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
711 void oop_Relocation::verify_oop_relocation() { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
712 if (!oop_is_immediate()) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
713 // get the oop from the pool, and re-insert it into the instruction: |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
714 verify_value(value()); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
715 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
716 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
717 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
718 // meta data versions |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
719 Metadata** metadata_Relocation::metadata_addr() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
720 int n = _metadata_index; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
721 if (n == 0) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
722 // metadata is stored in the code stream |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
723 return (Metadata**) pd_address_in_code(); |
0 | 724 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
725 // metadata is stored in table at nmethod::metadatas_begin |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
726 return code()->metadata_addr_at(n); |
0 | 727 } |
728 } | |
729 | |
730 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
731 Metadata* metadata_Relocation::metadata_value() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
732 Metadata* v = *metadata_addr(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
733 // clean inline caches store a special pseudo-null |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
734 if (v == (Metadata*)Universe::non_oop_word()) v = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
735 return v; |
0 | 736 } |
737 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
738 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
739 void metadata_Relocation::fix_metadata_relocation() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
740 if (!metadata_is_immediate()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
741 // get the metadata from the pool, and re-insert it into the instruction: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
742 pd_fix_value(value()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
743 } |
0 | 744 } |
745 | |
746 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
747 void metadata_Relocation::verify_metadata_relocation() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
748 if (!metadata_is_immediate()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
749 // get the metadata from the pool, and re-insert it into the instruction: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
750 verify_value(value()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
751 } |
0 | 752 } |
753 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
754 address virtual_call_Relocation::cached_value() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
755 assert(_cached_value != NULL && _cached_value < addr(), "must precede ic_call"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
756 return _cached_value; |
0 | 757 } |
758 | |
759 | |
760 void virtual_call_Relocation::clear_inline_cache() { | |
761 // No stubs for ICs | |
762 // Clean IC | |
763 ResourceMark rm; | |
764 CompiledIC* icache = CompiledIC_at(this); | |
765 icache->set_to_clean(); | |
766 } | |
767 | |
768 | |
769 void opt_virtual_call_Relocation::clear_inline_cache() { | |
770 // No stubs for ICs | |
771 // Clean IC | |
772 ResourceMark rm; | |
773 CompiledIC* icache = CompiledIC_at(this); | |
774 icache->set_to_clean(); | |
775 } | |
776 | |
777 | |
778 address opt_virtual_call_Relocation::static_stub() { | |
779 // search for the static stub who points back to this static call | |
780 address static_call_addr = addr(); | |
781 RelocIterator iter(code()); | |
782 while (iter.next()) { | |
783 if (iter.type() == relocInfo::static_stub_type) { | |
784 if (iter.static_stub_reloc()->static_call() == static_call_addr) { | |
785 return iter.addr(); | |
786 } | |
787 } | |
788 } | |
789 return NULL; | |
790 } | |
791 | |
792 | |
793 void static_call_Relocation::clear_inline_cache() { | |
794 // Safe call site info | |
795 CompiledStaticCall* handler = compiledStaticCall_at(this); | |
796 handler->set_to_clean(); | |
797 } | |
798 | |
799 | |
800 address static_call_Relocation::static_stub() { | |
801 // search for the static stub who points back to this static call | |
802 address static_call_addr = addr(); | |
803 RelocIterator iter(code()); | |
804 while (iter.next()) { | |
805 if (iter.type() == relocInfo::static_stub_type) { | |
806 if (iter.static_stub_reloc()->static_call() == static_call_addr) { | |
807 return iter.addr(); | |
808 } | |
809 } | |
810 } | |
811 return NULL; | |
812 } | |
813 | |
814 | |
815 void static_stub_Relocation::clear_inline_cache() { | |
816 // Call stub is only used when calling the interpreted code. | |
817 // It does not really need to be cleared, except that we want to clean out the methodoop. | |
818 CompiledStaticCall::set_stub_to_clean(this); | |
819 } | |
820 | |
821 | |
822 void external_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { | |
823 address target = _target; | |
824 if (target == NULL) { | |
825 // An absolute embedded reference to an external location, | |
826 // which means there is nothing to fix here. | |
827 return; | |
828 } | |
829 // Probably this reference is absolute, not relative, so the | |
830 // following is probably a no-op. | |
831 assert(src->section_index_of(target) == CodeBuffer::SECT_NONE, "sanity"); | |
832 set_value(target); | |
833 } | |
834 | |
835 | |
836 address external_word_Relocation::target() { | |
837 address target = _target; | |
838 if (target == NULL) { | |
839 target = pd_get_address_from_code(); | |
840 } | |
841 return target; | |
842 } | |
843 | |
844 | |
845 void internal_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { | |
846 address target = _target; | |
847 if (target == NULL) { | |
848 if (addr_in_const()) { | |
849 target = new_addr_for(*(address*)addr(), src, dest); | |
850 } else { | |
851 target = new_addr_for(pd_get_address_from_code(), src, dest); | |
852 } | |
853 } | |
854 set_value(target); | |
855 } | |
856 | |
857 | |
858 address internal_word_Relocation::target() { | |
859 address target = _target; | |
860 if (target == NULL) { | |
861 target = pd_get_address_from_code(); | |
862 } | |
863 return target; | |
864 } | |
865 | |
866 //--------------------------------------------------------------------------------- | |
867 // Non-product code | |
868 | |
869 #ifndef PRODUCT | |
870 | |
871 static const char* reloc_type_string(relocInfo::relocType t) { | |
872 switch (t) { | |
873 #define EACH_CASE(name) \ | |
874 case relocInfo::name##_type: \ | |
875 return #name; | |
876 | |
877 APPLY_TO_RELOCATIONS(EACH_CASE); | |
878 #undef EACH_CASE | |
879 | |
880 case relocInfo::none: | |
881 return "none"; | |
882 case relocInfo::data_prefix_tag: | |
883 return "prefix"; | |
884 default: | |
885 return "UNKNOWN RELOC TYPE"; | |
886 } | |
887 } | |
888 | |
889 | |
890 void RelocIterator::print_current() { | |
891 if (!has_current()) { | |
892 tty->print_cr("(no relocs)"); | |
893 return; | |
894 } | |
2002 | 895 tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d", |
896 _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr, _current->addr_offset()); | |
0 | 897 if (current()->format() != 0) |
898 tty->print(" format=%d", current()->format()); | |
899 if (datalen() == 1) { | |
900 tty->print(" data=%d", data()[0]); | |
901 } else if (datalen() > 0) { | |
902 tty->print(" data={"); | |
903 for (int i = 0; i < datalen(); i++) { | |
904 tty->print("%04x", data()[i] & 0xFFFF); | |
905 } | |
906 tty->print("}"); | |
907 } | |
908 tty->print("]"); | |
909 switch (type()) { | |
910 case relocInfo::oop_type: | |
911 { | |
912 oop_Relocation* r = oop_reloc(); | |
913 oop* oop_addr = NULL; | |
914 oop raw_oop = NULL; | |
915 oop oop_value = NULL; | |
916 if (code() != NULL || r->oop_is_immediate()) { | |
917 oop_addr = r->oop_addr(); | |
918 raw_oop = *oop_addr; | |
919 oop_value = r->oop_value(); | |
920 } | |
921 tty->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]", | |
922 oop_addr, (address)raw_oop, r->offset()); | |
923 // Do not print the oop by default--we want this routine to | |
924 // work even during GC or other inconvenient times. | |
925 if (WizardMode && oop_value != NULL) { | |
926 tty->print("oop_value=" INTPTR_FORMAT ": ", (address)oop_value); | |
927 oop_value->print_value_on(tty); | |
928 } | |
929 break; | |
930 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
931 case relocInfo::metadata_type: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
932 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
933 metadata_Relocation* r = metadata_reloc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
934 Metadata** metadata_addr = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
935 Metadata* raw_metadata = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
936 Metadata* metadata_value = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
937 if (code() != NULL || r->metadata_is_immediate()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
938 metadata_addr = r->metadata_addr(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
939 raw_metadata = *metadata_addr; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
940 metadata_value = r->metadata_value(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
941 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
942 tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]", |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
943 metadata_addr, (address)raw_metadata, r->offset()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
944 if (metadata_value != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
945 tty->print("metadata_value=" INTPTR_FORMAT ": ", (address)metadata_value); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
946 metadata_value->print_value_on(tty); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
947 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
948 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
949 } |
0 | 950 case relocInfo::external_word_type: |
951 case relocInfo::internal_word_type: | |
952 case relocInfo::section_word_type: | |
953 { | |
954 DataRelocation* r = (DataRelocation*) reloc(); | |
955 tty->print(" | [target=" INTPTR_FORMAT "]", r->value()); //value==target | |
956 break; | |
957 } | |
958 case relocInfo::static_call_type: | |
959 case relocInfo::runtime_call_type: | |
960 { | |
961 CallRelocation* r = (CallRelocation*) reloc(); | |
962 tty->print(" | [destination=" INTPTR_FORMAT "]", r->destination()); | |
963 break; | |
964 } | |
965 case relocInfo::virtual_call_type: | |
966 { | |
967 virtual_call_Relocation* r = (virtual_call_Relocation*) reloc(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
968 tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT "]", |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
969 r->destination(), r->cached_value()); |
0 | 970 break; |
971 } | |
972 case relocInfo::static_stub_type: | |
973 { | |
974 static_stub_Relocation* r = (static_stub_Relocation*) reloc(); | |
975 tty->print(" | [static_call=" INTPTR_FORMAT "]", r->static_call()); | |
976 break; | |
977 } | |
978 } | |
979 tty->cr(); | |
980 } | |
981 | |
982 | |
983 void RelocIterator::print() { | |
984 RelocIterator save_this = (*this); | |
985 relocInfo* scan = _current; | |
986 if (!has_current()) scan += 1; // nothing to scan here! | |
987 | |
988 bool skip_next = has_current(); | |
989 bool got_next; | |
990 while (true) { | |
991 got_next = (skip_next || next()); | |
992 skip_next = false; | |
993 | |
994 tty->print(" @" INTPTR_FORMAT ": ", scan); | |
995 relocInfo* newscan = _current+1; | |
996 if (!has_current()) newscan -= 1; // nothing to scan here! | |
997 while (scan < newscan) { | |
998 tty->print("%04x", *(short*)scan & 0xFFFF); | |
999 scan++; | |
1000 } | |
1001 tty->cr(); | |
1002 | |
1003 if (!got_next) break; | |
1004 print_current(); | |
1005 } | |
1006 | |
1007 (*this) = save_this; | |
1008 } | |
1009 | |
1010 // For the debugger: | |
1011 extern "C" | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
1012 void print_blob_locs(nmethod* nm) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
1013 nm->print(); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
1014 RelocIterator iter(nm); |
0 | 1015 iter.print(); |
1016 } | |
1017 extern "C" | |
1018 void print_buf_locs(CodeBuffer* cb) { | |
1019 FlagSetting fs(PrintRelocations, true); | |
1020 cb->print(); | |
1021 } | |
1022 #endif // !PRODUCT |