34
35 class HeapBlock {
36 friend class VMStructs;
37
38 public:
39 struct Header {
40 size_t _length; // the length in segments
41 bool _used; // Used bit
42 };
43
44 protected:
45 union {
46 Header _header;
47 int64_t _padding[ (sizeof(Header) + sizeof(int64_t)-1) / sizeof(int64_t) ];
48 // pad to 0 mod 8
49 };
50
51 public:
52 // Initialization
53 void initialize(size_t length) { _header._length = length; set_used(); }
54
55 // Accessors
56 void* allocated_space() const { return (void*)(this + 1); }
57 size_t length() const { return _header._length; }
58
59 // Used/free
60 void set_used() { _header._used = true; }
61 void set_free() { _header._used = false; }
62 bool free() { return !_header._used; }
63 };
64
65 class FreeBlock: public HeapBlock {
66 friend class VMStructs;
67 protected:
68 FreeBlock* _link;
69
70 public:
71 // Initialization
72 void initialize(size_t length) { HeapBlock::initialize(length); _link= NULL; }
73
74 // Merging
75 void set_length(size_t l) { _header._length = l; }
76
77 // Accessors
78 FreeBlock* link() const { return _link; }
79 void set_link(FreeBlock* link) { _link = link; }
80 };
81
82 class CodeHeap : public CHeapObj<mtCode> {
83 friend class VMStructs;
84 protected:
85 VirtualSpace _memory; // the memory holding the blocks
86 VirtualSpace _segmap; // the memory holding the segment map
87
88 size_t _number_of_committed_segments;
89 size_t _number_of_reserved_segments;
90 size_t _segment_size;
91 int _log2_segment_size;
92
93 size_t _next_segment;
94
95 FreeBlock* _freelist;
96 size_t _freelist_segments; // No. of segments in freelist
108 enum { free_sentinel = 0xFF };
109
110 // Helper functions
111 size_t size_to_segments(size_t size) const { return (size + _segment_size - 1) >> _log2_segment_size; }
112 size_t segments_to_size(size_t number_of_segments) const { return number_of_segments << _log2_segment_size; }
113
114 size_t segment_for(void* p) const { return ((char*)p - _memory.low()) >> _log2_segment_size; }
115 bool is_segment_unused(int val) const { return val == free_sentinel; }
116 HeapBlock* block_at(size_t i) const { return (HeapBlock*)(_memory.low() + (i << _log2_segment_size)); }
117
118 void mark_segmap_as_free(size_t beg, size_t end);
119 void mark_segmap_as_used(size_t beg, size_t end);
120
121 // Freelist management helpers
122 FreeBlock* following_block(FreeBlock* b);
123 void insert_after(FreeBlock* a, FreeBlock* b);
124 bool merge_right (FreeBlock* a);
125
126 // Toplevel freelist management
127 void add_to_freelist(HeapBlock* b);
128 FreeBlock* search_freelist(size_t length);
129
130 // Iteration helpers
131 void* next_used(HeapBlock* b) const;
132 HeapBlock* block_start(void* p) const;
133
134 // to perform additional actions on creation of executable code
135 void on_code_mapping(char* base, size_t size);
136 void clear(); // clears all heap contents
137
138 public:
139 CodeHeap(const char* name, const int code_blob_type);
140
141 // Heap extents
142 bool reserve(ReservedSpace rs, size_t committed_size, size_t segment_size);
143 bool expand_by(size_t size); // expands committed memory by size
144
145 // Memory allocation
146 void* allocate (size_t size); // Allocate 'size' bytes in the code cache or return NULL
147 void deallocate(void* p); // Deallocate memory
148 // Free the tail of segments allocated by the last call to 'allocate()' which exceed 'used_size'.
163 // Only the code they are pointing to is located in the AOTCodeHeap. All other CodeBlobs are allocated
164 // directly in their corresponding CodeHeap with their code appended to the actual C++ object.
165 // So all CodeBlobs except AOTCompiledMethod are continuous in memory with their data and code while
166 // AOTCompiledMethod and their code/data is distributed in the C-Heap. This means we can use the
167 // address of a CodeBlob object in order to locate it in its heap while we have to use the address
168 // of the actual code an AOTCompiledMethod object is pointing to in order to locate it.
169 // Notice that for an ordinary CodeBlob with code size zero, code_begin() may point beyond the object!
170 const void* start = AOT_ONLY( (code_blob_type() == CodeBlobType::AOT) ? blob->code_begin() : ) (void*)blob;
171 return contains(start);
172 }
173
174 virtual void* find_start(void* p) const; // returns the block containing p or NULL
175 virtual CodeBlob* find_blob_unsafe(void* start) const;
176 size_t alignment_unit() const; // alignment of any block
177 size_t alignment_offset() const; // offset of first byte of any block, within the enclosing alignment unit
178 static size_t header_size(); // returns the header size for each heap block
179
180 size_t segment_size() const { return _segment_size; } // for CodeHeapState
181 HeapBlock* first_block() const; // for CodeHeapState
182 HeapBlock* next_block(HeapBlock* b) const; // for CodeHeapState
183
184 FreeBlock* freelist() const { return _freelist; } // for CodeHeapState
185
186 size_t allocated_in_freelist() const { return _freelist_segments * CodeCacheSegmentSize; }
187 int freelist_length() const { return _freelist_length; } // number of elements in the freelist
188
189 // returns the first block or NULL
190 virtual void* first() const { return next_used(first_block()); }
191 // returns the next block given a block p or NULL
192 virtual void* next(void* p) const { return next_used(next_block(block_start(p))); }
193
194 // Statistics
195 size_t capacity() const;
196 size_t max_capacity() const;
197 int allocated_segments() const;
198 size_t allocated_capacity() const;
199 size_t max_allocated_capacity() const { return _max_allocated_capacity; }
200 size_t unallocated_capacity() const { return max_capacity() - allocated_capacity(); }
201
202 // Returns true if the CodeHeap contains CodeBlobs of the given type
|
34
35 class HeapBlock {
36 friend class VMStructs;
37
38 public:
39 struct Header {
40 size_t _length; // the length in segments
41 bool _used; // Used bit
42 };
43
44 protected:
45 union {
46 Header _header;
47 int64_t _padding[ (sizeof(Header) + sizeof(int64_t)-1) / sizeof(int64_t) ];
48 // pad to 0 mod 8
49 };
50
51 public:
52 // Initialization
53 void initialize(size_t length) { _header._length = length; set_used(); }
54 // Merging/splitting
55 void set_length(size_t length) { _header._length = length; }
56
57 // Accessors
58 void* allocated_space() const { return (void*)(this + 1); }
59 size_t length() const { return _header._length; }
60
61 // Used/free
62 void set_used() { _header._used = true; }
63 void set_free() { _header._used = false; }
64 bool free() { return !_header._used; }
65 };
66
67 class FreeBlock: public HeapBlock {
68 friend class VMStructs;
69 protected:
70 FreeBlock* _link;
71
72 public:
73 // Initialization
74 void initialize(size_t length) { HeapBlock::initialize(length); _link= NULL; }
75
76 // Accessors
77 FreeBlock* link() const { return _link; }
78 void set_link(FreeBlock* link) { _link = link; }
79 };
80
81 class CodeHeap : public CHeapObj<mtCode> {
82 friend class VMStructs;
83 protected:
84 VirtualSpace _memory; // the memory holding the blocks
85 VirtualSpace _segmap; // the memory holding the segment map
86
87 size_t _number_of_committed_segments;
88 size_t _number_of_reserved_segments;
89 size_t _segment_size;
90 int _log2_segment_size;
91
92 size_t _next_segment;
93
94 FreeBlock* _freelist;
95 size_t _freelist_segments; // No. of segments in freelist
107 enum { free_sentinel = 0xFF };
108
109 // Helper functions
110 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; }
112
113 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; }
115 HeapBlock* block_at(size_t i) const { return (HeapBlock*)(_memory.low() + (i << _log2_segment_size)); }
116
117 void mark_segmap_as_free(size_t beg, size_t end);
118 void mark_segmap_as_used(size_t beg, size_t end);
119
120 // Freelist management helpers
121 FreeBlock* following_block(FreeBlock* b);
122 void insert_after(FreeBlock* a, FreeBlock* b);
123 bool merge_right (FreeBlock* a);
124
125 // Toplevel freelist management
126 void add_to_freelist(HeapBlock* b);
127 HeapBlock* search_freelist(size_t length);
128
129 // Iteration helpers
130 void* next_used(HeapBlock* b) const;
131 HeapBlock* block_start(void* p) const;
132
133 // to perform additional actions on creation of executable code
134 void on_code_mapping(char* base, size_t size);
135 void clear(); // clears all heap contents
136
137 public:
138 CodeHeap(const char* name, const int code_blob_type);
139
140 // Heap extents
141 bool reserve(ReservedSpace rs, size_t committed_size, size_t segment_size);
142 bool expand_by(size_t size); // expands committed memory by size
143
144 // Memory allocation
145 void* allocate (size_t size); // Allocate 'size' bytes in the code cache or return NULL
146 void deallocate(void* p); // Deallocate memory
147 // Free the tail of segments allocated by the last call to 'allocate()' which exceed 'used_size'.
162 // Only the code they are pointing to is located in the AOTCodeHeap. All other CodeBlobs are allocated
163 // directly in their corresponding CodeHeap with their code appended to the actual C++ object.
164 // So all CodeBlobs except AOTCompiledMethod are continuous in memory with their data and code while
165 // AOTCompiledMethod and their code/data is distributed in the C-Heap. This means we can use the
166 // address of a CodeBlob object in order to locate it in its heap while we have to use the address
167 // of the actual code an AOTCompiledMethod object is pointing to in order to locate it.
168 // Notice that for an ordinary CodeBlob with code size zero, code_begin() may point beyond the object!
169 const void* start = AOT_ONLY( (code_blob_type() == CodeBlobType::AOT) ? blob->code_begin() : ) (void*)blob;
170 return contains(start);
171 }
172
173 virtual void* find_start(void* p) const; // returns the block containing p or NULL
174 virtual CodeBlob* find_blob_unsafe(void* start) const;
175 size_t alignment_unit() const; // alignment of any block
176 size_t alignment_offset() const; // offset of first byte of any block, within the enclosing alignment unit
177 static size_t header_size(); // returns the header size for each heap block
178
179 size_t segment_size() const { return _segment_size; } // for CodeHeapState
180 HeapBlock* first_block() const; // for CodeHeapState
181 HeapBlock* next_block(HeapBlock* b) const; // for CodeHeapState
182 HeapBlock* split_block(HeapBlock* b, size_t split_seg); // split one block into two
183
184 FreeBlock* freelist() const { return _freelist; } // for CodeHeapState
185
186 size_t allocated_in_freelist() const { return _freelist_segments * CodeCacheSegmentSize; }
187 int freelist_length() const { return _freelist_length; } // number of elements in the freelist
188
189 // returns the first block or NULL
190 virtual void* first() const { return next_used(first_block()); }
191 // returns the next block given a block p or NULL
192 virtual void* next(void* p) const { return next_used(next_block(block_start(p))); }
193
194 // Statistics
195 size_t capacity() const;
196 size_t max_capacity() const;
197 int allocated_segments() const;
198 size_t allocated_capacity() const;
199 size_t max_allocated_capacity() const { return _max_allocated_capacity; }
200 size_t unallocated_capacity() const { return max_capacity() - allocated_capacity(); }
201
202 // Returns true if the CodeHeap contains CodeBlobs of the given type
|