< prev index next >
src/share/vm/gc_implementation/g1/g1Allocator.cpp
Print this page
rev 7471 : 8060025: Object copy time regressions after JDK-8031323 and JDK-8057536
Summary: Evaluate and improve object copy time by micro-optimizations and splitting out slow and fast paths aggressively.
Reviewed-by:
Contributed-by: Tony Printezis <tprintezis@twitter.com>, Thomas Schatzl <thomas.schatzl@oracle.com>
rev 7472 : [mq]: 8060025-mikael-review1
rev 7473 : imported patch mikael-refactor-cset-state
*** 111,158 ****
}
G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
ParGCAllocBuffer(gclab_word_size), _retired(true) { }
! HeapWord* G1ParGCAllocator::allocate_slow(GCAllocPurpose purpose, size_t word_sz, AllocationContext_t context) {
! HeapWord* obj = NULL;
! size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
! G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose, context);
add_to_alloc_buffer_waste(alloc_buf->words_remaining());
alloc_buf->retire(false /* end_of_gc */, false /* retain */);
! HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size, context);
if (buf == NULL) {
return NULL; // Let caller handle allocation failure.
}
// Otherwise.
alloc_buf->set_word_size(gclab_word_size);
alloc_buf->set_buf(buf);
! obj = alloc_buf->allocate(word_sz);
assert(obj != NULL, "buffer was definitely big enough...");
} else {
! obj = _g1h->par_allocate_during_gc(purpose, word_sz, context);
}
- return obj;
}
G1DefaultParGCAllocator::G1DefaultParGCAllocator(G1CollectedHeap* g1h) :
G1ParGCAllocator(g1h),
! _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)),
! _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)) {
!
! _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer;
! _alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer;
!
}
void G1DefaultParGCAllocator::retire_alloc_buffers() {
! for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
! size_t waste = _alloc_buffers[ap]->words_remaining();
! add_to_alloc_buffer_waste(waste);
! _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
true /* end_of_gc */,
false /* retain */);
}
}
--- 111,162 ----
}
G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) :
ParGCAllocBuffer(gclab_word_size), _retired(true) { }
! HeapWord* G1ParGCAllocator::allocate_direct_or_new_plab(InCSetState dest,
! size_t word_sz,
! AllocationContext_t context) {
! size_t gclab_word_size = _g1h->desired_plab_sz(dest);
if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
! G1ParGCAllocBuffer* alloc_buf = alloc_buffer(dest, context);
add_to_alloc_buffer_waste(alloc_buf->words_remaining());
alloc_buf->retire(false /* end_of_gc */, false /* retain */);
! HeapWord* buf = _g1h->par_allocate_during_gc(dest, gclab_word_size, context);
if (buf == NULL) {
return NULL; // Let caller handle allocation failure.
}
// Otherwise.
alloc_buf->set_word_size(gclab_word_size);
alloc_buf->set_buf(buf);
! HeapWord* const obj = alloc_buf->allocate(word_sz);
assert(obj != NULL, "buffer was definitely big enough...");
+ return obj;
} else {
! return _g1h->par_allocate_during_gc(dest, word_sz, context);
}
}
G1DefaultParGCAllocator::G1DefaultParGCAllocator(G1CollectedHeap* g1h) :
G1ParGCAllocator(g1h),
! _surviving_alloc_buffer(g1h->desired_plab_sz(InCSetState::Young)),
! _tenured_alloc_buffer(g1h->desired_plab_sz(InCSetState::Old)) {
! for (uint state = 0; state < InCSetState::Num; state++) {
! _alloc_buffers[state] = NULL;
! }
! _alloc_buffers[InCSetState::Young] = &_surviving_alloc_buffer;
! _alloc_buffers[InCSetState::Old] = &_tenured_alloc_buffer;
}
void G1DefaultParGCAllocator::retire_alloc_buffers() {
! for (uint state = 0; state < InCSetState::Num; state++) {
! G1ParGCAllocBuffer* const buf = _alloc_buffers[state];
! if (buf != NULL) {
! add_to_alloc_buffer_waste(buf->words_remaining());
! buf->flush_stats_and_retire(_g1h->alloc_buffer_stats(state),
true /* end_of_gc */,
false /* retain */);
}
+ }
}
< prev index next >