< prev index next >
src/share/vm/gc/g1/g1Allocator.cpp
Print this page
rev 8461 : imported patch webrev1.patch
rev 8462 : [mq]: version3
*** 44,54 ****
OldGCAllocRegion* old,
HeapRegion** retained_old) {
HeapRegion* retained_region = *retained_old;
*retained_old = NULL;
assert(retained_region == NULL || !retained_region->is_archive(),
! "Archive region should not be alloc region");
// We will discard the current GC alloc region if:
// a) it's in the collection set (it can happen!),
// b) it's already full (no point in using it),
// c) it's empty (this means that it was emptied during
--- 44,54 ----
OldGCAllocRegion* old,
HeapRegion** retained_old) {
HeapRegion* retained_region = *retained_old;
*retained_old = NULL;
assert(retained_region == NULL || !retained_region->is_archive(),
! err_msg("Archive region should not be alloc region (index %u)", retained_region->hrm_index()));
// We will discard the current GC alloc region if:
// a) it's in the collection set (it can happen!),
// b) it's already full (no point in using it),
// c) it's empty (this means that it was emptied during
*** 170,194 ****
undo_wasted += buf->undo_waste();
}
}
}
-
G1ArchiveAllocator* G1ArchiveAllocator::create_allocator(G1CollectedHeap* g1h) {
// Create the archive allocator, and also enable archive object checking
// in mark-sweep, since we will be creating archive regions.
G1ArchiveAllocator* result = new G1ArchiveAllocator(g1h);
G1MarkSweep::enable_archive_object_check();
return result;
}
! HeapRegion* G1ArchiveAllocator::alloc_new_region() {
! // Allocate the highest available region in the reserved heap,
// and add it to our list of allocated regions. It is marked
// archive and added to the old set.
! HeapRegion* hr = _g1h->alloc_highest_available_region();
! assert(hr->top() == hr->bottom(), "expected empty region");
hr->set_archive();
_g1h->_old_set.add(hr);
_g1h->_hr_printer.alloc(hr, G1HRPrinter::Archive);
_allocated_regions.append(hr);
_allocation_region = hr;
--- 170,196 ----
undo_wasted += buf->undo_waste();
}
}
}
G1ArchiveAllocator* G1ArchiveAllocator::create_allocator(G1CollectedHeap* g1h) {
// Create the archive allocator, and also enable archive object checking
// in mark-sweep, since we will be creating archive regions.
G1ArchiveAllocator* result = new G1ArchiveAllocator(g1h);
G1MarkSweep::enable_archive_object_check();
return result;
}
! bool G1ArchiveAllocator::alloc_new_region() {
! // Allocate the highest free region in the reserved heap,
// and add it to our list of allocated regions. It is marked
// archive and added to the old set.
! HeapRegion* hr = _g1h->alloc_highest_free_region();
! if (hr == NULL) {
! return false;
! }
! assert(hr->is_empty(), err_msg("expected empty region (index %u)", hr->hrm_index()));
hr->set_archive();
_g1h->_old_set.add(hr);
_g1h->_hr_printer.alloc(hr, G1HRPrinter::Archive);
_allocated_regions.append(hr);
_allocation_region = hr;
*** 197,216 ****
// min_region_size'd chunk of the allocated G1 region.
_bottom = hr->bottom();
_max = _bottom + HeapRegion::min_region_size_in_words();
// Tell mark-sweep that objects in this region are not to be marked.
! G1MarkSweep::mark_range_archive(_bottom, hr->end() - 1);
// Since we've modified the old set, call update_sizes.
_g1h->g1mm()->update_sizes();
! return hr;
}
HeapWord* G1ArchiveAllocator::archive_mem_allocate(size_t word_size) {
if (_allocation_region == NULL) {
! alloc_new_region();
}
HeapWord* old_top = _allocation_region->top();
assert(_bottom >= _allocation_region->bottom(),
err_msg("inconsistent allocation state: " PTR_FORMAT " < " PTR_FORMAT,
p2i(_bottom), p2i(_allocation_region->bottom())));
--- 199,221 ----
// min_region_size'd chunk of the allocated G1 region.
_bottom = hr->bottom();
_max = _bottom + HeapRegion::min_region_size_in_words();
// Tell mark-sweep that objects in this region are not to be marked.
! G1MarkSweep::mark_range_archive(MemRegion(_bottom, HeapRegion::GrainWords));
// Since we've modified the old set, call update_sizes.
_g1h->g1mm()->update_sizes();
! return true;
}
HeapWord* G1ArchiveAllocator::archive_mem_allocate(size_t word_size) {
+ assert(word_size != 0, "size must not be zero");
if (_allocation_region == NULL) {
! if (!alloc_new_region()) {
! return NULL;
! }
}
HeapWord* old_top = _allocation_region->top();
assert(_bottom >= _allocation_region->bottom(),
err_msg("inconsistent allocation state: " PTR_FORMAT " < " PTR_FORMAT,
p2i(_bottom), p2i(_allocation_region->bottom())));
*** 221,240 ****
err_msg("inconsistent allocation state: expected "
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 fill 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 = (size_t)(_max - new_top);
if ((new_top > _max) ||
((new_top < _max) && (remainder < CollectedHeap::min_fill_size()))) {
if (old_top != _max) {
! size_t fill_size = _max - old_top;
CollectedHeap::fill_with_object(old_top, fill_size);
_summary_bytes_used += fill_size * HeapWordSize;
}
_allocation_region->set_top(_max);
old_top = _bottom = _max;
--- 226,245 ----
err_msg("inconsistent allocation state: expected "
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()))) {
if (old_top != _max) {
! size_t fill_size = pointer_delta(_max, old_top);
CollectedHeap::fill_with_object(old_top, fill_size);
_summary_bytes_used += fill_size * HeapWordSize;
}
_allocation_region->set_top(_max);
old_top = _bottom = _max;
*** 242,302 ****
// 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()) {
_max = _bottom + HeapRegion::min_region_size_in_words();
} else {
! alloc_new_region();
old_top = _allocation_region->bottom();
}
}
_allocation_region->set_top(old_top + word_size);
_summary_bytes_used += word_size * HeapWordSize;
return old_top;
}
void G1ArchiveAllocator::complete_archive(GrowableArray<MemRegion>* ranges,
! uint end_alignment) {
! assert((end_alignment >> LogHeapWordSize) < HeapRegion::min_region_size_in_words(),
! "alignment too large");
// If we've allocated nothing, simply return.
if (_allocation_region == NULL) {
return;
}
// If an end alignment was requested, insert filler objects.
! if (end_alignment != 0) {
HeapWord* currtop = _allocation_region->top();
! HeapWord* newtop = (HeapWord*)round_to((intptr_t)currtop, end_alignment);
! size_t fill_size = newtop - currtop;
if (fill_size != 0) {
HeapWord* fill = archive_mem_allocate(fill_size);
CollectedHeap::fill_with_objects(fill, fill_size);
}
}
// Loop through the allocated regions, and create MemRegions summarizing
// the allocated address range, combining contiguous ranges. Add the
! // MemRegions to the growable array provided by the caller.
int index = _allocated_regions.length() - 1;
! assert(_allocated_regions.at(index) == _allocation_region, "expect current region at end of array");
HeapWord* base_address = _allocation_region->bottom();
HeapWord* top = base_address;
while (index >= 0) {
! HeapRegion* next = _allocated_regions.at(index--);
HeapWord* new_base = next->bottom();
HeapWord* new_top = next->top();
if (new_base != top) {
! ranges->append(MemRegion(base_address, top - base_address));
base_address = new_base;
}
top = new_top;
}
! ranges->append(MemRegion(base_address, top - base_address));
_allocated_regions.clear();
_allocation_region = NULL;
-
- return;
-
};
--- 247,323 ----
// 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()) {
_max = _bottom + HeapRegion::min_region_size_in_words();
} else {
! if (!alloc_new_region()) {
! return NULL;
! }
old_top = _allocation_region->bottom();
}
}
_allocation_region->set_top(old_top + word_size);
_summary_bytes_used += word_size * HeapWordSize;
return old_top;
}
void G1ArchiveAllocator::complete_archive(GrowableArray<MemRegion>* ranges,
! size_t end_alignment_in_bytes) {
! assert((end_alignment_in_bytes >> LogHeapWordSize) < HeapRegion::min_region_size_in_words(),
! err_msg("alignment " SIZE_FORMAT " too large", end_alignment_in_bytes));
! assert(is_size_aligned(end_alignment_in_bytes, HeapWordSize),
! err_msg("alignment " SIZE_FORMAT " is not HeapWord (%u) aligned", end_alignment_in_bytes, HeapWordSize));
!
// If we've allocated nothing, simply return.
if (_allocation_region == NULL) {
return;
}
// If an end alignment was requested, insert filler objects.
! if (end_alignment_in_bytes != 0) {
HeapWord* currtop = _allocation_region->top();
! HeapWord* newtop = (HeapWord*)align_pointer_up(currtop, end_alignment_in_bytes);
! size_t fill_size = pointer_delta(newtop, currtop);
if (fill_size != 0) {
+ if (fill_size < CollectedHeap::min_fill_size()) {
+ // If the required fill is smaller than we can represent,
+ // bump up to the next aligned address. We know we won't exceed the current
+ // region boundary because the max supported alignment is smaller than the min
+ // region size, and because the allocation code never leaves space smaller than
+ // the min_fill_size at the top of the current allocation region.
+ newtop = (HeapWord*)align_pointer_up(currtop + CollectedHeap::min_fill_size(),
+ end_alignment_in_bytes);
+ fill_size = pointer_delta(newtop, currtop);
+ }
HeapWord* fill = archive_mem_allocate(fill_size);
CollectedHeap::fill_with_objects(fill, fill_size);
}
}
// Loop through the allocated regions, and create MemRegions summarizing
// the allocated address range, combining contiguous ranges. Add the
! // MemRegions to the GrowableArray provided by the caller.
int index = _allocated_regions.length() - 1;
! assert(_allocated_regions.at(index) == _allocation_region,
! err_msg("expected region %u at end of array, found %u",
! _allocation_region->hrm_index(), _allocated_regions.at(index)->hrm_index()));
HeapWord* base_address = _allocation_region->bottom();
HeapWord* top = base_address;
while (index >= 0) {
! HeapRegion* next = _allocated_regions.at(index);
HeapWord* new_base = next->bottom();
HeapWord* new_top = next->top();
if (new_base != top) {
! ranges->append(MemRegion(base_address, pointer_delta(top, base_address)));
base_address = new_base;
}
top = new_top;
+ index = index - 1;
}
! assert(top != base_address, err_msg("zero-sized range, address " PTR_FORMAT, p2i(base_address)));
! ranges->append(MemRegion(base_address, pointer_delta(top, base_address)));
_allocated_regions.clear();
_allocation_region = NULL;
};
< prev index next >