< prev index next >

src/hotspot/share/asm/codeBuffer.hpp

Print this page
*** 26,10 ***
--- 26,11 ---
  #define SHARE_ASM_CODEBUFFER_HPP
  
  #include "code/oopRecorder.hpp"
  #include "code/relocInfo.hpp"
  #include "compiler/compiler_globals.hpp"
+ #include "runtime/os.hpp"
  #include "utilities/align.hpp"
  #include "utilities/debug.hpp"
  #include "utilities/growableArray.hpp"
  #include "utilities/linkedlist.hpp"
  #include "utilities/resizeableResourceHash.hpp"

*** 87,10 ***
--- 88,11 ---
  // This class represents a stream of code and associated relocations.
  // There are a few in each CodeBuffer.
  // They are filled concurrently, and concatenated at the end.
  class CodeSection {
    friend class CodeBuffer;
+   friend class SCCReader;
   public:
    typedef int csize_t;  // code size type; would be size_t except for history
  
   private:
    address     _start;           // first byte of contents (instructions)

*** 281,19 ***
    // Return true if there was an expansion.
    bool maybe_expand_to_ensure_remaining(csize_t amount);
  
  #ifndef PRODUCT
    void decode();
!   void print(const char* name);
  #endif //PRODUCT
  };
  
  
  #ifndef PRODUCT
  
! class AsmRemarkCollection;
! class DbgStringCollection;
  
  // The assumption made here is that most code remarks (or comments) added to
  // the generated assembly code are unique, i.e. there is very little gain in
  // trying to share the strings between the different offsets tracked in a
  // buffer (or blob).
--- 283,86 ---
    // Return true if there was an expansion.
    bool maybe_expand_to_ensure_remaining(csize_t amount);
  
  #ifndef PRODUCT
    void decode();
!   void print_on(outputStream* st, const char* name);
  #endif //PRODUCT
  };
  
  
  #ifndef PRODUCT
  
! 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;
+ };
+ 
+ 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();
+ 
+   template<typename Function>
+   bool iterate(Function function) const { // lambda enabled API
+     if (_remarks != nullptr) {
+       Cell* tmp = _remarks;
+       do {
+         if(!function(tmp->offset, tmp->string())) {
+           return false;
+         }
+         tmp = tmp->next;
+       } while (tmp != _remarks);
+     }
+     return true;
+   }
+ 
+  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;
+ };
  
  // The assumption made here is that most code remarks (or comments) added to
  // the generated assembly code are unique, i.e. there is very little gain in
  // trying to share the strings between the different offsets tracked in a
  // buffer (or blob).

*** 301,10 ***
--- 370,12 ---
  class AsmRemarks {
   public:
    AsmRemarks();
   ~AsmRemarks();
  
+   static void init(AsmRemarks& asm_remarks);
+ 
    const char* insert(uint offset, const char* remstr);
  
    bool is_empty() const;
  
    void share(const AsmRemarks &src);

*** 312,32 ***
--- 383,91 ---
    uint print(uint offset, outputStream* strm = tty) const;
  
    // For testing purposes only.
    const AsmRemarkCollection* ref() const { return _remarks; }
  
+   template<typename Function>
+   bool iterate(Function function) const { return _remarks->iterate(function); }
+ 
  private:
    AsmRemarkCollection* _remarks;
  };
  
+ 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();
+ 
+   template<typename Function>
+   bool iterate(Function function) const { // lambda enabled API
+     if (_strings != nullptr) {
+       Cell* tmp = _strings;
+       do {
+         if (!function(tmp->string())) {
+           return false;
+         }
+         tmp = tmp->next;
+       } while (tmp != _strings);
+     }
+     return true;
+   }
+ 
+  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;
+ };
+ 
  // The assumption made here is that the number of debug strings (with a fixed
  // address requirement) is a rather small set per compilation unit.
  
  class DbgStrings {
   public:
    DbgStrings();
   ~DbgStrings();
  
+   static void init(DbgStrings& dbg_strings);
+ 
    const char* insert(const char* dbgstr);
  
    bool is_empty() const;
  
    void share(const DbgStrings &src);
    void clear();
  
    // For testing purposes only.
    const DbgStringCollection* ref() const { return _strings; }
  
+   template<typename Function>
+   bool iterate(Function function) const { return _strings->iterate(function); }
+ 
  private:
    DbgStringCollection* _strings;
  };
  #endif // not PRODUCT
  

*** 384,10 ***
--- 514,11 ---
  // addresses in a sibling section.
  
  class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) {
    friend class CodeSection;
    friend class StubCodeGenerator;
+   friend class SCCReader;
  
   private:
    // CodeBuffers must be allocated on the stack except for a single
    // special case during expansion which is handled internally.  This
    // is done to guarantee proper cleanup of resources.

*** 740,11 ***
  #ifndef PRODUCT
   public:
    // Printing / Decoding
    // decodes from decode_begin() to code_end() and sets decode_begin to end
    void    decode();
!   void    print();
  #endif
    // Directly disassemble code buffer.
    void    decode(address start, address end);
  
    // The following header contains architecture-specific implementations
--- 871,11 ---
  #ifndef PRODUCT
   public:
    // Printing / Decoding
    // decodes from decode_begin() to code_end() and sets decode_begin to end
    void    decode();
!   void    print_on(outputStream* st);
  #endif
    // Directly disassemble code buffer.
    void    decode(address start, address end);
  
    // The following header contains architecture-specific implementations
< prev index next >