8266787: Potential overflow of pointer arithmetic in G1ArchiveAllocator
Reviewed-by: kbarrett, tschatzl
This commit is contained in:
parent
8468001f88
commit
6575566d83
@ -452,26 +452,29 @@ HeapWord* G1ArchiveAllocator::archive_mem_allocate(size_t word_size) {
|
||||
PTR_FORMAT " <= " PTR_FORMAT " <= " PTR_FORMAT,
|
||||
p2i(_bottom), p2i(old_top), p2i(_max));
|
||||
|
||||
// Allocate the next word_size words in the current allocation chunk.
|
||||
// If allocation would cross the _max boundary, insert a filler and begin
|
||||
// at the base of the next min_region_size'd chunk. Also advance to the next
|
||||
// chunk if we don't yet cross the boundary, but the remainder would be too
|
||||
// small to fill.
|
||||
HeapWord* new_top = old_top + word_size;
|
||||
size_t remainder = pointer_delta(_max, new_top);
|
||||
if ((new_top > _max) ||
|
||||
((new_top < _max) && (remainder < CollectedHeap::min_fill_size()))) {
|
||||
// Try to allocate word_size in the current allocation chunk. Two cases
|
||||
// require special treatment:
|
||||
// 1. no enough space for word_size
|
||||
// 2. after allocating word_size, there's non-zero space left, but too small for the minimal filler
|
||||
// In both cases, we retire the current chunk and move on to the next one.
|
||||
size_t free_words = pointer_delta(_max, old_top);
|
||||
if (free_words < word_size ||
|
||||
((free_words - word_size != 0) && (free_words - word_size < CollectedHeap::min_fill_size()))) {
|
||||
// Retiring the current chunk
|
||||
if (old_top != _max) {
|
||||
size_t fill_size = pointer_delta(_max, old_top);
|
||||
// Non-zero space; need to insert the filler
|
||||
size_t fill_size = free_words;
|
||||
CollectedHeap::fill_with_object(old_top, fill_size);
|
||||
_summary_bytes_used += fill_size * HeapWordSize;
|
||||
}
|
||||
// Set the current chunk as "full"
|
||||
_allocation_region->set_top(_max);
|
||||
old_top = _bottom = _max;
|
||||
|
||||
// Check if we've just used up the last min_region_size'd chunk
|
||||
// in the current region, and if so, allocate a new one.
|
||||
if (_bottom != _allocation_region->end()) {
|
||||
if (_max != _allocation_region->end()) {
|
||||
// Shift to the next chunk
|
||||
old_top = _bottom = _max;
|
||||
_max = _bottom + HeapRegion::min_region_size_in_words();
|
||||
} else {
|
||||
if (!alloc_new_region()) {
|
||||
@ -480,6 +483,7 @@ HeapWord* G1ArchiveAllocator::archive_mem_allocate(size_t word_size) {
|
||||
old_top = _allocation_region->bottom();
|
||||
}
|
||||
}
|
||||
assert(pointer_delta(_max, old_top) >= word_size, "enough space left");
|
||||
_allocation_region->set_top(old_top + word_size);
|
||||
_summary_bytes_used += word_size * HeapWordSize;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user