Mercurial > hg > truffle
annotate src/share/vm/code/relocInfo.cpp @ 14649:f6301b007a16
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 | abec000618bf |
children | d8041d695d19 78bbf4d43a14 |
rev | line source |
---|---|
0 | 1 /* |
14223
de6a9e811145
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 | |
14397
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
585 void trampoline_stub_Relocation::pack_data_to(CodeSection* dest ) { |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
586 short* p = (short*) dest->locs_end(); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
587 CodeSection* insts = dest->outer()->insts(); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
588 normalize_address(_owner, insts); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
589 p = pack_1_int_to(p, scaled_offset(_owner, insts->start())); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
590 dest->set_locs_end((relocInfo*) p); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
591 } |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
592 |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
593 void trampoline_stub_Relocation::unpack_data() { |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
594 address base = binding()->section_start(CodeBuffer::SECT_INSTS); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
595 _owner = address_from_scaled_offset(unpack_1_int(), base); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
596 } |
0 | 597 |
598 void external_word_Relocation::pack_data_to(CodeSection* dest) { | |
599 short* p = (short*) dest->locs_end(); | |
600 int32_t index = runtime_address_to_index(_target); | |
601 #ifndef _LP64 | |
602 p = pack_1_int_to(p, index); | |
603 #else | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
604 if (is_reloc_index(index)) { |
0 | 605 p = pack_2_ints_to(p, index, 0); |
606 } else { | |
607 jlong t = (jlong) _target; | |
608 int32_t lo = low(t); | |
609 int32_t hi = high(t); | |
610 p = pack_2_ints_to(p, lo, hi); | |
611 DEBUG_ONLY(jlong t1 = jlong_from(hi, lo)); | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
612 assert(!is_reloc_index(t1) && (address) t1 == _target, "not symmetric"); |
0 | 613 } |
614 #endif /* _LP64 */ | |
615 dest->set_locs_end((relocInfo*) p); | |
616 } | |
617 | |
618 | |
619 void external_word_Relocation::unpack_data() { | |
620 #ifndef _LP64 | |
621 _target = index_to_runtime_address(unpack_1_int()); | |
622 #else | |
623 int32_t lo, hi; | |
624 unpack_2_ints(lo, hi); | |
625 jlong t = jlong_from(hi, lo);; | |
2455
479b4b4b6950
6777083: assert(target != __null,"must not be null")
never
parents:
2375
diff
changeset
|
626 if (is_reloc_index(t)) { |
0 | 627 _target = index_to_runtime_address(t); |
628 } else { | |
629 _target = (address) t; | |
630 } | |
631 #endif /* _LP64 */ | |
632 } | |
633 | |
634 | |
635 void internal_word_Relocation::pack_data_to(CodeSection* dest) { | |
636 short* p = (short*) dest->locs_end(); | |
637 normalize_address(_target, dest, true); | |
638 | |
639 // Check whether my target address is valid within this section. | |
640 // If not, strengthen the relocation type to point to another section. | |
641 int sindex = _section; | |
642 if (sindex == CodeBuffer::SECT_NONE && _target != NULL | |
643 && (!dest->allocates(_target) || _target == dest->locs_point())) { | |
644 sindex = dest->outer()->section_index_of(_target); | |
645 guarantee(sindex != CodeBuffer::SECT_NONE, "must belong somewhere"); | |
646 relocInfo* base = dest->locs_end() - 1; | |
647 assert(base->type() == this->type(), "sanity"); | |
648 // Change the written type, to be section_word_type instead. | |
649 base->set_type(relocInfo::section_word_type); | |
650 } | |
651 | |
652 // Note: An internal_word relocation cannot refer to its own instruction, | |
653 // because we reserve "0" to mean that the pointer itself is embedded | |
654 // in the code stream. We use a section_word relocation for such cases. | |
655 | |
656 if (sindex == CodeBuffer::SECT_NONE) { | |
657 assert(type() == relocInfo::internal_word_type, "must be base class"); | |
658 guarantee(_target == NULL || dest->allocates2(_target), "must be within the given code section"); | |
659 jint x0 = scaled_offset_null_special(_target, dest->locs_point()); | |
660 assert(!(x0 == 0 && _target != NULL), "correct encoding of null target"); | |
661 p = pack_1_int_to(p, x0); | |
662 } else { | |
663 assert(_target != NULL, "sanity"); | |
664 CodeSection* sect = dest->outer()->code_section(sindex); | |
665 guarantee(sect->allocates2(_target), "must be in correct section"); | |
666 address base = sect->start(); | |
667 jint offset = scaled_offset(_target, base); | |
668 assert((uint)sindex < (uint)CodeBuffer::SECT_LIMIT, "sanity"); | |
669 assert(CodeBuffer::SECT_LIMIT <= (1 << section_width), "section_width++"); | |
670 p = pack_1_int_to(p, (offset << section_width) | sindex); | |
671 } | |
672 | |
673 dest->set_locs_end((relocInfo*) p); | |
674 } | |
675 | |
676 | |
677 void internal_word_Relocation::unpack_data() { | |
678 jint x0 = unpack_1_int(); | |
679 _target = x0==0? NULL: address_from_scaled_offset(x0, addr()); | |
680 _section = CodeBuffer::SECT_NONE; | |
681 } | |
682 | |
683 | |
684 void section_word_Relocation::unpack_data() { | |
685 jint x = unpack_1_int(); | |
686 jint offset = (x >> section_width); | |
687 int sindex = (x & ((1<<section_width)-1)); | |
688 address base = binding()->section_start(sindex); | |
689 | |
690 _section = sindex; | |
691 _target = address_from_scaled_offset(offset, base); | |
692 } | |
693 | |
694 //// miscellaneous methods | |
695 oop* oop_Relocation::oop_addr() { | |
696 int n = _oop_index; | |
697 if (n == 0) { | |
698 // oop is stored in the code stream | |
699 return (oop*) pd_address_in_code(); | |
700 } else { | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
701 // oop is stored in table at nmethod::oops_begin |
0 | 702 return code()->oop_addr_at(n); |
703 } | |
704 } | |
705 | |
706 | |
707 oop oop_Relocation::oop_value() { | |
708 oop v = *oop_addr(); | |
709 // clean inline caches store a special pseudo-null | |
710 if (v == (oop)Universe::non_oop_word()) v = NULL; | |
711 return v; | |
712 } | |
713 | |
714 | |
715 void oop_Relocation::fix_oop_relocation() { | |
716 if (!oop_is_immediate()) { | |
717 // get the oop from the pool, and re-insert it into the instruction: | |
718 set_value(value()); | |
719 } | |
720 } | |
721 | |
722 | |
2375
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
723 void oop_Relocation::verify_oop_relocation() { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
724 if (!oop_is_immediate()) { |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
725 // 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
|
726 verify_value(value()); |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
727 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
728 } |
d673ef06fe96
7028374: race in fix_oop_relocations for scavengeable nmethods
never
parents:
2192
diff
changeset
|
729 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
730 // meta data versions |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
731 Metadata** metadata_Relocation::metadata_addr() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
732 int n = _metadata_index; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
733 if (n == 0) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
734 // metadata is stored in the code stream |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
735 return (Metadata**) pd_address_in_code(); |
0 | 736 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
737 // 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
|
738 return code()->metadata_addr_at(n); |
0 | 739 } |
740 } | |
741 | |
742 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
743 Metadata* metadata_Relocation::metadata_value() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
744 Metadata* v = *metadata_addr(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
745 // clean inline caches store a special pseudo-null |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
746 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
|
747 return v; |
0 | 748 } |
749 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
750 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
751 void metadata_Relocation::fix_metadata_relocation() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
752 if (!metadata_is_immediate()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
753 // 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
|
754 pd_fix_value(value()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
755 } |
0 | 756 } |
757 | |
758 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
759 void metadata_Relocation::verify_metadata_relocation() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
760 if (!metadata_is_immediate()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
761 // 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
|
762 verify_value(value()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
763 } |
0 | 764 } |
765 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
766 address virtual_call_Relocation::cached_value() { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
767 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
|
768 return _cached_value; |
0 | 769 } |
770 | |
771 | |
772 void virtual_call_Relocation::clear_inline_cache() { | |
773 // No stubs for ICs | |
774 // Clean IC | |
775 ResourceMark rm; | |
776 CompiledIC* icache = CompiledIC_at(this); | |
777 icache->set_to_clean(); | |
778 } | |
779 | |
780 | |
781 void opt_virtual_call_Relocation::clear_inline_cache() { | |
782 // No stubs for ICs | |
783 // Clean IC | |
784 ResourceMark rm; | |
785 CompiledIC* icache = CompiledIC_at(this); | |
786 icache->set_to_clean(); | |
787 } | |
788 | |
789 | |
790 address opt_virtual_call_Relocation::static_stub() { | |
791 // search for the static stub who points back to this static call | |
792 address static_call_addr = addr(); | |
793 RelocIterator iter(code()); | |
794 while (iter.next()) { | |
795 if (iter.type() == relocInfo::static_stub_type) { | |
796 if (iter.static_stub_reloc()->static_call() == static_call_addr) { | |
797 return iter.addr(); | |
798 } | |
799 } | |
800 } | |
801 return NULL; | |
802 } | |
803 | |
804 | |
805 void static_call_Relocation::clear_inline_cache() { | |
806 // Safe call site info | |
807 CompiledStaticCall* handler = compiledStaticCall_at(this); | |
808 handler->set_to_clean(); | |
809 } | |
810 | |
811 | |
812 address static_call_Relocation::static_stub() { | |
813 // search for the static stub who points back to this static call | |
814 address static_call_addr = addr(); | |
815 RelocIterator iter(code()); | |
816 while (iter.next()) { | |
817 if (iter.type() == relocInfo::static_stub_type) { | |
818 if (iter.static_stub_reloc()->static_call() == static_call_addr) { | |
819 return iter.addr(); | |
820 } | |
821 } | |
822 } | |
823 return NULL; | |
824 } | |
825 | |
14397
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
826 // Finds the trampoline address for a call. If no trampoline stub is |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
827 // found NULL is returned which can be handled by the caller. |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
828 address trampoline_stub_Relocation::get_trampoline_for(address call, nmethod* code) { |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
829 // There are no relocations available when the code gets relocated |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
830 // because of CodeBuffer expansion. |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
831 if (code->relocation_size() == 0) |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
832 return NULL; |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
833 |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
834 RelocIterator iter(code, call); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
835 while (iter.next()) { |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
836 if (iter.type() == relocInfo::trampoline_stub_type) { |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
837 if (iter.trampoline_stub_reloc()->owner() == call) { |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
838 return iter.addr(); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
839 } |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
840 } |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
841 } |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
842 |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
843 return NULL; |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
844 } |
0 | 845 |
846 void static_stub_Relocation::clear_inline_cache() { | |
847 // Call stub is only used when calling the interpreted code. | |
848 // It does not really need to be cleared, except that we want to clean out the methodoop. | |
849 CompiledStaticCall::set_stub_to_clean(this); | |
850 } | |
851 | |
852 | |
853 void external_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { | |
854 address target = _target; | |
855 if (target == NULL) { | |
856 // An absolute embedded reference to an external location, | |
857 // which means there is nothing to fix here. | |
858 return; | |
859 } | |
860 // Probably this reference is absolute, not relative, so the | |
861 // following is probably a no-op. | |
862 assert(src->section_index_of(target) == CodeBuffer::SECT_NONE, "sanity"); | |
863 set_value(target); | |
864 } | |
865 | |
866 | |
867 address external_word_Relocation::target() { | |
868 address target = _target; | |
869 if (target == NULL) { | |
870 target = pd_get_address_from_code(); | |
871 } | |
872 return target; | |
873 } | |
874 | |
875 | |
876 void internal_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { | |
877 address target = _target; | |
878 if (target == NULL) { | |
879 if (addr_in_const()) { | |
880 target = new_addr_for(*(address*)addr(), src, dest); | |
881 } else { | |
882 target = new_addr_for(pd_get_address_from_code(), src, dest); | |
883 } | |
884 } | |
885 set_value(target); | |
886 } | |
887 | |
888 | |
889 address internal_word_Relocation::target() { | |
890 address target = _target; | |
891 if (target == NULL) { | |
892 target = pd_get_address_from_code(); | |
893 } | |
894 return target; | |
895 } | |
896 | |
897 //--------------------------------------------------------------------------------- | |
898 // Non-product code | |
899 | |
900 #ifndef PRODUCT | |
901 | |
902 static const char* reloc_type_string(relocInfo::relocType t) { | |
903 switch (t) { | |
904 #define EACH_CASE(name) \ | |
905 case relocInfo::name##_type: \ | |
906 return #name; | |
907 | |
908 APPLY_TO_RELOCATIONS(EACH_CASE); | |
909 #undef EACH_CASE | |
910 | |
911 case relocInfo::none: | |
912 return "none"; | |
913 case relocInfo::data_prefix_tag: | |
914 return "prefix"; | |
915 default: | |
916 return "UNKNOWN RELOC TYPE"; | |
917 } | |
918 } | |
919 | |
920 | |
921 void RelocIterator::print_current() { | |
922 if (!has_current()) { | |
923 tty->print_cr("(no relocs)"); | |
924 return; | |
925 } | |
2002 | 926 tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d", |
927 _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr, _current->addr_offset()); | |
0 | 928 if (current()->format() != 0) |
929 tty->print(" format=%d", current()->format()); | |
930 if (datalen() == 1) { | |
931 tty->print(" data=%d", data()[0]); | |
932 } else if (datalen() > 0) { | |
933 tty->print(" data={"); | |
934 for (int i = 0; i < datalen(); i++) { | |
935 tty->print("%04x", data()[i] & 0xFFFF); | |
936 } | |
937 tty->print("}"); | |
938 } | |
939 tty->print("]"); | |
940 switch (type()) { | |
941 case relocInfo::oop_type: | |
942 { | |
943 oop_Relocation* r = oop_reloc(); | |
944 oop* oop_addr = NULL; | |
945 oop raw_oop = NULL; | |
946 oop oop_value = NULL; | |
947 if (code() != NULL || r->oop_is_immediate()) { | |
948 oop_addr = r->oop_addr(); | |
949 raw_oop = *oop_addr; | |
950 oop_value = r->oop_value(); | |
951 } | |
952 tty->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]", | |
953 oop_addr, (address)raw_oop, r->offset()); | |
954 // Do not print the oop by default--we want this routine to | |
955 // work even during GC or other inconvenient times. | |
956 if (WizardMode && oop_value != NULL) { | |
957 tty->print("oop_value=" INTPTR_FORMAT ": ", (address)oop_value); | |
958 oop_value->print_value_on(tty); | |
959 } | |
960 break; | |
961 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
962 case relocInfo::metadata_type: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
963 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
964 metadata_Relocation* r = metadata_reloc(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
965 Metadata** metadata_addr = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
966 Metadata* raw_metadata = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
967 Metadata* metadata_value = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
968 if (code() != NULL || r->metadata_is_immediate()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
969 metadata_addr = r->metadata_addr(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
970 raw_metadata = *metadata_addr; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
971 metadata_value = r->metadata_value(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
972 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
973 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
|
974 metadata_addr, (address)raw_metadata, r->offset()); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
975 if (metadata_value != NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
976 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
|
977 metadata_value->print_value_on(tty); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
978 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
979 break; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2468
diff
changeset
|
980 } |
0 | 981 case relocInfo::external_word_type: |
982 case relocInfo::internal_word_type: | |
983 case relocInfo::section_word_type: | |
984 { | |
985 DataRelocation* r = (DataRelocation*) reloc(); | |
986 tty->print(" | [target=" INTPTR_FORMAT "]", r->value()); //value==target | |
987 break; | |
988 } | |
989 case relocInfo::static_call_type: | |
990 case relocInfo::runtime_call_type: | |
991 { | |
992 CallRelocation* r = (CallRelocation*) reloc(); | |
993 tty->print(" | [destination=" INTPTR_FORMAT "]", r->destination()); | |
994 break; | |
995 } | |
996 case relocInfo::virtual_call_type: | |
997 { | |
998 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
|
999 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
|
1000 r->destination(), r->cached_value()); |
0 | 1001 break; |
1002 } | |
1003 case relocInfo::static_stub_type: | |
1004 { | |
1005 static_stub_Relocation* r = (static_stub_Relocation*) reloc(); | |
1006 tty->print(" | [static_call=" INTPTR_FORMAT "]", r->static_call()); | |
1007 break; | |
1008 } | |
14397
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
1009 case relocInfo::trampoline_stub_type: |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
1010 { |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
1011 trampoline_stub_Relocation* r = (trampoline_stub_Relocation*) reloc(); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
1012 tty->print(" | [trampoline owner=" INTPTR_FORMAT "]", r->owner()); |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
1013 break; |
53fa76359eb1
8016696: PPC64 (part 4): add relocation for trampoline stubs
goetz
parents:
11041
diff
changeset
|
1014 } |
0 | 1015 } |
1016 tty->cr(); | |
1017 } | |
1018 | |
1019 | |
1020 void RelocIterator::print() { | |
1021 RelocIterator save_this = (*this); | |
1022 relocInfo* scan = _current; | |
1023 if (!has_current()) scan += 1; // nothing to scan here! | |
1024 | |
1025 bool skip_next = has_current(); | |
1026 bool got_next; | |
1027 while (true) { | |
1028 got_next = (skip_next || next()); | |
1029 skip_next = false; | |
1030 | |
1031 tty->print(" @" INTPTR_FORMAT ": ", scan); | |
1032 relocInfo* newscan = _current+1; | |
1033 if (!has_current()) newscan -= 1; // nothing to scan here! | |
1034 while (scan < newscan) { | |
1035 tty->print("%04x", *(short*)scan & 0xFFFF); | |
1036 scan++; | |
1037 } | |
1038 tty->cr(); | |
1039 | |
1040 if (!got_next) break; | |
1041 print_current(); | |
1042 } | |
1043 | |
1044 (*this) = save_this; | |
1045 } | |
1046 | |
1047 // For the debugger: | |
1048 extern "C" | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
1049 void print_blob_locs(nmethod* nm) { |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
1050 nm->print(); |
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
0
diff
changeset
|
1051 RelocIterator iter(nm); |
0 | 1052 iter.print(); |
1053 } | |
1054 extern "C" | |
1055 void print_buf_locs(CodeBuffer* cb) { | |
1056 FlagSetting fs(PrintRelocations, true); | |
1057 cb->print(); | |
1058 } | |
1059 #endif // !PRODUCT |