< prev index next >
src/hotspot/share/gc/g1/g1Allocator.cpp
Print this page
*** 98,227 ****
&_old_gc_alloc_region,
&_retained_old_gc_alloc_region);
}
void G1DefaultAllocator::release_gc_alloc_regions(EvacuationInfo& evacuation_info) {
! AllocationContext_t context = AllocationContext::current();
! evacuation_info.set_allocation_regions(survivor_gc_alloc_region(context)->count() +
! old_gc_alloc_region(context)->count());
! survivor_gc_alloc_region(context)->release();
// If we have an old GC alloc region to release, we'll save it in
// _retained_old_gc_alloc_region. If we don't
// _retained_old_gc_alloc_region will become NULL. This is what we
// want either way so no reason to check explicitly for either
// condition.
! _retained_old_gc_alloc_region = old_gc_alloc_region(context)->release();
}
void G1DefaultAllocator::abandon_gc_alloc_regions() {
! assert(survivor_gc_alloc_region(AllocationContext::current())->get() == NULL, "pre-condition");
! assert(old_gc_alloc_region(AllocationContext::current())->get() == NULL, "pre-condition");
_retained_old_gc_alloc_region = NULL;
}
! bool G1DefaultAllocator::survivor_is_full(AllocationContext_t context) const {
return _survivor_is_full;
}
! bool G1DefaultAllocator::old_is_full(AllocationContext_t context) const {
return _old_is_full;
}
! void G1DefaultAllocator::set_survivor_full(AllocationContext_t context) {
_survivor_is_full = true;
}
! void G1DefaultAllocator::set_old_full(AllocationContext_t context) {
_old_is_full = true;
}
! size_t G1Allocator::unsafe_max_tlab_alloc(AllocationContext_t context) {
// Return the remaining space in the cur alloc region, but not less than
// the min TLAB size.
// Also, this value can be at most the humongous object threshold,
// since we can't allow tlabs to grow big enough to accommodate
// humongous objects.
! HeapRegion* hr = mutator_alloc_region(context)->get();
size_t max_tlab = _g1h->max_tlab_size() * wordSize;
if (hr == NULL) {
return max_tlab;
} else {
return MIN2(MAX2(hr->free(), (size_t) MinTLABSize), max_tlab);
}
}
HeapWord* G1Allocator::par_allocate_during_gc(InCSetState dest,
! size_t word_size,
! AllocationContext_t context) {
size_t temp = 0;
! HeapWord* result = par_allocate_during_gc(dest, word_size, word_size, &temp, context);
assert(result == NULL || temp == word_size,
"Requested " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT,
word_size, temp, p2i(result));
return result;
}
HeapWord* G1Allocator::par_allocate_during_gc(InCSetState dest,
size_t min_word_size,
size_t desired_word_size,
! size_t* actual_word_size,
! AllocationContext_t context) {
switch (dest.value()) {
case InCSetState::Young:
! return survivor_attempt_allocation(min_word_size, desired_word_size, actual_word_size, context);
case InCSetState::Old:
! return old_attempt_allocation(min_word_size, desired_word_size, actual_word_size, context);
default:
ShouldNotReachHere();
return NULL; // Keep some compilers happy
}
}
HeapWord* G1Allocator::survivor_attempt_allocation(size_t min_word_size,
size_t desired_word_size,
! size_t* actual_word_size,
! AllocationContext_t context) {
assert(!_g1h->is_humongous(desired_word_size),
"we should not be seeing humongous-size allocations in this path");
! HeapWord* result = survivor_gc_alloc_region(context)->attempt_allocation(min_word_size,
desired_word_size,
actual_word_size);
! if (result == NULL && !survivor_is_full(context)) {
MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
! result = survivor_gc_alloc_region(context)->attempt_allocation_locked(min_word_size,
desired_word_size,
actual_word_size);
if (result == NULL) {
! set_survivor_full(context);
}
}
if (result != NULL) {
_g1h->dirty_young_block(result, *actual_word_size);
}
return result;
}
HeapWord* G1Allocator::old_attempt_allocation(size_t min_word_size,
size_t desired_word_size,
! size_t* actual_word_size,
! AllocationContext_t context) {
assert(!_g1h->is_humongous(desired_word_size),
"we should not be seeing humongous-size allocations in this path");
! HeapWord* result = old_gc_alloc_region(context)->attempt_allocation(min_word_size,
desired_word_size,
actual_word_size);
! if (result == NULL && !old_is_full(context)) {
MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
! result = old_gc_alloc_region(context)->attempt_allocation_locked(min_word_size,
desired_word_size,
actual_word_size);
if (result == NULL) {
! set_old_full(context);
}
}
return result;
}
--- 98,222 ----
&_old_gc_alloc_region,
&_retained_old_gc_alloc_region);
}
void G1DefaultAllocator::release_gc_alloc_regions(EvacuationInfo& evacuation_info) {
! evacuation_info.set_allocation_regions(survivor_gc_alloc_region()->count() +
! old_gc_alloc_region()->count());
! survivor_gc_alloc_region()->release();
// If we have an old GC alloc region to release, we'll save it in
// _retained_old_gc_alloc_region. If we don't
// _retained_old_gc_alloc_region will become NULL. This is what we
// want either way so no reason to check explicitly for either
// condition.
! _retained_old_gc_alloc_region = old_gc_alloc_region()->release();
}
void G1DefaultAllocator::abandon_gc_alloc_regions() {
! assert(survivor_gc_alloc_region()->get() == NULL, "pre-condition");
! assert(old_gc_alloc_region()->get() == NULL, "pre-condition");
_retained_old_gc_alloc_region = NULL;
}
! bool G1DefaultAllocator::survivor_is_full() const {
return _survivor_is_full;
}
! bool G1DefaultAllocator::old_is_full() const {
return _old_is_full;
}
! void G1DefaultAllocator::set_survivor_full() {
_survivor_is_full = true;
}
! void G1DefaultAllocator::set_old_full() {
_old_is_full = true;
}
! size_t G1Allocator::unsafe_max_tlab_alloc() {
// Return the remaining space in the cur alloc region, but not less than
// the min TLAB size.
// Also, this value can be at most the humongous object threshold,
// since we can't allow tlabs to grow big enough to accommodate
// humongous objects.
! HeapRegion* hr = mutator_alloc_region()->get();
size_t max_tlab = _g1h->max_tlab_size() * wordSize;
if (hr == NULL) {
return max_tlab;
} else {
return MIN2(MAX2(hr->free(), (size_t) MinTLABSize), max_tlab);
}
}
HeapWord* G1Allocator::par_allocate_during_gc(InCSetState dest,
! size_t word_size) {
size_t temp = 0;
! HeapWord* result = par_allocate_during_gc(dest, word_size, word_size, &temp);
assert(result == NULL || temp == word_size,
"Requested " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT,
word_size, temp, p2i(result));
return result;
}
HeapWord* G1Allocator::par_allocate_during_gc(InCSetState dest,
size_t min_word_size,
size_t desired_word_size,
! size_t* actual_word_size) {
switch (dest.value()) {
case InCSetState::Young:
! return survivor_attempt_allocation(min_word_size, desired_word_size, actual_word_size);
case InCSetState::Old:
! return old_attempt_allocation(min_word_size, desired_word_size, actual_word_size);
default:
ShouldNotReachHere();
return NULL; // Keep some compilers happy
}
}
HeapWord* G1Allocator::survivor_attempt_allocation(size_t min_word_size,
size_t desired_word_size,
! size_t* actual_word_size) {
assert(!_g1h->is_humongous(desired_word_size),
"we should not be seeing humongous-size allocations in this path");
! HeapWord* result = survivor_gc_alloc_region()->attempt_allocation(min_word_size,
desired_word_size,
actual_word_size);
! if (result == NULL && !survivor_is_full()) {
MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
! result = survivor_gc_alloc_region()->attempt_allocation_locked(min_word_size,
desired_word_size,
actual_word_size);
if (result == NULL) {
! set_survivor_full();
}
}
if (result != NULL) {
_g1h->dirty_young_block(result, *actual_word_size);
}
return result;
}
HeapWord* G1Allocator::old_attempt_allocation(size_t min_word_size,
size_t desired_word_size,
! size_t* actual_word_size) {
assert(!_g1h->is_humongous(desired_word_size),
"we should not be seeing humongous-size allocations in this path");
! HeapWord* result = old_gc_alloc_region()->attempt_allocation(min_word_size,
desired_word_size,
actual_word_size);
! if (result == NULL && !old_is_full()) {
MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag);
! result = old_gc_alloc_region()->attempt_allocation_locked(min_word_size,
desired_word_size,
actual_word_size);
if (result == NULL) {
! set_old_full();
}
}
return result;
}
*** 238,266 ****
return (allocation_word_sz * 100 < buffer_size * ParallelGCBufferWastePct);
}
HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(InCSetState dest,
size_t word_sz,
- AllocationContext_t context,
bool* plab_refill_failed) {
size_t plab_word_size = G1CollectedHeap::heap()->desired_plab_sz(dest);
size_t required_in_plab = PLAB::size_required_for_allocation(word_sz);
// Only get a new PLAB if the allocation fits and it would not waste more than
// ParallelGCBufferWastePct in the existing buffer.
if ((required_in_plab <= plab_word_size) &&
may_throw_away_buffer(required_in_plab, plab_word_size)) {
! PLAB* alloc_buf = alloc_buffer(dest, context);
alloc_buf->retire();
size_t actual_plab_size = 0;
HeapWord* buf = _allocator->par_allocate_during_gc(dest,
required_in_plab,
plab_word_size,
! &actual_plab_size,
! context);
assert(buf == NULL || ((actual_plab_size >= required_in_plab) && (actual_plab_size <= plab_word_size)),
"Requested at minimum " SIZE_FORMAT ", desired " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT,
required_in_plab, plab_word_size, actual_plab_size, p2i(buf));
--- 233,259 ----
return (allocation_word_sz * 100 < buffer_size * ParallelGCBufferWastePct);
}
HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(InCSetState dest,
size_t word_sz,
bool* plab_refill_failed) {
size_t plab_word_size = G1CollectedHeap::heap()->desired_plab_sz(dest);
size_t required_in_plab = PLAB::size_required_for_allocation(word_sz);
// Only get a new PLAB if the allocation fits and it would not waste more than
// ParallelGCBufferWastePct in the existing buffer.
if ((required_in_plab <= plab_word_size) &&
may_throw_away_buffer(required_in_plab, plab_word_size)) {
! PLAB* alloc_buf = alloc_buffer(dest);
alloc_buf->retire();
size_t actual_plab_size = 0;
HeapWord* buf = _allocator->par_allocate_during_gc(dest,
required_in_plab,
plab_word_size,
! &actual_plab_size);
assert(buf == NULL || ((actual_plab_size >= required_in_plab) && (actual_plab_size <= plab_word_size)),
"Requested at minimum " SIZE_FORMAT ", desired " SIZE_FORMAT " words, but got " SIZE_FORMAT " at " PTR_FORMAT,
required_in_plab, plab_word_size, actual_plab_size, p2i(buf));
*** 275,293 ****
}
// Otherwise.
*plab_refill_failed = true;
}
// Try direct allocation.
! HeapWord* result = _allocator->par_allocate_during_gc(dest, word_sz, context);
if (result != NULL) {
_direct_allocated[dest.value()] += word_sz;
}
return result;
}
! void G1PLABAllocator::undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz, AllocationContext_t context) {
! alloc_buffer(dest, context)->undo_allocation(obj, word_sz);
}
G1DefaultPLABAllocator::G1DefaultPLABAllocator(G1Allocator* allocator) :
G1PLABAllocator(allocator),
_surviving_alloc_buffer(_g1h->desired_plab_sz(InCSetState::Young)),
--- 268,286 ----
}
// Otherwise.
*plab_refill_failed = true;
}
// Try direct allocation.
! HeapWord* result = _allocator->par_allocate_during_gc(dest, word_sz);
if (result != NULL) {
_direct_allocated[dest.value()] += word_sz;
}
return result;
}
! void G1PLABAllocator::undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz) {
! alloc_buffer(dest)->undo_allocation(obj, word_sz);
}
G1DefaultPLABAllocator::G1DefaultPLABAllocator(G1Allocator* allocator) :
G1PLABAllocator(allocator),
_surviving_alloc_buffer(_g1h->desired_plab_sz(InCSetState::Young)),
< prev index next >