< prev index next >

src/hotspot/share/code/relocInfo.cpp

Print this page
*** 21,14 ***
--- 21,16 ---
   * 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"

*** 171,10 ***
--- 173,13 ---
    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) {

*** 461,15 ***
  }
  
  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);
    dest->set_locs_end((relocInfo*) p);
  }
  
- 
  void external_word_Relocation::unpack_data() {
    int index = unpack_1_int();
    _target = ExternalsRecorder::at(index);
  }
  
--- 466,16 ---
  }
  
  void external_word_Relocation::pack_data_to(CodeSection* dest) {
    short* p = (short*) dest->locs_end();
    int index = ExternalsRecorder::find_index(_target);
!   // 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);
  }
  

*** 734,10 ***
--- 740,18 ---
      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);
  }
  
  

*** 769,16 ***
      }
    }
    return target;
  }
  
! //---------------------------------------------------------------------------------
- // Non-product code
- 
- #ifndef PRODUCT
- 
- static const char* reloc_type_string(relocInfo::relocType t) {
    switch (t) {
    #define EACH_CASE(name) \
    case relocInfo::name##_type: \
      return #name;
  
--- 783,11 ---
      }
    }
    return target;
  }
  
! const char* relocInfo::type_name(relocInfo::relocType t) {
    switch (t) {
    #define EACH_CASE(name) \
    case relocInfo::name##_type: \
      return #name;
  

*** 793,29 ***
      return "UNKNOWN RELOC TYPE";
    }
  }
  
  
! void RelocIterator::print_current() {
    if (!has_current()) {
!     tty->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());
    if (current()->format() != 0)
!     tty->print(" format=%d", current()->format());
    if (datalen() == 1) {
!     tty->print(" data=%d", data()[0]);
    } else if (datalen() > 0) {
!     tty->print(" data={");
      for (int i = 0; i < datalen(); i++) {
!       tty->print("%04x", data()[i] & 0xFFFF);
      }
!     tty->print("}");
    }
!   tty->print("]");
    switch (type()) {
    case relocInfo::oop_type:
      {
        oop_Relocation* r = oop_reloc();
        oop* oop_addr  = nullptr;
--- 802,29 ---
      return "UNKNOWN RELOC TYPE";
    }
  }
  
  
! void RelocIterator::print_current_on(outputStream* st) {
    if (!has_current()) {
!     st->print_cr("(no relocs)");
      return;
    }
!   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)
!     st->print(" format=%d", current()->format());
    if (datalen() == 1) {
!     st->print(" data=%d", data()[0]);
    } else if (datalen() > 0) {
!     st->print(" data={");
      for (int i = 0; i < datalen(); i++) {
!       st->print("%04x", data()[i] & 0xFFFF);
      }
!     st->print("}");
    }
!   st->print("]");
    switch (type()) {
    case relocInfo::oop_type:
      {
        oop_Relocation* r = oop_reloc();
        oop* oop_addr  = nullptr;

*** 824,18 ***
        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));
        // 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));
          if (oopDesc::is_oop(oop_value)) {
!           oop_value->print_value_on(tty);
          }
        }
        break;
      }
    case relocInfo::metadata_type:
--- 833,18 ---
        if (code() != nullptr || r->oop_is_immediate()) {
          oop_addr  = r->oop_addr();
          raw_oop   = *oop_addr;
          oop_value = r->oop_value();
        }
!       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) {
!         st->print("oop_value=" INTPTR_FORMAT ": ", p2i(oop_value));
          if (oopDesc::is_oop(oop_value)) {
!           oop_value->print_value_on(st);
          }
        }
        break;
      }
    case relocInfo::metadata_type:

*** 847,108 ***
        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));
        if (metadata_value != nullptr) {
!         tty->print("metadata_value=" INTPTR_FORMAT ": ", p2i(metadata_value));
!         metadata_value->print_value_on(tty);
        }
        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
        break;
      }
    case relocInfo::static_call_type:
      {
        static_call_Relocation* r = (static_call_Relocation*) reloc();
!       tty->print(" | [destination=" INTPTR_FORMAT " metadata=" INTPTR_FORMAT "]",
                   p2i(r->destination()), p2i(r->method_value()));
        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()));
        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()));
        break;
      }
    case relocInfo::static_stub_type:
      {
        static_stub_Relocation* r = (static_stub_Relocation*) reloc();
!       tty->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()));
        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 "]",
                   p2i(r->destination()), p2i(r->method_value()));
        break;
      }
    default:
      break;
    }
!   tty->cr();
  }
  
  
! void RelocIterator::print() {
    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));
      relocInfo* newscan = _current+1;
      if (!has_current())  newscan -= 1;  // nothing to scan here!
      while (scan < newscan) {
!       tty->print("%04x", *(short*)scan & 0xFFFF);
        scan++;
      }
!     tty->cr();
  
      if (!got_next)  break;
!     print_current();
    }
  
    (*this) = save_this;
  }
  
  // For the debugger:
  extern "C"
  void print_blob_locs(nmethod* nm) {
    nm->print();
    RelocIterator iter(nm);
!   iter.print();
  }
  extern "C"
  void print_buf_locs(CodeBuffer* cb) {
    FlagSetting fs(PrintRelocations, true);
!   cb->print();
  }
  #endif // !PRODUCT
--- 856,151 ---
        if (code() != nullptr || r->metadata_is_immediate()) {
          metadata_addr  = r->metadata_addr();
          raw_metadata   = *metadata_addr;
          metadata_value = r->metadata_value();
        }
!       st->print(" | [metadata_addr=" INTPTR_FORMAT " *=" INTPTR_FORMAT " index=%d]",
!                  p2i(metadata_addr), p2i(raw_metadata), r->metadata_index());
        if (metadata_value != nullptr) {
!         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();
!       st->print(" | [target=" INTPTR_FORMAT "]", p2i(r->value())); //value==target
        break;
      }
    case relocInfo::static_call_type:
      {
        static_call_Relocation* r = (static_call_Relocation*) reloc();
!       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();
!       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();
!       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();
!       st->print(" | [static_call=" INTPTR_FORMAT "]", p2i(r->static_call()));
        break;
      }
    case relocInfo::trampoline_stub_type:
      {
        trampoline_stub_Relocation* r = (trampoline_stub_Relocation*) reloc();
!       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();
!       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;
    }
!   st->cr();
  }
  
  
! 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;
  
!     st->print("         @" INTPTR_FORMAT ": ", p2i(scan));
      relocInfo* newscan = _current+1;
      if (!has_current())  newscan -= 1;  // nothing to scan here!
      while (scan < newscan) {
!       st->print("%04x", *(short*)scan & 0xFFFF);
        scan++;
      }
!     st->cr();
  
      if (!got_next)  break;
!     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_on(tty);
  }
  extern "C"
  void print_buf_locs(CodeBuffer* cb) {
    FlagSetting fs(PrintRelocations, true);
!   cb->print_on(tty);
  }
  #endif // !PRODUCT
< prev index next >