src/hotspot/share/memory/heap.hpp
changeset 59145 ea044aedc2b6
parent 54943 6cbb5c2255e3
--- a/src/hotspot/share/memory/heap.hpp	Wed Nov 20 16:37:42 2019 +0900
+++ b/src/hotspot/share/memory/heap.hpp	Wed Nov 20 09:12:07 2019 +0100
@@ -92,6 +92,7 @@
   size_t       _next_segment;
 
   FreeBlock*   _freelist;
+  FreeBlock*   _last_insert_point;               // last insert point in add_to_freelist
   size_t       _freelist_segments;               // No. of segments in freelist
   int          _freelist_length;
   size_t       _max_allocated_capacity;          // Peak capacity that was allocated during lifetime of the heap
@@ -102,9 +103,12 @@
   int          _nmethod_count;                   // Number of nmethods
   int          _adapter_count;                   // Number of adapters
   int          _full_count;                      // Number of times the code heap was full
-
+  int          _fragmentation_count;             // #FreeBlock joins without fully initializing segment map elements.
 
   enum { free_sentinel = 0xFF };
+  static const int fragmentation_limit = 10000;  // defragment after that many potential fragmentations.
+  static const int freelist_limit = 100;         // improve insert point search if list is longer than this limit.
+  static char  segmap_template[free_sentinel+1];
 
   // Helper functions
   size_t   size_to_segments(size_t size) const { return (size + _segment_size - 1) >> _log2_segment_size; }
@@ -112,14 +116,17 @@
 
   size_t   segment_for(void* p) const            { return ((char*)p - _memory.low()) >> _log2_segment_size; }
   bool     is_segment_unused(int val) const      { return val == free_sentinel; }
-  HeapBlock* block_at(size_t i) const            { return (HeapBlock*)(_memory.low() + (i << _log2_segment_size)); }
+  void*    address_for(size_t i) const           { return (void*)(_memory.low() + segments_to_size(i)); }
+  void*    find_block_for(void* p) const;
+  HeapBlock* block_at(size_t i) const            { return (HeapBlock*)address_for(i); }
 
   // These methods take segment map indices as range boundaries
   void mark_segmap_as_free(size_t beg, size_t end);
-  void mark_segmap_as_used(size_t beg, size_t end);
+  void mark_segmap_as_used(size_t beg, size_t end, bool is_FreeBlock_join);
   void invalidate(size_t beg, size_t end, size_t header_bytes);
   void clear(size_t beg, size_t end);
   void clear();                                 // clears all heap contents
+  static void init_segmap_template();
 
   // Freelist management helpers
   FreeBlock* following_block(FreeBlock* b);
@@ -154,12 +161,15 @@
   //            beforehand and we also can't easily relocate the interpreter to a new location.
   void  deallocate_tail(void* p, size_t used_size);
 
-  // Attributes
+  // Boundaries of committed space.
+  char* low()  const                             { return _memory.low(); }
+  char* high() const                             { return _memory.high(); }
+  // Boundaries of reserved space.
   char* low_boundary() const                     { return _memory.low_boundary(); }
-  char* high() const                             { return _memory.high(); }
   char* high_boundary() const                    { return _memory.high_boundary(); }
 
-  bool contains(const void* p) const             { return low_boundary() <= p && p < high(); }
+  // Containment means "contained in committed space".
+  bool contains(const void* p) const             { return low() <= p && p < high(); }
   bool contains_blob(const CodeBlob* blob) const {
     // AOT CodeBlobs (i.e. AOTCompiledMethod) objects aren't allocated in the AOTCodeHeap but on the C-Heap.
     // Only the code they are pointing to is located in the AOTCodeHeap. All other CodeBlobs are allocated
@@ -219,6 +229,8 @@
 
 private:
   size_t heap_unallocated_capacity() const;
+  int defrag_segmap(bool do_defrag);
+  int segmap_hops(size_t beg, size_t end);
 
 public:
   // Debugging