169 _next_segment = 0; |
169 _next_segment = 0; |
170 mark_segmap_as_free(0, _number_of_committed_segments); |
170 mark_segmap_as_free(0, _number_of_committed_segments); |
171 } |
171 } |
172 |
172 |
173 |
173 |
174 void* CodeHeap::allocate(size_t instance_size, bool is_critical) { |
174 void* CodeHeap::allocate(size_t instance_size) { |
175 size_t number_of_segments = size_to_segments(instance_size + header_size()); |
175 size_t number_of_segments = size_to_segments(instance_size + header_size()); |
176 assert(segments_to_size(number_of_segments) >= sizeof(FreeBlock), "not enough room for FreeList"); |
176 assert(segments_to_size(number_of_segments) >= sizeof(FreeBlock), "not enough room for FreeList"); |
177 |
177 |
178 // First check if we can satisfy request from freelist |
178 // First check if we can satisfy request from freelist |
179 NOT_PRODUCT(verify()); |
179 NOT_PRODUCT(verify()); |
180 HeapBlock* block = search_freelist(number_of_segments, is_critical); |
180 HeapBlock* block = search_freelist(number_of_segments); |
181 NOT_PRODUCT(verify()); |
181 NOT_PRODUCT(verify()); |
182 |
182 |
183 if (block != NULL) { |
183 if (block != NULL) { |
184 assert(block->length() >= number_of_segments && block->length() < number_of_segments + CodeCacheMinBlockLength, "sanity check"); |
184 assert(block->length() >= number_of_segments && block->length() < number_of_segments + CodeCacheMinBlockLength, "sanity check"); |
185 assert(!block->free(), "must be marked free"); |
185 assert(!block->free(), "must be marked free"); |
188 return block->allocated_space(); |
188 return block->allocated_space(); |
189 } |
189 } |
190 |
190 |
191 // Ensure minimum size for allocation to the heap. |
191 // Ensure minimum size for allocation to the heap. |
192 number_of_segments = MAX2((int)CodeCacheMinBlockLength, (int)number_of_segments); |
192 number_of_segments = MAX2((int)CodeCacheMinBlockLength, (int)number_of_segments); |
193 |
|
194 if (!is_critical) { |
|
195 // Make sure the allocation fits in the unallocated heap without using |
|
196 // the CodeCacheMimimumFreeSpace that is reserved for critical allocations. |
|
197 if (segments_to_size(number_of_segments) > (heap_unallocated_capacity() - CodeCacheMinimumFreeSpace)) { |
|
198 // Fail allocation |
|
199 return NULL; |
|
200 } |
|
201 } |
|
202 |
193 |
203 if (_next_segment + number_of_segments <= _number_of_committed_segments) { |
194 if (_next_segment + number_of_segments <= _number_of_committed_segments) { |
204 mark_segmap_as_used(_next_segment, _next_segment + number_of_segments); |
195 mark_segmap_as_used(_next_segment, _next_segment + number_of_segments); |
205 HeapBlock* b = block_at(_next_segment); |
196 HeapBlock* b = block_at(_next_segment); |
206 b->initialize(number_of_segments); |
197 b->initialize(number_of_segments); |
425 |
416 |
426 /** |
417 /** |
427 * Search freelist for an entry on the list with the best fit. |
418 * Search freelist for an entry on the list with the best fit. |
428 * @return NULL, if no one was found |
419 * @return NULL, if no one was found |
429 */ |
420 */ |
430 FreeBlock* CodeHeap::search_freelist(size_t length, bool is_critical) { |
421 FreeBlock* CodeHeap::search_freelist(size_t length) { |
431 FreeBlock* found_block = NULL; |
422 FreeBlock* found_block = NULL; |
432 FreeBlock* found_prev = NULL; |
423 FreeBlock* found_prev = NULL; |
433 size_t found_length = 0; |
424 size_t found_length = 0; |
434 |
425 |
435 FreeBlock* prev = NULL; |
426 FreeBlock* prev = NULL; |
436 FreeBlock* cur = _freelist; |
427 FreeBlock* cur = _freelist; |
437 const size_t critical_boundary = (size_t)high_boundary() - CodeCacheMinimumFreeSpace; |
|
438 |
428 |
439 // Search for first block that fits |
429 // Search for first block that fits |
440 while(cur != NULL) { |
430 while(cur != NULL) { |
441 if (cur->length() >= length) { |
431 if (cur->length() >= length) { |
442 // Non critical allocations are not allowed to use the last part of the code heap. |
|
443 // Make sure the end of the allocation doesn't cross into the last part of the code heap. |
|
444 if (!is_critical && (((size_t)cur + length) > critical_boundary)) { |
|
445 // The freelist is sorted by address - if one fails, all consecutive will also fail. |
|
446 break; |
|
447 } |
|
448 // Remember block, its previous element, and its length |
432 // Remember block, its previous element, and its length |
449 found_block = cur; |
433 found_block = cur; |
450 found_prev = prev; |
434 found_prev = prev; |
451 found_length = found_block->length(); |
435 found_length = found_block->length(); |
452 |
436 |