< 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"

@@ -172,10 +174,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) {

@@ -451,23 +456,25 @@
  void trampoline_stub_Relocation::unpack_data() {
    address base = binding()->section_start(CodeBuffer::SECT_INSTS);
    _owner = address_from_scaled_offset(unpack_1_int(), base);
  }
  
- void external_word_Relocation::pack_data_to(CodeSection* dest) {
-   short* p = (short*) dest->locs_end();
+ short* external_word_Relocation::pack_data_to(short* p) {
  #ifndef _LP64
-   p = pack_1_int_to(p, (int32_t) (intptr_t)_target);
+   return pack_1_int_to(p, (int32_t) (intptr_t)_target);
  #else
    jlong t = (jlong) _target;
    int32_t lo = low(t);
    int32_t hi = high(t);
-   p = pack_2_ints_to(p, lo, hi);
+   return pack_2_ints_to(p, lo, hi);
  #endif /* _LP64 */
-   dest->set_locs_end((relocInfo*) p);
  }
  
+ void external_word_Relocation::pack_data_to(CodeSection* dest) {
+   short* p = (short*) dest->locs_end();
+   dest->set_locs_end((relocInfo*)pack_data_to(p));
+ }
  
  void external_word_Relocation::unpack_data() {
  #ifndef _LP64
    _target = (address) (intptr_t)unpack_1_int();
  #else

@@ -739,10 +746,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);
  }
  
  

@@ -774,16 +789,11 @@
      }
    }
    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;
  

@@ -798,29 +808,29 @@
      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;

@@ -829,18 +839,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));
+       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:

@@ -852,108 +862,151 @@
        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 >