1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/code/relocInfo.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,1060 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "code/codeCache.hpp" 1.30 +#include "code/compiledIC.hpp" 1.31 +#include "code/nmethod.hpp" 1.32 +#include "code/relocInfo.hpp" 1.33 +#include "memory/resourceArea.hpp" 1.34 +#include "runtime/stubCodeGenerator.hpp" 1.35 +#include "utilities/copy.hpp" 1.36 + 1.37 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 1.38 + 1.39 +const RelocationHolder RelocationHolder::none; // its type is relocInfo::none 1.40 + 1.41 + 1.42 +// Implementation of relocInfo 1.43 + 1.44 +#ifdef ASSERT 1.45 +relocInfo::relocInfo(relocType t, int off, int f) { 1.46 + assert(t != data_prefix_tag, "cannot build a prefix this way"); 1.47 + assert((t & type_mask) == t, "wrong type"); 1.48 + assert((f & format_mask) == f, "wrong format"); 1.49 + assert(off >= 0 && off < offset_limit(), "offset out off bounds"); 1.50 + assert((off & (offset_unit-1)) == 0, "misaligned offset"); 1.51 + (*this) = relocInfo(t, RAW_BITS, off, f); 1.52 +} 1.53 +#endif 1.54 + 1.55 +void relocInfo::initialize(CodeSection* dest, Relocation* reloc) { 1.56 + relocInfo* data = this+1; // here's where the data might go 1.57 + dest->set_locs_end(data); // sync end: the next call may read dest.locs_end 1.58 + reloc->pack_data_to(dest); // maybe write data into locs, advancing locs_end 1.59 + relocInfo* data_limit = dest->locs_end(); 1.60 + if (data_limit > data) { 1.61 + relocInfo suffix = (*this); 1.62 + data_limit = this->finish_prefix((short*) data_limit); 1.63 + // Finish up with the suffix. (Hack note: pack_data_to might edit this.) 1.64 + *data_limit = suffix; 1.65 + dest->set_locs_end(data_limit+1); 1.66 + } 1.67 +} 1.68 + 1.69 +relocInfo* relocInfo::finish_prefix(short* prefix_limit) { 1.70 + assert(sizeof(relocInfo) == sizeof(short), "change this code"); 1.71 + short* p = (short*)(this+1); 1.72 + assert(prefix_limit >= p, "must be a valid span of data"); 1.73 + int plen = prefix_limit - p; 1.74 + if (plen == 0) { 1.75 + debug_only(_value = 0xFFFF); 1.76 + return this; // no data: remove self completely 1.77 + } 1.78 + if (plen == 1 && fits_into_immediate(p[0])) { 1.79 + (*this) = immediate_relocInfo(p[0]); // move data inside self 1.80 + return this+1; 1.81 + } 1.82 + // cannot compact, so just update the count and return the limit pointer 1.83 + (*this) = prefix_relocInfo(plen); // write new datalen 1.84 + assert(data() + datalen() == prefix_limit, "pointers must line up"); 1.85 + return (relocInfo*)prefix_limit; 1.86 +} 1.87 + 1.88 + 1.89 +void relocInfo::set_type(relocType t) { 1.90 + int old_offset = addr_offset(); 1.91 + int old_format = format(); 1.92 + (*this) = relocInfo(t, old_offset, old_format); 1.93 + assert(type()==(int)t, "sanity check"); 1.94 + assert(addr_offset()==old_offset, "sanity check"); 1.95 + assert(format()==old_format, "sanity check"); 1.96 +} 1.97 + 1.98 + 1.99 +void relocInfo::set_format(int f) { 1.100 + int old_offset = addr_offset(); 1.101 + assert((f & format_mask) == f, "wrong format"); 1.102 + _value = (_value & ~(format_mask << offset_width)) | (f << offset_width); 1.103 + assert(addr_offset()==old_offset, "sanity check"); 1.104 +} 1.105 + 1.106 + 1.107 +void relocInfo::change_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type, relocType new_type) { 1.108 + bool found = false; 1.109 + while (itr->next() && !found) { 1.110 + if (itr->addr() == pc) { 1.111 + assert(itr->type()==old_type, "wrong relocInfo type found"); 1.112 + itr->current()->set_type(new_type); 1.113 + found=true; 1.114 + } 1.115 + } 1.116 + assert(found, "no relocInfo found for pc"); 1.117 +} 1.118 + 1.119 + 1.120 +void relocInfo::remove_reloc_info_for_address(RelocIterator *itr, address pc, relocType old_type) { 1.121 + change_reloc_info_for_address(itr, pc, old_type, none); 1.122 +} 1.123 + 1.124 + 1.125 +// ---------------------------------------------------------------------------------------------------- 1.126 +// Implementation of RelocIterator 1.127 + 1.128 +void RelocIterator::initialize(nmethod* nm, address begin, address limit) { 1.129 + initialize_misc(); 1.130 + 1.131 + if (nm == NULL && begin != NULL) { 1.132 + // allow nmethod to be deduced from beginning address 1.133 + CodeBlob* cb = CodeCache::find_blob(begin); 1.134 + nm = cb->as_nmethod_or_null(); 1.135 + } 1.136 + assert(nm != NULL, "must be able to deduce nmethod from other arguments"); 1.137 + 1.138 + _code = nm; 1.139 + _current = nm->relocation_begin() - 1; 1.140 + _end = nm->relocation_end(); 1.141 + _addr = nm->content_begin(); 1.142 + 1.143 + // Initialize code sections. 1.144 + _section_start[CodeBuffer::SECT_CONSTS] = nm->consts_begin(); 1.145 + _section_start[CodeBuffer::SECT_INSTS ] = nm->insts_begin() ; 1.146 + _section_start[CodeBuffer::SECT_STUBS ] = nm->stub_begin() ; 1.147 + 1.148 + _section_end [CodeBuffer::SECT_CONSTS] = nm->consts_end() ; 1.149 + _section_end [CodeBuffer::SECT_INSTS ] = nm->insts_end() ; 1.150 + _section_end [CodeBuffer::SECT_STUBS ] = nm->stub_end() ; 1.151 + 1.152 + assert(!has_current(), "just checking"); 1.153 + assert(begin == NULL || begin >= nm->code_begin(), "in bounds"); 1.154 + assert(limit == NULL || limit <= nm->code_end(), "in bounds"); 1.155 + set_limits(begin, limit); 1.156 +} 1.157 + 1.158 + 1.159 +RelocIterator::RelocIterator(CodeSection* cs, address begin, address limit) { 1.160 + initialize_misc(); 1.161 + 1.162 + _current = cs->locs_start()-1; 1.163 + _end = cs->locs_end(); 1.164 + _addr = cs->start(); 1.165 + _code = NULL; // Not cb->blob(); 1.166 + 1.167 + CodeBuffer* cb = cs->outer(); 1.168 + assert((int) SECT_LIMIT == CodeBuffer::SECT_LIMIT, "my copy must be equal"); 1.169 + for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) { 1.170 + CodeSection* cs = cb->code_section(n); 1.171 + _section_start[n] = cs->start(); 1.172 + _section_end [n] = cs->end(); 1.173 + } 1.174 + 1.175 + assert(!has_current(), "just checking"); 1.176 + 1.177 + assert(begin == NULL || begin >= cs->start(), "in bounds"); 1.178 + assert(limit == NULL || limit <= cs->end(), "in bounds"); 1.179 + set_limits(begin, limit); 1.180 +} 1.181 + 1.182 + 1.183 +enum { indexCardSize = 128 }; 1.184 +struct RelocIndexEntry { 1.185 + jint addr_offset; // offset from header_end of an addr() 1.186 + jint reloc_offset; // offset from header_end of a relocInfo (prefix) 1.187 +}; 1.188 + 1.189 + 1.190 +bool RelocIterator::addr_in_const() const { 1.191 + const int n = CodeBuffer::SECT_CONSTS; 1.192 + return section_start(n) <= addr() && addr() < section_end(n); 1.193 +} 1.194 + 1.195 + 1.196 +static inline int num_cards(int code_size) { 1.197 + return (code_size-1) / indexCardSize; 1.198 +} 1.199 + 1.200 + 1.201 +int RelocIterator::locs_and_index_size(int code_size, int locs_size) { 1.202 + if (!UseRelocIndex) return locs_size; // no index 1.203 + code_size = round_to(code_size, oopSize); 1.204 + locs_size = round_to(locs_size, oopSize); 1.205 + int index_size = num_cards(code_size) * sizeof(RelocIndexEntry); 1.206 + // format of indexed relocs: 1.207 + // relocation_begin: relocInfo ... 1.208 + // index: (addr,reloc#) ... 1.209 + // indexSize :relocation_end 1.210 + return locs_size + index_size + BytesPerInt; 1.211 +} 1.212 + 1.213 + 1.214 +void RelocIterator::create_index(relocInfo* dest_begin, int dest_count, relocInfo* dest_end) { 1.215 + address relocation_begin = (address)dest_begin; 1.216 + address relocation_end = (address)dest_end; 1.217 + int total_size = relocation_end - relocation_begin; 1.218 + int locs_size = dest_count * sizeof(relocInfo); 1.219 + if (!UseRelocIndex) { 1.220 + Copy::fill_to_bytes(relocation_begin + locs_size, total_size-locs_size, 0); 1.221 + return; 1.222 + } 1.223 + int index_size = total_size - locs_size - BytesPerInt; // find out how much space is left 1.224 + int ncards = index_size / sizeof(RelocIndexEntry); 1.225 + assert(total_size == locs_size + index_size + BytesPerInt, "checkin'"); 1.226 + assert(index_size >= 0 && index_size % sizeof(RelocIndexEntry) == 0, "checkin'"); 1.227 + jint* index_size_addr = (jint*)relocation_end - 1; 1.228 + 1.229 + assert(sizeof(jint) == BytesPerInt, "change this code"); 1.230 + 1.231 + *index_size_addr = index_size; 1.232 + if (index_size != 0) { 1.233 + assert(index_size > 0, "checkin'"); 1.234 + 1.235 + RelocIndexEntry* index = (RelocIndexEntry *)(relocation_begin + locs_size); 1.236 + assert(index == (RelocIndexEntry*)index_size_addr - ncards, "checkin'"); 1.237 + 1.238 + // walk over the relocations, and fill in index entries as we go 1.239 + RelocIterator iter; 1.240 + const address initial_addr = NULL; 1.241 + relocInfo* const initial_current = dest_begin - 1; // biased by -1 like elsewhere 1.242 + 1.243 + iter._code = NULL; 1.244 + iter._addr = initial_addr; 1.245 + iter._limit = (address)(intptr_t)(ncards * indexCardSize); 1.246 + iter._current = initial_current; 1.247 + iter._end = dest_begin + dest_count; 1.248 + 1.249 + int i = 0; 1.250 + address next_card_addr = (address)indexCardSize; 1.251 + int addr_offset = 0; 1.252 + int reloc_offset = 0; 1.253 + while (true) { 1.254 + // Checkpoint the iterator before advancing it. 1.255 + addr_offset = iter._addr - initial_addr; 1.256 + reloc_offset = iter._current - initial_current; 1.257 + if (!iter.next()) break; 1.258 + while (iter.addr() >= next_card_addr) { 1.259 + index[i].addr_offset = addr_offset; 1.260 + index[i].reloc_offset = reloc_offset; 1.261 + i++; 1.262 + next_card_addr += indexCardSize; 1.263 + } 1.264 + } 1.265 + while (i < ncards) { 1.266 + index[i].addr_offset = addr_offset; 1.267 + index[i].reloc_offset = reloc_offset; 1.268 + i++; 1.269 + } 1.270 + } 1.271 +} 1.272 + 1.273 + 1.274 +void RelocIterator::set_limits(address begin, address limit) { 1.275 + int index_size = 0; 1.276 + if (UseRelocIndex && _code != NULL) { 1.277 + index_size = ((jint*)_end)[-1]; 1.278 + _end = (relocInfo*)( (address)_end - index_size - BytesPerInt ); 1.279 + } 1.280 + 1.281 + _limit = limit; 1.282 + 1.283 + // the limit affects this next stuff: 1.284 + if (begin != NULL) { 1.285 +#ifdef ASSERT 1.286 + // In ASSERT mode we do not actually use the index, but simply 1.287 + // check that its contents would have led us to the right answer. 1.288 + address addrCheck = _addr; 1.289 + relocInfo* infoCheck = _current; 1.290 +#endif // ASSERT 1.291 + if (index_size > 0) { 1.292 + // skip ahead 1.293 + RelocIndexEntry* index = (RelocIndexEntry*)_end; 1.294 + RelocIndexEntry* index_limit = (RelocIndexEntry*)((address)index + index_size); 1.295 + assert(_addr == _code->code_begin(), "_addr must be unadjusted"); 1.296 + int card = (begin - _addr) / indexCardSize; 1.297 + if (card > 0) { 1.298 + if (index+card-1 < index_limit) index += card-1; 1.299 + else index = index_limit - 1; 1.300 +#ifdef ASSERT 1.301 + addrCheck = _addr + index->addr_offset; 1.302 + infoCheck = _current + index->reloc_offset; 1.303 +#else 1.304 + // Advance the iterator immediately to the last valid state 1.305 + // for the previous card. Calling "next" will then advance 1.306 + // it to the first item on the required card. 1.307 + _addr += index->addr_offset; 1.308 + _current += index->reloc_offset; 1.309 +#endif // ASSERT 1.310 + } 1.311 + } 1.312 + 1.313 + relocInfo* backup; 1.314 + address backup_addr; 1.315 + while (true) { 1.316 + backup = _current; 1.317 + backup_addr = _addr; 1.318 +#ifdef ASSERT 1.319 + if (backup == infoCheck) { 1.320 + assert(backup_addr == addrCheck, "must match"); addrCheck = NULL; infoCheck = NULL; 1.321 + } else { 1.322 + assert(addrCheck == NULL || backup_addr <= addrCheck, "must not pass addrCheck"); 1.323 + } 1.324 +#endif // ASSERT 1.325 + if (!next() || addr() >= begin) break; 1.326 + } 1.327 + assert(addrCheck == NULL || addrCheck == backup_addr, "must have matched addrCheck"); 1.328 + assert(infoCheck == NULL || infoCheck == backup, "must have matched infoCheck"); 1.329 + // At this point, either we are at the first matching record, 1.330 + // or else there is no such record, and !has_current(). 1.331 + // In either case, revert to the immediatly preceding state. 1.332 + _current = backup; 1.333 + _addr = backup_addr; 1.334 + set_has_current(false); 1.335 + } 1.336 +} 1.337 + 1.338 + 1.339 +void RelocIterator::set_limit(address limit) { 1.340 + address code_end = (address)code() + code()->size(); 1.341 + assert(limit == NULL || limit <= code_end, "in bounds"); 1.342 + _limit = limit; 1.343 +} 1.344 + 1.345 +// All the strange bit-encodings are in here. 1.346 +// The idea is to encode relocation data which are small integers 1.347 +// very efficiently (a single extra halfword). Larger chunks of 1.348 +// relocation data need a halfword header to hold their size. 1.349 +void RelocIterator::advance_over_prefix() { 1.350 + if (_current->is_datalen()) { 1.351 + _data = (short*) _current->data(); 1.352 + _datalen = _current->datalen(); 1.353 + _current += _datalen + 1; // skip the embedded data & header 1.354 + } else { 1.355 + _databuf = _current->immediate(); 1.356 + _data = &_databuf; 1.357 + _datalen = 1; 1.358 + _current++; // skip the header 1.359 + } 1.360 + // The client will see the following relocInfo, whatever that is. 1.361 + // It is the reloc to which the preceding data applies. 1.362 +} 1.363 + 1.364 + 1.365 +void RelocIterator::initialize_misc() { 1.366 + set_has_current(false); 1.367 + for (int i = (int) CodeBuffer::SECT_FIRST; i < (int) CodeBuffer::SECT_LIMIT; i++) { 1.368 + _section_start[i] = NULL; // these will be lazily computed, if needed 1.369 + _section_end [i] = NULL; 1.370 + } 1.371 +} 1.372 + 1.373 + 1.374 +Relocation* RelocIterator::reloc() { 1.375 + // (take the "switch" out-of-line) 1.376 + relocInfo::relocType t = type(); 1.377 + if (false) {} 1.378 + #define EACH_TYPE(name) \ 1.379 + else if (t == relocInfo::name##_type) { \ 1.380 + return name##_reloc(); \ 1.381 + } 1.382 + APPLY_TO_RELOCATIONS(EACH_TYPE); 1.383 + #undef EACH_TYPE 1.384 + assert(t == relocInfo::none, "must be padding"); 1.385 + return new(_rh) Relocation(); 1.386 +} 1.387 + 1.388 + 1.389 +//////// Methods for flyweight Relocation types 1.390 + 1.391 + 1.392 +RelocationHolder RelocationHolder::plus(int offset) const { 1.393 + if (offset != 0) { 1.394 + switch (type()) { 1.395 + case relocInfo::none: 1.396 + break; 1.397 + case relocInfo::oop_type: 1.398 + { 1.399 + oop_Relocation* r = (oop_Relocation*)reloc(); 1.400 + return oop_Relocation::spec(r->oop_index(), r->offset() + offset); 1.401 + } 1.402 + case relocInfo::metadata_type: 1.403 + { 1.404 + metadata_Relocation* r = (metadata_Relocation*)reloc(); 1.405 + return metadata_Relocation::spec(r->metadata_index(), r->offset() + offset); 1.406 + } 1.407 + default: 1.408 + ShouldNotReachHere(); 1.409 + } 1.410 + } 1.411 + return (*this); 1.412 +} 1.413 + 1.414 + 1.415 +void Relocation::guarantee_size() { 1.416 + guarantee(false, "Make _relocbuf bigger!"); 1.417 +} 1.418 + 1.419 + // some relocations can compute their own values 1.420 +address Relocation::value() { 1.421 + ShouldNotReachHere(); 1.422 + return NULL; 1.423 +} 1.424 + 1.425 + 1.426 +void Relocation::set_value(address x) { 1.427 + ShouldNotReachHere(); 1.428 +} 1.429 + 1.430 + 1.431 +RelocationHolder Relocation::spec_simple(relocInfo::relocType rtype) { 1.432 + if (rtype == relocInfo::none) return RelocationHolder::none; 1.433 + relocInfo ri = relocInfo(rtype, 0); 1.434 + RelocIterator itr; 1.435 + itr.set_current(ri); 1.436 + itr.reloc(); 1.437 + return itr._rh; 1.438 +} 1.439 + 1.440 +int32_t Relocation::runtime_address_to_index(address runtime_address) { 1.441 + assert(!is_reloc_index((intptr_t)runtime_address), "must not look like an index"); 1.442 + 1.443 + if (runtime_address == NULL) return 0; 1.444 + 1.445 + StubCodeDesc* p = StubCodeDesc::desc_for(runtime_address); 1.446 + if (p != NULL && p->begin() == runtime_address) { 1.447 + assert(is_reloc_index(p->index()), "there must not be too many stubs"); 1.448 + return (int32_t)p->index(); 1.449 + } else { 1.450 + // Known "miscellaneous" non-stub pointers: 1.451 + // os::get_polling_page(), SafepointSynchronize::address_of_state() 1.452 + if (PrintRelocations) { 1.453 + tty->print_cr("random unregistered address in relocInfo: " INTPTR_FORMAT, runtime_address); 1.454 + } 1.455 +#ifndef _LP64 1.456 + return (int32_t) (intptr_t)runtime_address; 1.457 +#else 1.458 + // didn't fit return non-index 1.459 + return -1; 1.460 +#endif /* _LP64 */ 1.461 + } 1.462 +} 1.463 + 1.464 + 1.465 +address Relocation::index_to_runtime_address(int32_t index) { 1.466 + if (index == 0) return NULL; 1.467 + 1.468 + if (is_reloc_index(index)) { 1.469 + StubCodeDesc* p = StubCodeDesc::desc_for_index(index); 1.470 + assert(p != NULL, "there must be a stub for this index"); 1.471 + return p->begin(); 1.472 + } else { 1.473 +#ifndef _LP64 1.474 + // this only works on 32bit machines 1.475 + return (address) ((intptr_t) index); 1.476 +#else 1.477 + fatal("Relocation::index_to_runtime_address, int32_t not pointer sized"); 1.478 + return NULL; 1.479 +#endif /* _LP64 */ 1.480 + } 1.481 +} 1.482 + 1.483 +address Relocation::old_addr_for(address newa, 1.484 + const CodeBuffer* src, CodeBuffer* dest) { 1.485 + int sect = dest->section_index_of(newa); 1.486 + guarantee(sect != CodeBuffer::SECT_NONE, "lost track of this address"); 1.487 + address ostart = src->code_section(sect)->start(); 1.488 + address nstart = dest->code_section(sect)->start(); 1.489 + return ostart + (newa - nstart); 1.490 +} 1.491 + 1.492 +address Relocation::new_addr_for(address olda, 1.493 + const CodeBuffer* src, CodeBuffer* dest) { 1.494 + debug_only(const CodeBuffer* src0 = src); 1.495 + int sect = CodeBuffer::SECT_NONE; 1.496 + // Look for olda in the source buffer, and all previous incarnations 1.497 + // if the source buffer has been expanded. 1.498 + for (; src != NULL; src = src->before_expand()) { 1.499 + sect = src->section_index_of(olda); 1.500 + if (sect != CodeBuffer::SECT_NONE) break; 1.501 + } 1.502 + guarantee(sect != CodeBuffer::SECT_NONE, "lost track of this address"); 1.503 + address ostart = src->code_section(sect)->start(); 1.504 + address nstart = dest->code_section(sect)->start(); 1.505 + return nstart + (olda - ostart); 1.506 +} 1.507 + 1.508 +void Relocation::normalize_address(address& addr, const CodeSection* dest, bool allow_other_sections) { 1.509 + address addr0 = addr; 1.510 + if (addr0 == NULL || dest->allocates2(addr0)) return; 1.511 + CodeBuffer* cb = dest->outer(); 1.512 + addr = new_addr_for(addr0, cb, cb); 1.513 + assert(allow_other_sections || dest->contains2(addr), 1.514 + "addr must be in required section"); 1.515 +} 1.516 + 1.517 + 1.518 +void CallRelocation::set_destination(address x) { 1.519 + pd_set_call_destination(x); 1.520 +} 1.521 + 1.522 +void CallRelocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { 1.523 + // Usually a self-relative reference to an external routine. 1.524 + // On some platforms, the reference is absolute (not self-relative). 1.525 + // The enhanced use of pd_call_destination sorts this all out. 1.526 + address orig_addr = old_addr_for(addr(), src, dest); 1.527 + address callee = pd_call_destination(orig_addr); 1.528 + // Reassert the callee address, this time in the new copy of the code. 1.529 + pd_set_call_destination(callee); 1.530 +} 1.531 + 1.532 + 1.533 +//// pack/unpack methods 1.534 + 1.535 +void oop_Relocation::pack_data_to(CodeSection* dest) { 1.536 + short* p = (short*) dest->locs_end(); 1.537 + p = pack_2_ints_to(p, _oop_index, _offset); 1.538 + dest->set_locs_end((relocInfo*) p); 1.539 +} 1.540 + 1.541 + 1.542 +void oop_Relocation::unpack_data() { 1.543 + unpack_2_ints(_oop_index, _offset); 1.544 +} 1.545 + 1.546 +void metadata_Relocation::pack_data_to(CodeSection* dest) { 1.547 + short* p = (short*) dest->locs_end(); 1.548 + p = pack_2_ints_to(p, _metadata_index, _offset); 1.549 + dest->set_locs_end((relocInfo*) p); 1.550 +} 1.551 + 1.552 + 1.553 +void metadata_Relocation::unpack_data() { 1.554 + unpack_2_ints(_metadata_index, _offset); 1.555 +} 1.556 + 1.557 + 1.558 +void virtual_call_Relocation::pack_data_to(CodeSection* dest) { 1.559 + short* p = (short*) dest->locs_end(); 1.560 + address point = dest->locs_point(); 1.561 + 1.562 + normalize_address(_cached_value, dest); 1.563 + jint x0 = scaled_offset_null_special(_cached_value, point); 1.564 + p = pack_1_int_to(p, x0); 1.565 + dest->set_locs_end((relocInfo*) p); 1.566 +} 1.567 + 1.568 + 1.569 +void virtual_call_Relocation::unpack_data() { 1.570 + jint x0 = unpack_1_int(); 1.571 + address point = addr(); 1.572 + _cached_value = x0==0? NULL: address_from_scaled_offset(x0, point); 1.573 +} 1.574 + 1.575 + 1.576 +void static_stub_Relocation::pack_data_to(CodeSection* dest) { 1.577 + short* p = (short*) dest->locs_end(); 1.578 + CodeSection* insts = dest->outer()->insts(); 1.579 + normalize_address(_static_call, insts); 1.580 + p = pack_1_int_to(p, scaled_offset(_static_call, insts->start())); 1.581 + dest->set_locs_end((relocInfo*) p); 1.582 +} 1.583 + 1.584 +void static_stub_Relocation::unpack_data() { 1.585 + address base = binding()->section_start(CodeBuffer::SECT_INSTS); 1.586 + _static_call = address_from_scaled_offset(unpack_1_int(), base); 1.587 +} 1.588 + 1.589 +void trampoline_stub_Relocation::pack_data_to(CodeSection* dest ) { 1.590 + short* p = (short*) dest->locs_end(); 1.591 + CodeSection* insts = dest->outer()->insts(); 1.592 + normalize_address(_owner, insts); 1.593 + p = pack_1_int_to(p, scaled_offset(_owner, insts->start())); 1.594 + dest->set_locs_end((relocInfo*) p); 1.595 +} 1.596 + 1.597 +void trampoline_stub_Relocation::unpack_data() { 1.598 + address base = binding()->section_start(CodeBuffer::SECT_INSTS); 1.599 + _owner = address_from_scaled_offset(unpack_1_int(), base); 1.600 +} 1.601 + 1.602 +void external_word_Relocation::pack_data_to(CodeSection* dest) { 1.603 + short* p = (short*) dest->locs_end(); 1.604 + int32_t index = runtime_address_to_index(_target); 1.605 +#ifndef _LP64 1.606 + p = pack_1_int_to(p, index); 1.607 +#else 1.608 + if (is_reloc_index(index)) { 1.609 + p = pack_2_ints_to(p, index, 0); 1.610 + } else { 1.611 + jlong t = (jlong) _target; 1.612 + int32_t lo = low(t); 1.613 + int32_t hi = high(t); 1.614 + p = pack_2_ints_to(p, lo, hi); 1.615 + DEBUG_ONLY(jlong t1 = jlong_from(hi, lo)); 1.616 + assert(!is_reloc_index(t1) && (address) t1 == _target, "not symmetric"); 1.617 + } 1.618 +#endif /* _LP64 */ 1.619 + dest->set_locs_end((relocInfo*) p); 1.620 +} 1.621 + 1.622 + 1.623 +void external_word_Relocation::unpack_data() { 1.624 +#ifndef _LP64 1.625 + _target = index_to_runtime_address(unpack_1_int()); 1.626 +#else 1.627 + int32_t lo, hi; 1.628 + unpack_2_ints(lo, hi); 1.629 + jlong t = jlong_from(hi, lo);; 1.630 + if (is_reloc_index(t)) { 1.631 + _target = index_to_runtime_address(t); 1.632 + } else { 1.633 + _target = (address) t; 1.634 + } 1.635 +#endif /* _LP64 */ 1.636 +} 1.637 + 1.638 + 1.639 +void internal_word_Relocation::pack_data_to(CodeSection* dest) { 1.640 + short* p = (short*) dest->locs_end(); 1.641 + normalize_address(_target, dest, true); 1.642 + 1.643 + // Check whether my target address is valid within this section. 1.644 + // If not, strengthen the relocation type to point to another section. 1.645 + int sindex = _section; 1.646 + if (sindex == CodeBuffer::SECT_NONE && _target != NULL 1.647 + && (!dest->allocates(_target) || _target == dest->locs_point())) { 1.648 + sindex = dest->outer()->section_index_of(_target); 1.649 + guarantee(sindex != CodeBuffer::SECT_NONE, "must belong somewhere"); 1.650 + relocInfo* base = dest->locs_end() - 1; 1.651 + assert(base->type() == this->type(), "sanity"); 1.652 + // Change the written type, to be section_word_type instead. 1.653 + base->set_type(relocInfo::section_word_type); 1.654 + } 1.655 + 1.656 + // Note: An internal_word relocation cannot refer to its own instruction, 1.657 + // because we reserve "0" to mean that the pointer itself is embedded 1.658 + // in the code stream. We use a section_word relocation for such cases. 1.659 + 1.660 + if (sindex == CodeBuffer::SECT_NONE) { 1.661 + assert(type() == relocInfo::internal_word_type, "must be base class"); 1.662 + guarantee(_target == NULL || dest->allocates2(_target), "must be within the given code section"); 1.663 + jint x0 = scaled_offset_null_special(_target, dest->locs_point()); 1.664 + assert(!(x0 == 0 && _target != NULL), "correct encoding of null target"); 1.665 + p = pack_1_int_to(p, x0); 1.666 + } else { 1.667 + assert(_target != NULL, "sanity"); 1.668 + CodeSection* sect = dest->outer()->code_section(sindex); 1.669 + guarantee(sect->allocates2(_target), "must be in correct section"); 1.670 + address base = sect->start(); 1.671 + jint offset = scaled_offset(_target, base); 1.672 + assert((uint)sindex < (uint)CodeBuffer::SECT_LIMIT, "sanity"); 1.673 + assert(CodeBuffer::SECT_LIMIT <= (1 << section_width), "section_width++"); 1.674 + p = pack_1_int_to(p, (offset << section_width) | sindex); 1.675 + } 1.676 + 1.677 + dest->set_locs_end((relocInfo*) p); 1.678 +} 1.679 + 1.680 + 1.681 +void internal_word_Relocation::unpack_data() { 1.682 + jint x0 = unpack_1_int(); 1.683 + _target = x0==0? NULL: address_from_scaled_offset(x0, addr()); 1.684 + _section = CodeBuffer::SECT_NONE; 1.685 +} 1.686 + 1.687 + 1.688 +void section_word_Relocation::unpack_data() { 1.689 + jint x = unpack_1_int(); 1.690 + jint offset = (x >> section_width); 1.691 + int sindex = (x & ((1<<section_width)-1)); 1.692 + address base = binding()->section_start(sindex); 1.693 + 1.694 + _section = sindex; 1.695 + _target = address_from_scaled_offset(offset, base); 1.696 +} 1.697 + 1.698 +//// miscellaneous methods 1.699 +oop* oop_Relocation::oop_addr() { 1.700 + int n = _oop_index; 1.701 + if (n == 0) { 1.702 + // oop is stored in the code stream 1.703 + return (oop*) pd_address_in_code(); 1.704 + } else { 1.705 + // oop is stored in table at nmethod::oops_begin 1.706 + return code()->oop_addr_at(n); 1.707 + } 1.708 +} 1.709 + 1.710 + 1.711 +oop oop_Relocation::oop_value() { 1.712 + oop v = *oop_addr(); 1.713 + // clean inline caches store a special pseudo-null 1.714 + if (v == (oop)Universe::non_oop_word()) v = NULL; 1.715 + return v; 1.716 +} 1.717 + 1.718 + 1.719 +void oop_Relocation::fix_oop_relocation() { 1.720 + if (!oop_is_immediate()) { 1.721 + // get the oop from the pool, and re-insert it into the instruction: 1.722 + set_value(value()); 1.723 + } 1.724 +} 1.725 + 1.726 + 1.727 +void oop_Relocation::verify_oop_relocation() { 1.728 + if (!oop_is_immediate()) { 1.729 + // get the oop from the pool, and re-insert it into the instruction: 1.730 + verify_value(value()); 1.731 + } 1.732 +} 1.733 + 1.734 +// meta data versions 1.735 +Metadata** metadata_Relocation::metadata_addr() { 1.736 + int n = _metadata_index; 1.737 + if (n == 0) { 1.738 + // metadata is stored in the code stream 1.739 + return (Metadata**) pd_address_in_code(); 1.740 + } else { 1.741 + // metadata is stored in table at nmethod::metadatas_begin 1.742 + return code()->metadata_addr_at(n); 1.743 + } 1.744 + } 1.745 + 1.746 + 1.747 +Metadata* metadata_Relocation::metadata_value() { 1.748 + Metadata* v = *metadata_addr(); 1.749 + // clean inline caches store a special pseudo-null 1.750 + if (v == (Metadata*)Universe::non_oop_word()) v = NULL; 1.751 + return v; 1.752 + } 1.753 + 1.754 + 1.755 +void metadata_Relocation::fix_metadata_relocation() { 1.756 + if (!metadata_is_immediate()) { 1.757 + // get the metadata from the pool, and re-insert it into the instruction: 1.758 + pd_fix_value(value()); 1.759 + } 1.760 +} 1.761 + 1.762 + 1.763 +void metadata_Relocation::verify_metadata_relocation() { 1.764 + if (!metadata_is_immediate()) { 1.765 + // get the metadata from the pool, and re-insert it into the instruction: 1.766 + verify_value(value()); 1.767 + } 1.768 +} 1.769 + 1.770 +address virtual_call_Relocation::cached_value() { 1.771 + assert(_cached_value != NULL && _cached_value < addr(), "must precede ic_call"); 1.772 + return _cached_value; 1.773 +} 1.774 + 1.775 + 1.776 +void virtual_call_Relocation::clear_inline_cache() { 1.777 + // No stubs for ICs 1.778 + // Clean IC 1.779 + ResourceMark rm; 1.780 + CompiledIC* icache = CompiledIC_at(this); 1.781 + icache->set_to_clean(); 1.782 +} 1.783 + 1.784 + 1.785 +void opt_virtual_call_Relocation::clear_inline_cache() { 1.786 + // No stubs for ICs 1.787 + // Clean IC 1.788 + ResourceMark rm; 1.789 + CompiledIC* icache = CompiledIC_at(this); 1.790 + icache->set_to_clean(); 1.791 +} 1.792 + 1.793 + 1.794 +address opt_virtual_call_Relocation::static_stub() { 1.795 + // search for the static stub who points back to this static call 1.796 + address static_call_addr = addr(); 1.797 + RelocIterator iter(code()); 1.798 + while (iter.next()) { 1.799 + if (iter.type() == relocInfo::static_stub_type) { 1.800 + if (iter.static_stub_reloc()->static_call() == static_call_addr) { 1.801 + return iter.addr(); 1.802 + } 1.803 + } 1.804 + } 1.805 + return NULL; 1.806 +} 1.807 + 1.808 + 1.809 +void static_call_Relocation::clear_inline_cache() { 1.810 + // Safe call site info 1.811 + CompiledStaticCall* handler = compiledStaticCall_at(this); 1.812 + handler->set_to_clean(); 1.813 +} 1.814 + 1.815 + 1.816 +address static_call_Relocation::static_stub() { 1.817 + // search for the static stub who points back to this static call 1.818 + address static_call_addr = addr(); 1.819 + RelocIterator iter(code()); 1.820 + while (iter.next()) { 1.821 + if (iter.type() == relocInfo::static_stub_type) { 1.822 + if (iter.static_stub_reloc()->static_call() == static_call_addr) { 1.823 + return iter.addr(); 1.824 + } 1.825 + } 1.826 + } 1.827 + return NULL; 1.828 +} 1.829 + 1.830 +// Finds the trampoline address for a call. If no trampoline stub is 1.831 +// found NULL is returned which can be handled by the caller. 1.832 +address trampoline_stub_Relocation::get_trampoline_for(address call, nmethod* code) { 1.833 + // There are no relocations available when the code gets relocated 1.834 + // because of CodeBuffer expansion. 1.835 + if (code->relocation_size() == 0) 1.836 + return NULL; 1.837 + 1.838 + RelocIterator iter(code, call); 1.839 + while (iter.next()) { 1.840 + if (iter.type() == relocInfo::trampoline_stub_type) { 1.841 + if (iter.trampoline_stub_reloc()->owner() == call) { 1.842 + return iter.addr(); 1.843 + } 1.844 + } 1.845 + } 1.846 + 1.847 + return NULL; 1.848 +} 1.849 + 1.850 +void static_stub_Relocation::clear_inline_cache() { 1.851 + // Call stub is only used when calling the interpreted code. 1.852 + // It does not really need to be cleared, except that we want to clean out the methodoop. 1.853 + CompiledStaticCall::set_stub_to_clean(this); 1.854 +} 1.855 + 1.856 + 1.857 +void external_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { 1.858 + address target = _target; 1.859 + if (target == NULL) { 1.860 + // An absolute embedded reference to an external location, 1.861 + // which means there is nothing to fix here. 1.862 + return; 1.863 + } 1.864 + // Probably this reference is absolute, not relative, so the 1.865 + // following is probably a no-op. 1.866 + assert(src->section_index_of(target) == CodeBuffer::SECT_NONE, "sanity"); 1.867 + set_value(target); 1.868 +} 1.869 + 1.870 + 1.871 +address external_word_Relocation::target() { 1.872 + address target = _target; 1.873 + if (target == NULL) { 1.874 + target = pd_get_address_from_code(); 1.875 + } 1.876 + return target; 1.877 +} 1.878 + 1.879 + 1.880 +void internal_word_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { 1.881 + address target = _target; 1.882 + if (target == NULL) { 1.883 + if (addr_in_const()) { 1.884 + target = new_addr_for(*(address*)addr(), src, dest); 1.885 + } else { 1.886 + target = new_addr_for(pd_get_address_from_code(), src, dest); 1.887 + } 1.888 + } 1.889 + set_value(target); 1.890 +} 1.891 + 1.892 + 1.893 +address internal_word_Relocation::target() { 1.894 + address target = _target; 1.895 + if (target == NULL) { 1.896 + target = pd_get_address_from_code(); 1.897 + } 1.898 + return target; 1.899 +} 1.900 + 1.901 +//--------------------------------------------------------------------------------- 1.902 +// Non-product code 1.903 + 1.904 +#ifndef PRODUCT 1.905 + 1.906 +static const char* reloc_type_string(relocInfo::relocType t) { 1.907 + switch (t) { 1.908 + #define EACH_CASE(name) \ 1.909 + case relocInfo::name##_type: \ 1.910 + return #name; 1.911 + 1.912 + APPLY_TO_RELOCATIONS(EACH_CASE); 1.913 + #undef EACH_CASE 1.914 + 1.915 + case relocInfo::none: 1.916 + return "none"; 1.917 + case relocInfo::data_prefix_tag: 1.918 + return "prefix"; 1.919 + default: 1.920 + return "UNKNOWN RELOC TYPE"; 1.921 + } 1.922 +} 1.923 + 1.924 + 1.925 +void RelocIterator::print_current() { 1.926 + if (!has_current()) { 1.927 + tty->print_cr("(no relocs)"); 1.928 + return; 1.929 + } 1.930 + tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d", 1.931 + _current, type(), reloc_type_string((relocInfo::relocType) type()), _addr, _current->addr_offset()); 1.932 + if (current()->format() != 0) 1.933 + tty->print(" format=%d", current()->format()); 1.934 + if (datalen() == 1) { 1.935 + tty->print(" data=%d", data()[0]); 1.936 + } else if (datalen() > 0) { 1.937 + tty->print(" data={"); 1.938 + for (int i = 0; i < datalen(); i++) { 1.939 + tty->print("%04x", data()[i] & 0xFFFF); 1.940 + } 1.941 + tty->print("}"); 1.942 + } 1.943 + tty->print("]"); 1.944 + switch (type()) { 1.945 + case relocInfo::oop_type: 1.946 + { 1.947 + oop_Relocation* r = oop_reloc(); 1.948 + oop* oop_addr = NULL; 1.949 + oop raw_oop = NULL; 1.950 + oop oop_value = NULL; 1.951 + if (code() != NULL || r->oop_is_immediate()) { 1.952 + oop_addr = r->oop_addr(); 1.953 + raw_oop = *oop_addr; 1.954 + oop_value = r->oop_value(); 1.955 + } 1.956 + tty->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]", 1.957 + oop_addr, (address)raw_oop, r->offset()); 1.958 + // Do not print the oop by default--we want this routine to 1.959 + // work even during GC or other inconvenient times. 1.960 + if (WizardMode && oop_value != NULL) { 1.961 + tty->print("oop_value=" INTPTR_FORMAT ": ", (address)oop_value); 1.962 + oop_value->print_value_on(tty); 1.963 + } 1.964 + break; 1.965 + } 1.966 + case relocInfo::metadata_type: 1.967 + { 1.968 + metadata_Relocation* r = metadata_reloc(); 1.969 + Metadata** metadata_addr = NULL; 1.970 + Metadata* raw_metadata = NULL; 1.971 + Metadata* metadata_value = NULL; 1.972 + if (code() != NULL || r->metadata_is_immediate()) { 1.973 + metadata_addr = r->metadata_addr(); 1.974 + raw_metadata = *metadata_addr; 1.975 + metadata_value = r->metadata_value(); 1.976 + } 1.977 + tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " offset=%d]", 1.978 + metadata_addr, (address)raw_metadata, r->offset()); 1.979 + if (metadata_value != NULL) { 1.980 + tty->print("metadata_value=" INTPTR_FORMAT ": ", (address)metadata_value); 1.981 + metadata_value->print_value_on(tty); 1.982 + } 1.983 + break; 1.984 + } 1.985 + case relocInfo::external_word_type: 1.986 + case relocInfo::internal_word_type: 1.987 + case relocInfo::section_word_type: 1.988 + { 1.989 + DataRelocation* r = (DataRelocation*) reloc(); 1.990 + tty->print(" | [target=" INTPTR_FORMAT "]", r->value()); //value==target 1.991 + break; 1.992 + } 1.993 + case relocInfo::static_call_type: 1.994 + case relocInfo::runtime_call_type: 1.995 + { 1.996 + CallRelocation* r = (CallRelocation*) reloc(); 1.997 + tty->print(" | [destination=" INTPTR_FORMAT "]", r->destination()); 1.998 + break; 1.999 + } 1.1000 + case relocInfo::virtual_call_type: 1.1001 + { 1.1002 + virtual_call_Relocation* r = (virtual_call_Relocation*) reloc(); 1.1003 + tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT "]", 1.1004 + r->destination(), r->cached_value()); 1.1005 + break; 1.1006 + } 1.1007 + case relocInfo::static_stub_type: 1.1008 + { 1.1009 + static_stub_Relocation* r = (static_stub_Relocation*) reloc(); 1.1010 + tty->print(" | [static_call=" INTPTR_FORMAT "]", r->static_call()); 1.1011 + break; 1.1012 + } 1.1013 + case relocInfo::trampoline_stub_type: 1.1014 + { 1.1015 + trampoline_stub_Relocation* r = (trampoline_stub_Relocation*) reloc(); 1.1016 + tty->print(" | [trampoline owner=" INTPTR_FORMAT "]", r->owner()); 1.1017 + break; 1.1018 + } 1.1019 + } 1.1020 + tty->cr(); 1.1021 +} 1.1022 + 1.1023 + 1.1024 +void RelocIterator::print() { 1.1025 + RelocIterator save_this = (*this); 1.1026 + relocInfo* scan = _current; 1.1027 + if (!has_current()) scan += 1; // nothing to scan here! 1.1028 + 1.1029 + bool skip_next = has_current(); 1.1030 + bool got_next; 1.1031 + while (true) { 1.1032 + got_next = (skip_next || next()); 1.1033 + skip_next = false; 1.1034 + 1.1035 + tty->print(" @" INTPTR_FORMAT ": ", scan); 1.1036 + relocInfo* newscan = _current+1; 1.1037 + if (!has_current()) newscan -= 1; // nothing to scan here! 1.1038 + while (scan < newscan) { 1.1039 + tty->print("%04x", *(short*)scan & 0xFFFF); 1.1040 + scan++; 1.1041 + } 1.1042 + tty->cr(); 1.1043 + 1.1044 + if (!got_next) break; 1.1045 + print_current(); 1.1046 + } 1.1047 + 1.1048 + (*this) = save_this; 1.1049 +} 1.1050 + 1.1051 +// For the debugger: 1.1052 +extern "C" 1.1053 +void print_blob_locs(nmethod* nm) { 1.1054 + nm->print(); 1.1055 + RelocIterator iter(nm); 1.1056 + iter.print(); 1.1057 +} 1.1058 +extern "C" 1.1059 +void print_buf_locs(CodeBuffer* cb) { 1.1060 + FlagSetting fs(PrintRelocations, true); 1.1061 + cb->print(); 1.1062 +} 1.1063 +#endif // !PRODUCT