< prev index next >

src/hotspot/share/asm/codeBuffer.cpp

Print this page
*** 26,10 ***
--- 26,11 ---
  #include "code/compiledIC.hpp"
  #include "code/oopRecorder.inline.hpp"
  #include "compiler/disassembler.hpp"
  #include "logging/log.hpp"
  #include "oops/klass.inline.hpp"
+ #include "oops/methodCounters.hpp"
  #include "oops/methodData.hpp"
  #include "oops/oop.inline.hpp"
  #include "runtime/icache.hpp"
  #include "runtime/safepointVerifiers.hpp"
  #include "utilities/align.hpp"

*** 534,10 ***
--- 535,13 ---
            Metadata* m = md->metadata_value();
            if (oop_recorder()->is_real(m)) {
              if (m->is_methodData()) {
                m = ((MethodData*)m)->method();
              }
+             if (m->is_methodCounters()) {
+               m = ((MethodCounters*)m)->method();
+             }
              if (m->is_method()) {
                m = ((Method*)m)->method_holder();
              }
              if (m->is_klass()) {
                append_oop_references(&oops, (Klass*)m);

*** 558,10 ***
--- 562,13 ---
        Metadata* m = oop_recorder()->metadata_at(i);
        if (oop_recorder()->is_real(m)) {
          if (m->is_methodData()) {
            m = ((MethodData*)m)->method();
          }
+         if (m->is_methodCounters()) {
+           m = ((MethodCounters*)m)->method();
+         }
          if (m->is_method()) {
            m = ((Method*)m)->method_holder();
          }
          if (m->is_klass()) {
            append_oop_references(&oops, (Klass*)m);

*** 720,11 ***
  
  void CodeBuffer::copy_code_to(CodeBlob* dest_blob) {
  #ifndef PRODUCT
    if (PrintNMethods && (WizardMode || Verbose)) {
      tty->print("done with CodeBuffer:");
!     ((CodeBuffer*)this)->print();
    }
  #endif //PRODUCT
  
    CodeBuffer dest(dest_blob);
    assert(dest_blob->content_size() >= total_content_size(), "good sizing");
--- 727,11 ---
  
  void CodeBuffer::copy_code_to(CodeBlob* dest_blob) {
  #ifndef PRODUCT
    if (PrintNMethods && (WizardMode || Verbose)) {
      tty->print("done with CodeBuffer:");
!     ((CodeBuffer*)this)->print_on(tty);
    }
  #endif //PRODUCT
  
    CodeBuffer dest(dest_blob);
    assert(dest_blob->content_size() >= total_content_size(), "good sizing");

*** 859,11 ***
  
  void CodeBuffer::expand(CodeSection* which_cs, csize_t amount) {
  #ifndef PRODUCT
    if (PrintNMethods && (WizardMode || Verbose)) {
      tty->print("expanding CodeBuffer:");
!     this->print();
    }
  
    if (StressCodeBuffers && blob() != nullptr) {
      static int expand_count = 0;
      if (expand_count >= 0)  expand_count += 1;
--- 866,11 ---
  
  void CodeBuffer::expand(CodeSection* which_cs, csize_t amount) {
  #ifndef PRODUCT
    if (PrintNMethods && (WizardMode || Verbose)) {
      tty->print("expanding CodeBuffer:");
!     this->print_on(tty);
    }
  
    if (StressCodeBuffers && blob() != nullptr) {
      static int expand_count = 0;
      if (expand_count >= 0)  expand_count += 1;

*** 947,11 ***
  
  #ifndef PRODUCT
    _decode_begin = nullptr;  // sanity
    if (PrintNMethods && (WizardMode || Verbose)) {
      tty->print("expanded CodeBuffer:");
!     this->print();
    }
  #endif //PRODUCT
  }
  
  void CodeBuffer::adjust_internal_address(address from, address to) {
--- 954,11 ---
  
  #ifndef PRODUCT
    _decode_begin = nullptr;  // sanity
    if (PrintNMethods && (WizardMode || Verbose)) {
      tty->print("expanded CodeBuffer:");
!     this->print_on(tty);
    }
  #endif //PRODUCT
  }
  
  void CodeBuffer::adjust_internal_address(address from, address to) {

*** 1000,27 ***
        if (!other->is_allocated() || other == sect) {
          continue;
        }
        guarantee(other->disjoint(sect), "sanity");
      }
!     guarantee(sect->end() <= tend, "sanity");
!     guarantee(sect->end() <= sect->limit(), "sanity");
    }
  }
  
  void CodeBuffer::log_section_sizes(const char* name) {
    if (xtty != nullptr) {
      ttyLocker ttyl;
      // log info about buffer usage
!     xtty->print_cr("<blob name='%s' total_size='%d'>", name, _total_size);
      for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
        CodeSection* sect = code_section(n);
        if (!sect->is_allocated() || sect->is_empty())  continue;
!       xtty->print_cr("<sect index='%d' capacity='%d' size='%d' remaining='%d'/>",
!                      n, sect->capacity(), sect->size(), sect->remaining());
      }
!     xtty->print_cr("</blob>");
    }
  }
  
  bool CodeBuffer::finalize_stubs() {
    if (_finalize_stubs && !pd_finalize_stubs()) {
--- 1007,27 ---
        if (!other->is_allocated() || other == sect) {
          continue;
        }
        guarantee(other->disjoint(sect), "sanity");
      }
!     guarantee(sect->end() <= tend, "sanity, sect_end: " PTR_FORMAT " tend: " PTR_FORMAT " size: %d", p2i(sect->end()), p2i(tend), (int)_total_size);
!     guarantee(sect->end() <= sect->limit(), "sanity, sect_end: " PTR_FORMAT " sect_limit: " PTR_FORMAT, p2i(sect->end()), p2i(sect->limit()));
    }
  }
  
  void CodeBuffer::log_section_sizes(const char* name) {
    if (xtty != nullptr) {
      ttyLocker ttyl;
      // log info about buffer usage
!     xtty->head("blob name='%s' total_size='%d'", name, _total_size);
      for (int n = (int) CodeBuffer::SECT_FIRST; n < (int) CodeBuffer::SECT_LIMIT; n++) {
        CodeSection* sect = code_section(n);
        if (!sect->is_allocated() || sect->is_empty())  continue;
!       xtty->elem("sect index='%d' capacity='%d' size='%d' remaining='%d'",
!                  n, sect->capacity(), sect->size(), sect->remaining());
      }
!     xtty->tail("blob");
    }
  }
  
  bool CodeBuffer::finalize_stubs() {
    if (_finalize_stubs && !pd_finalize_stubs()) {

*** 1058,130 ***
    ttyLocker ttyl;
    Disassembler::decode(decode_begin(), insts_end(), tty NOT_PRODUCT(COMMA &asm_remarks()));
    _decode_begin = insts_end();
  }
  
! void CodeSection::print(const char* name) {
    csize_t locs_size = locs_end() - locs_start();
!   tty->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)",
!                 name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity());
!   tty->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d",
!                 name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off());
    if (PrintRelocations && (locs_size != 0)) {
      RelocIterator iter(this);
!     iter.print();
    }
  }
  
! void CodeBuffer::print() {
!   tty->print_cr("CodeBuffer:");
    for (int n = 0; n < (int)SECT_LIMIT; n++) {
      // print each section
      CodeSection* cs = code_section(n);
!     cs->print(code_section_name(n));
    }
  }
  
- // ----- CHeapString -----------------------------------------------------------
- 
- class CHeapString : public CHeapObj<mtCode> {
-  public:
-   CHeapString(const char* str) : _string(os::strdup(str)) {}
-  ~CHeapString() {
-     os::free((void*)_string);
-     _string = nullptr;
-   }
-   const char* string() const { return _string; }
- 
-  private:
-   const char* _string;
- };
- 
- // ----- AsmRemarkCollection ---------------------------------------------------
- 
- class AsmRemarkCollection : public CHeapObj<mtCode> {
-  public:
-   AsmRemarkCollection() : _ref_cnt(1), _remarks(nullptr), _next(nullptr) {}
-  ~AsmRemarkCollection() {
-     assert(is_empty(), "Must 'clear()' before deleting!");
-     assert(_ref_cnt == 0, "No uses must remain when deleting!");
-   }
-   AsmRemarkCollection* reuse() {
-     precond(_ref_cnt > 0);
-     return _ref_cnt++, this;
-   }
- 
-   const char* insert(uint offset, const char* remark);
-   const char* lookup(uint offset) const;
-   const char* next(uint offset) const;
- 
-   bool is_empty() const { return _remarks == nullptr; }
-   uint clear();
- 
-  private:
-   struct Cell : CHeapString {
-     Cell(const char* remark, uint offset) :
-         CHeapString(remark), offset(offset), prev(nullptr), next(nullptr) {}
-     void push_back(Cell* cell) {
-       Cell* head = this;
-       Cell* tail = prev;
-       tail->next = cell;
-       cell->next = head;
-       cell->prev = tail;
-       prev = cell;
-     }
-     uint offset;
-     Cell* prev;
-     Cell* next;
-   };
-   uint  _ref_cnt;
-   Cell* _remarks;
-   // Using a 'mutable' iteration pointer to allow 'const' on lookup/next (that
-   // does not change the state of the list per se), supportig a simplistic
-   // iteration scheme.
-   mutable Cell* _next;
- };
- 
- // ----- DbgStringCollection ---------------------------------------------------
- 
- class DbgStringCollection : public CHeapObj<mtCode> {
-  public:
-   DbgStringCollection() : _ref_cnt(1), _strings(nullptr) {}
-  ~DbgStringCollection() {
-     assert(is_empty(), "Must 'clear()' before deleting!");
-     assert(_ref_cnt == 0, "No uses must remain when deleting!");
-   }
-   DbgStringCollection* reuse() {
-     precond(_ref_cnt > 0);
-     return _ref_cnt++, this;
-   }
- 
-   const char* insert(const char* str);
-   const char* lookup(const char* str) const;
- 
-   bool is_empty() const { return _strings == nullptr; }
-   uint clear();
- 
-  private:
-   struct Cell : CHeapString {
-     Cell(const char* dbgstr) :
-         CHeapString(dbgstr), prev(nullptr), next(nullptr) {}
-     void push_back(Cell* cell) {
-       Cell* head = this;
-       Cell* tail = prev;
-       tail->next = cell;
-       cell->next = head;
-       cell->prev = tail;
-       prev = cell;
-     }
-     Cell* prev;
-     Cell* next;
-   };
-   uint  _ref_cnt;
-   Cell* _strings;
- };
- 
  // ----- AsmRemarks ------------------------------------------------------------
  //
  // Acting as interface to reference counted mapping [offset -> remark], where
  // offset is a byte offset into an instruction stream (CodeBuffer, CodeBlob or
  // other memory buffer) and remark is a string (comment).
--- 1065,38 ---
    ttyLocker ttyl;
    Disassembler::decode(decode_begin(), insts_end(), tty NOT_PRODUCT(COMMA &asm_remarks()));
    _decode_begin = insts_end();
  }
  
! void CodeSection::print_on(outputStream* st, const char* name) {
    csize_t locs_size = locs_end() - locs_start();
!   st->print_cr(" %7s.code = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d)",
!                name, p2i(start()), p2i(end()), p2i(limit()), size(), capacity());
!   st->print_cr(" %7s.locs = " PTR_FORMAT " : " PTR_FORMAT " : " PTR_FORMAT " (%d of %d) point=%d",
!                name, p2i(locs_start()), p2i(locs_end()), p2i(locs_limit()), locs_size, locs_capacity(), locs_point_off());
    if (PrintRelocations && (locs_size != 0)) {
      RelocIterator iter(this);
!     iter.print_on(st);
    }
  }
  
! void CodeBuffer::print_on(outputStream* st) {
! #if 0
+   if (this == nullptr) { // gcc complains 'nonnull' argument 'this' compared to nullptr
+     st->print_cr("null CodeBuffer pointer");
+     return;
+   }
+ #endif
+ 
+   st->print_cr("CodeBuffer:%s", name());
    for (int n = 0; n < (int)SECT_LIMIT; n++) {
      // print each section
      CodeSection* cs = code_section(n);
!     cs->print_on(st, code_section_name(n));
    }
  }
  
  // ----- AsmRemarks ------------------------------------------------------------
  //
  // Acting as interface to reference counted mapping [offset -> remark], where
  // offset is a byte offset into an instruction stream (CodeBuffer, CodeBlob or
  // other memory buffer) and remark is a string (comment).

*** 1189,13 ***
--- 1104,20 ---
  AsmRemarks::AsmRemarks() : _remarks(new AsmRemarkCollection()) {
    assert(_remarks != nullptr, "Allocation failure!");
  }
  
  AsmRemarks::~AsmRemarks() {
+   if (_remarks != nullptr) {
+     clear();
+   }
    assert(_remarks == nullptr, "Must 'clear()' before deleting!");
  }
  
+ void AsmRemarks::init(AsmRemarks& asm_remarks) {
+   asm_remarks._remarks = new AsmRemarkCollection();
+ }
+ 
  const char* AsmRemarks::insert(uint offset, const char* remstr) {
    precond(remstr != nullptr);
    return _remarks->insert(offset, remstr);
  }
  

*** 1208,10 ***
--- 1130,11 ---
    clear();
    _remarks = src._remarks->reuse();
  }
  
  void AsmRemarks::clear() {
+   assert(_remarks != nullptr, "sanity check");
    if (_remarks->clear() == 0) {
      delete _remarks;
    }
    _remarks = nullptr;
  }

*** 1241,13 ***
--- 1164,20 ---
  DbgStrings::DbgStrings() : _strings(new DbgStringCollection()) {
    assert(_strings != nullptr, "Allocation failure!");
  }
  
  DbgStrings::~DbgStrings() {
+   if (_strings != nullptr) {
+     clear();
+   }
    assert(_strings == nullptr, "Must 'clear()' before deleting!");
  }
  
+ void DbgStrings::init(DbgStrings& dbg_strings) {
+   dbg_strings._strings = new DbgStringCollection();
+ }
+ 
  const char* DbgStrings::insert(const char* dbgstr) {
    const char* str = _strings->lookup(dbgstr);
    return str != nullptr ? str : _strings->insert(dbgstr);
  }
  

*** 1260,10 ***
--- 1190,11 ---
    clear();
    _strings = src._strings->reuse();
  }
  
  void DbgStrings::clear() {
+   assert(_strings != nullptr, "sanity check");
    if (_strings->clear() == 0) {
      delete _strings;
    }
    _strings = nullptr;
  }
< prev index next >