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