90 int _log2_segment_size; |
90 int _log2_segment_size; |
91 |
91 |
92 size_t _next_segment; |
92 size_t _next_segment; |
93 |
93 |
94 FreeBlock* _freelist; |
94 FreeBlock* _freelist; |
|
95 FreeBlock* _last_insert_point; // last insert point in add_to_freelist |
95 size_t _freelist_segments; // No. of segments in freelist |
96 size_t _freelist_segments; // No. of segments in freelist |
96 int _freelist_length; |
97 int _freelist_length; |
97 size_t _max_allocated_capacity; // Peak capacity that was allocated during lifetime of the heap |
98 size_t _max_allocated_capacity; // Peak capacity that was allocated during lifetime of the heap |
98 |
99 |
99 const char* _name; // Name of the CodeHeap |
100 const char* _name; // Name of the CodeHeap |
100 const int _code_blob_type; // CodeBlobType it contains |
101 const int _code_blob_type; // CodeBlobType it contains |
101 int _blob_count; // Number of CodeBlobs |
102 int _blob_count; // Number of CodeBlobs |
102 int _nmethod_count; // Number of nmethods |
103 int _nmethod_count; // Number of nmethods |
103 int _adapter_count; // Number of adapters |
104 int _adapter_count; // Number of adapters |
104 int _full_count; // Number of times the code heap was full |
105 int _full_count; // Number of times the code heap was full |
105 |
106 int _fragmentation_count; // #FreeBlock joins without fully initializing segment map elements. |
106 |
107 |
107 enum { free_sentinel = 0xFF }; |
108 enum { free_sentinel = 0xFF }; |
|
109 static const int fragmentation_limit = 10000; // defragment after that many potential fragmentations. |
|
110 static const int freelist_limit = 100; // improve insert point search if list is longer than this limit. |
|
111 static char segmap_template[free_sentinel+1]; |
108 |
112 |
109 // Helper functions |
113 // Helper functions |
110 size_t size_to_segments(size_t size) const { return (size + _segment_size - 1) >> _log2_segment_size; } |
114 size_t size_to_segments(size_t size) const { return (size + _segment_size - 1) >> _log2_segment_size; } |
111 size_t segments_to_size(size_t number_of_segments) const { return number_of_segments << _log2_segment_size; } |
115 size_t segments_to_size(size_t number_of_segments) const { return number_of_segments << _log2_segment_size; } |
112 |
116 |
113 size_t segment_for(void* p) const { return ((char*)p - _memory.low()) >> _log2_segment_size; } |
117 size_t segment_for(void* p) const { return ((char*)p - _memory.low()) >> _log2_segment_size; } |
114 bool is_segment_unused(int val) const { return val == free_sentinel; } |
118 bool is_segment_unused(int val) const { return val == free_sentinel; } |
115 HeapBlock* block_at(size_t i) const { return (HeapBlock*)(_memory.low() + (i << _log2_segment_size)); } |
119 void* address_for(size_t i) const { return (void*)(_memory.low() + segments_to_size(i)); } |
|
120 void* find_block_for(void* p) const; |
|
121 HeapBlock* block_at(size_t i) const { return (HeapBlock*)address_for(i); } |
116 |
122 |
117 // These methods take segment map indices as range boundaries |
123 // These methods take segment map indices as range boundaries |
118 void mark_segmap_as_free(size_t beg, size_t end); |
124 void mark_segmap_as_free(size_t beg, size_t end); |
119 void mark_segmap_as_used(size_t beg, size_t end); |
125 void mark_segmap_as_used(size_t beg, size_t end, bool is_FreeBlock_join); |
120 void invalidate(size_t beg, size_t end, size_t header_bytes); |
126 void invalidate(size_t beg, size_t end, size_t header_bytes); |
121 void clear(size_t beg, size_t end); |
127 void clear(size_t beg, size_t end); |
122 void clear(); // clears all heap contents |
128 void clear(); // clears all heap contents |
|
129 static void init_segmap_template(); |
123 |
130 |
124 // Freelist management helpers |
131 // Freelist management helpers |
125 FreeBlock* following_block(FreeBlock* b); |
132 FreeBlock* following_block(FreeBlock* b); |
126 void insert_after(FreeBlock* a, FreeBlock* b); |
133 void insert_after(FreeBlock* a, FreeBlock* b); |
127 bool merge_right (FreeBlock* a); |
134 bool merge_right (FreeBlock* a); |
152 // 'p' was allocated. Only intended for freeing memory which would be otherwise |
159 // 'p' was allocated. Only intended for freeing memory which would be otherwise |
153 // wasted after the interpreter generation because we don't know the interpreter size |
160 // wasted after the interpreter generation because we don't know the interpreter size |
154 // beforehand and we also can't easily relocate the interpreter to a new location. |
161 // beforehand and we also can't easily relocate the interpreter to a new location. |
155 void deallocate_tail(void* p, size_t used_size); |
162 void deallocate_tail(void* p, size_t used_size); |
156 |
163 |
157 // Attributes |
164 // Boundaries of committed space. |
|
165 char* low() const { return _memory.low(); } |
|
166 char* high() const { return _memory.high(); } |
|
167 // Boundaries of reserved space. |
158 char* low_boundary() const { return _memory.low_boundary(); } |
168 char* low_boundary() const { return _memory.low_boundary(); } |
159 char* high() const { return _memory.high(); } |
|
160 char* high_boundary() const { return _memory.high_boundary(); } |
169 char* high_boundary() const { return _memory.high_boundary(); } |
161 |
170 |
162 bool contains(const void* p) const { return low_boundary() <= p && p < high(); } |
171 // Containment means "contained in committed space". |
|
172 bool contains(const void* p) const { return low() <= p && p < high(); } |
163 bool contains_blob(const CodeBlob* blob) const { |
173 bool contains_blob(const CodeBlob* blob) const { |
164 // AOT CodeBlobs (i.e. AOTCompiledMethod) objects aren't allocated in the AOTCodeHeap but on the C-Heap. |
174 // AOT CodeBlobs (i.e. AOTCompiledMethod) objects aren't allocated in the AOTCodeHeap but on the C-Heap. |
165 // Only the code they are pointing to is located in the AOTCodeHeap. All other CodeBlobs are allocated |
175 // Only the code they are pointing to is located in the AOTCodeHeap. All other CodeBlobs are allocated |
166 // directly in their corresponding CodeHeap with their code appended to the actual C++ object. |
176 // directly in their corresponding CodeHeap with their code appended to the actual C++ object. |
167 // So all CodeBlobs except AOTCompiledMethod are continuous in memory with their data and code while |
177 // So all CodeBlobs except AOTCompiledMethod are continuous in memory with their data and code while |