< prev index next > src/hotspot/share/code/relocInfo.cpp
Print this page
* questions.
*
*/
#include "precompiled.hpp"
+ #include "ci/ciUtilities.hpp"
#include "code/codeCache.hpp"
#include "code/compiledIC.hpp"
#include "code/nmethod.hpp"
#include "code/relocInfo.hpp"
+ #include "code/SCCache.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/compressedOops.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/flags/flagSetting.hpp"
set_limits(begin, limit);
}
bool RelocIterator::addr_in_const() const {
const int n = CodeBuffer::SECT_CONSTS;
+ if (_section_start[n] == nullptr) {
+ return false;
+ }
return section_start(n) <= addr() && addr() < section_end(n);
}
void RelocIterator::set_limits(address begin, address limit) {
}
void external_word_Relocation::pack_data_to(CodeSection* dest) {
short* p = (short*) dest->locs_end();
int index = ExternalsRecorder::find_index(_target);
- p = pack_1_int_to(p, index);
+ // Use 4 bytes to store index to be able patch it when
+ // updating relocations in SCCReader::read_relocations().
+ p = add_jint(p, index);
dest->set_locs_end((relocInfo*) p);
}
-
void external_word_Relocation::unpack_data() {
int index = unpack_1_int();
_target = ExternalsRecorder::at(index);
}
set_value(_target);
}
// If target is nullptr, this is an absolute embedded reference to an external
// location, which means there is nothing to fix here. In either case, the
// resulting target should be an "external" address.
+ #ifdef ASSERT
+ if (SCCache::is_on()) {
+ // SCA needs relocation info for card table base which may point to CodeCache
+ if (is_card_table_address(target())) {
+ return;
+ }
+ }
+ #endif
postcond(src->section_index_of(target()) == CodeBuffer::SECT_NONE);
postcond(dest->section_index_of(target()) == CodeBuffer::SECT_NONE);
}
}
}
return target;
}
- //---------------------------------------------------------------------------------
- // Non-product code
-
- #ifndef PRODUCT
-
- static const char* reloc_type_string(relocInfo::relocType t) {
+ const char* relocInfo::type_name(relocInfo::relocType t) {
switch (t) {
#define EACH_CASE(name) \
case relocInfo::name##_type: \
return #name;
return "UNKNOWN RELOC TYPE";
}
}
- void RelocIterator::print_current() {
+ void RelocIterator::print_current_on(outputStream* st) {
if (!has_current()) {
- tty->print_cr("(no relocs)");
+ st->print_cr("(no relocs)");
return;
}
- tty->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d",
- p2i(_current), type(), reloc_type_string((relocInfo::relocType) type()), p2i(_addr), _current->addr_offset());
+ st->print("relocInfo@" INTPTR_FORMAT " [type=%d(%s) addr=" INTPTR_FORMAT " offset=%d",
+ p2i(_current), type(), relocInfo::type_name(type()), p2i(_addr), _current->addr_offset());
if (current()->format() != 0)
- tty->print(" format=%d", current()->format());
+ st->print(" format=%d", current()->format());
if (datalen() == 1) {
- tty->print(" data=%d", data()[0]);
+ st->print(" data=%d", data()[0]);
} else if (datalen() > 0) {
- tty->print(" data={");
+ st->print(" data={");
for (int i = 0; i < datalen(); i++) {
- tty->print("%04x", data()[i] & 0xFFFF);
+ st->print("%04x", data()[i] & 0xFFFF);
}
- tty->print("}");
+ st->print("}");
}
- tty->print("]");
+ st->print("]");
switch (type()) {
case relocInfo::oop_type:
{
oop_Relocation* r = oop_reloc();
oop* oop_addr = nullptr;
if (code() != nullptr || r->oop_is_immediate()) {
oop_addr = r->oop_addr();
raw_oop = *oop_addr;
oop_value = r->oop_value();
}
- tty->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT "]",
- p2i(oop_addr), p2i(raw_oop));
+ st->print(" | [oop_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " index=%d]",
+ p2i(oop_addr), p2i(raw_oop), r->oop_index());
// Do not print the oop by default--we want this routine to
// work even during GC or other inconvenient times.
if (WizardMode && oop_value != nullptr) {
- tty->print("oop_value=" INTPTR_FORMAT ": ", p2i(oop_value));
+ st->print("oop_value=" INTPTR_FORMAT ": ", p2i(oop_value));
if (oopDesc::is_oop(oop_value)) {
- oop_value->print_value_on(tty);
+ oop_value->print_value_on(st);
}
}
break;
}
case relocInfo::metadata_type:
if (code() != nullptr || r->metadata_is_immediate()) {
metadata_addr = r->metadata_addr();
raw_metadata = *metadata_addr;
metadata_value = r->metadata_value();
}
- tty->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT "]",
- p2i(metadata_addr), p2i(raw_metadata));
+ st->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " index=%d]",
+ p2i(metadata_addr), p2i(raw_metadata), r->metadata_index());
if (metadata_value != nullptr) {
- tty->print("metadata_value=" INTPTR_FORMAT ": ", p2i(metadata_value));
- metadata_value->print_value_on(tty);
+ st->print("metadata_value=" INTPTR_FORMAT ": ", p2i(metadata_value));
+ metadata_value->print_value_on(st);
}
break;
}
case relocInfo::external_word_type:
case relocInfo::internal_word_type:
case relocInfo::section_word_type:
{
DataRelocation* r = (DataRelocation*) reloc();
- tty->print(" | [target=" INTPTR_FORMAT "]", p2i(r->value())); //value==target
+ st->print(" | [target=" INTPTR_FORMAT "]", p2i(r->value())); //value==target
break;
}
case relocInfo::static_call_type:
{
static_call_Relocation* r = (static_call_Relocation*) reloc();
- tty->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
+ st->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
p2i(r->destination()), p2i(r->method_value()));
+ CodeBlob* cb = CodeCache::find_blob(r->destination());
+ if (cb != nullptr) {
+ st->print(" Blob::%s", cb->name());
+ }
break;
}
case relocInfo::runtime_call_type:
case relocInfo::runtime_call_w_cp_type:
{
CallRelocation* r = (CallRelocation*) reloc();
- tty->print(" | [destination=" INTPTR_FORMAT "]", p2i(r->destination()));
+ address dest = r->destination();
+ st->print(" | [destination=" INTPTR_FORMAT "]", p2i(dest));
+ if (StubRoutines::contains(dest)) {
+ StubCodeDesc* desc = StubCodeDesc::desc_for(dest);
+ if (desc == nullptr) {
+ desc = StubCodeDesc::desc_for(dest + frame::pc_return_offset);
+ }
+ if (desc != nullptr) {
+ st->print(" Stub::%s", desc->name());
+ }
+ } else {
+ CodeBlob* cb = CodeCache::find_blob(dest);
+ if (cb != nullptr) {
+ st->print(" Blob::%s", cb->name());
+ } else {
+ ResourceMark rm;
+ const int buflen = 1024;
+ char* buf = NEW_RESOURCE_ARRAY(char, buflen);
+ int offset;
+ if (os::dll_address_to_function_name(dest, buf, buflen, &offset)) {
+ st->print(" %s", buf);
+ if (offset != 0) {
+ st->print("+%d", offset);
+ }
+ }
+ }
+ }
break;
}
case relocInfo::virtual_call_type:
{
virtual_call_Relocation* r = (virtual_call_Relocation*) reloc();
- tty->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
- p2i(r->destination()), p2i(r->cached_value()), p2i(r->method_value()));
+ st->print(" | [destination=" INTPTR_FORMAT " cached_value=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
+ p2i(r->destination()), p2i(r->cached_value()), p2i(r->method_value()));
+ CodeBlob* cb = CodeCache::find_blob(r->destination());
+ if (cb != nullptr) {
+ st->print(" Blob::%s", cb->name());
+ }
break;
}
case relocInfo::static_stub_type:
{
static_stub_Relocation* r = (static_stub_Relocation*) reloc();
- tty->print(" | [static_call=" INTPTR_FORMAT "]", p2i(r->static_call()));
+ st->print(" | [static_call=" INTPTR_FORMAT "]", p2i(r->static_call()));
break;
}
case relocInfo::trampoline_stub_type:
{
trampoline_stub_Relocation* r = (trampoline_stub_Relocation*) reloc();
- tty->print(" | [trampoline owner=" INTPTR_FORMAT "]", p2i(r->owner()));
+ st->print(" | [trampoline owner=" INTPTR_FORMAT "]", p2i(r->owner()));
break;
}
case relocInfo::opt_virtual_call_type:
{
opt_virtual_call_Relocation* r = (opt_virtual_call_Relocation*) reloc();
- tty->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
+ st->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
p2i(r->destination()), p2i(r->method_value()));
+ CodeBlob* cb = CodeCache::find_blob(r->destination());
+ if (cb != nullptr) {
+ st->print(" Blob::%s", cb->name());
+ }
break;
}
default:
break;
}
- tty->cr();
+ st->cr();
}
- void RelocIterator::print() {
+ void RelocIterator::print_on(outputStream* st) {
RelocIterator save_this = (*this);
relocInfo* scan = _current;
if (!has_current()) scan += 1; // nothing to scan here!
bool skip_next = has_current();
bool got_next;
while (true) {
got_next = (skip_next || next());
skip_next = false;
- tty->print(" @" INTPTR_FORMAT ": ", p2i(scan));
+ st->print(" @" INTPTR_FORMAT ": ", p2i(scan));
relocInfo* newscan = _current+1;
if (!has_current()) newscan -= 1; // nothing to scan here!
while (scan < newscan) {
- tty->print("%04x", *(short*)scan & 0xFFFF);
+ st->print("%04x", *(short*)scan & 0xFFFF);
scan++;
}
- tty->cr();
+ st->cr();
if (!got_next) break;
- print_current();
+ print_current_on(st);
}
(*this) = save_this;
}
+ //---------------------------------------------------------------------------------
+ // Non-product code
+
+ #ifndef PRODUCT
+
// For the debugger:
extern "C"
void print_blob_locs(nmethod* nm) {
nm->print();
RelocIterator iter(nm);
- iter.print();
+ iter.print_on(tty);
}
extern "C"
void print_buf_locs(CodeBuffer* cb) {
FlagSetting fs(PrintRelocations, true);
- cb->print();
+ cb->print_on(tty);
}
#endif // !PRODUCT
< prev index next >