/*
堆中内存块空闲标记
@beg 起始地址
@end 结束地址
*/
void CodeHeap::mark_segmap_as_free(size_t beg, size_t end) {
assert(0 <= beg && beg < _number_of_committed_segments, "interval begin out of bounds");
assert(beg < end && end <= _number_of_committed_segments, "interval end out of bounds");
// 使用内存段@_segmap 指针,用于快速索引
address p = (address)_segmap.low() + beg;
address q = (address)_segmap.low() + end;
// 初始化间隔,低位(起始地址)每次向上移动0xFF个空间大小
while (p < q) *p++ = 0xFF;
}
占用标记
**
* 将指定的堆内存标记为使用
* @beg 内存块起始地址
* @end 内存块结束地址
*/
void CodeHeap::mark_segmap_as_used(size_t beg, size_t end) {
assert(0 <= beg && beg < _number_of_committed_segments, "interval begin out of bounds");
assert(beg < end && end <= _number_of_committed_segments, "interval end out of bounds");
address p = (address)_segmap.low() + beg;
address q = (address)_segmap.low() + end;
int i = 0;
while (p < q) {
*p++ = i++;
// 块状标记
if (i == 0xFF) i = 1;
}
}
内存分配
void* CodeHeap::allocate(size_t instance_size, bool is_critical) {
size_t number_of_segments = size_to_segments(instance_size + sizeof(HeapBlock));
assert(segments_to_size(number_of_segments) >= sizeof(FreeBlock), "not enough room for FreeList");
// First check if we can satify request from freelist
debug_only(verify());
HeapBlock* block = search_freelist(number_of_segments, is_critical);
debug_only(if (VerifyCodeCacheOften) verify());
if (block != NULL) {
assert(block->length() >= number_of_segments && block->length() < number_of_segments + CodeCacheMinBlockLength, "sanity check");
assert(!block->free(), "must be marked free");
#ifdef ASSERT
memset((void *)block->allocated_space(), badCodeHeapNewVal, instance_size);
#endif
return block->allocated_space();
}
// Ensure minimum size for allocation to the heap.
if (number_of_segments < CodeCacheMinBlockLength) {
number_of_segments = CodeCacheMinBlockLength;
}
if (!is_critical) {
// Make sure the allocation fits in the unallocated heap without using
// the CodeCacheMimimumFreeSpace that is reserved for critical allocations.
if (segments_to_size(number_of_segments) > (heap_unallocated_capacity() - CodeCacheMinimumFreeSpace)) {
// Fail allocation
return NULL;
}
}
if (_next_segment + number_of_segments <= _number_of_committed_segments) {
mark_segmap_as_used(_next_segment, _next_segment + number_of_segments);
HeapBlock* b = block_at(_next_segment);
b->initialize(number_of_segments);
_next_segment += number_of_segments;
#ifdef ASSERT
memset((void *)b->allocated_space(), badCodeHeapNewVal, instance_size);
#endif
return b->allocated_space();
} else {
return NULL;
}
}