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