< 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 >