src/share/vm/code/relocInfo.cpp

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

mercurial