< prev index next >
src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp
Print this page
rev 7902 : [mq]: 8073052-Rename-and-clean-up-the-allocation-manager-hierarchy-in-g1Allocator
rev 7903 : imported patch 8073013-add-detailed-information-about-plab-memory-usage
rev 7904 : imported patch 8040162-avoid-reallocating-plab-allocators
rev 7908 : [mq]: 8073317-move-region-level-allocation-into-allocregionmanager
@@ -28,22 +28,23 @@
#include "gc_implementation/g1/g1ParScanThreadState.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/oop.pcgc.inline.hpp"
#include "runtime/prefetch.inline.hpp"
-G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num, ReferenceProcessor* rp)
+G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint worker_id)
: _g1h(g1h),
- _refs(g1h->task_queue(queue_num)),
+ _refs(g1h->task_queue(worker_id)),
_dcq(&g1h->dirty_card_queue_set()),
_ct_bs(g1h->g1_barrier_set()),
_g1_rem(g1h->g1_rem_set()),
- _hash_seed(17), _queue_num(queue_num),
- _term_attempts(0),
+ _hash_seed(17), _worker_id(worker_id),
_tenuring_threshold(g1h->g1_policy()->tenuring_threshold()),
- _age_table(false), _scanner(g1h, rp),
- _strong_roots_time(0), _term_time(0) {
+ _age_table(false),
+ _scanner(g1h),
+ _evac_failure_cl(g1h) {
_scanner.set_par_scan_thread_state(this);
+ _evac_failure_cl.set_par_scan_thread_state(this);
// we allocate G1YoungSurvRateNumRegions plus one entries, since
// we "sacrifice" entry 0 to keep track of surviving bytes for
// non-young regions (where the age is -1)
// We also add a few elements at the beginning and at the end in
// an attempt to eliminate cache contention
@@ -56,56 +57,33 @@
vm_exit_out_of_memory(array_length * sizeof(size_t), OOM_MALLOC_ERROR,
"Not enough space for young surv histo.");
_surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
memset(_surviving_young_words, 0, (size_t) real_length * sizeof(size_t));
- _g1_par_allocator = G1ParGCAllocator::create_allocator(_g1h);
+ _plab_allocator = PLABAllocator::create_allocator(_g1h->_allocator);
_dest[InCSetState::NotInCSet] = InCSetState::NotInCSet;
// The dest for Young is used when the objects are aged enough to
// need to be moved to the next space.
_dest[InCSetState::Young] = InCSetState::Old;
_dest[InCSetState::Old] = InCSetState::Old;
-
- _start = os::elapsedTime();
}
G1ParScanThreadState::~G1ParScanThreadState() {
- _g1_par_allocator->retire_alloc_buffers();
- delete _g1_par_allocator;
+ _plab_allocator->flush_stats_and_retire();
+ delete _plab_allocator;
FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base);
}
-void
-G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st)
-{
- st->print_raw_cr("GC Termination Stats");
- st->print_raw_cr(" elapsed --strong roots-- -------termination-------"
- " ------waste (KiB)------");
- st->print_raw_cr("thr ms ms % ms % attempts"
- " total alloc undo");
- st->print_raw_cr("--- --------- --------- ------ --------- ------ --------"
- " ------- ------- -------");
-}
-
-void
-G1ParScanThreadState::print_termination_stats(int i,
- outputStream* const st) const
-{
- const double elapsed_ms = elapsed_time() * 1000.0;
- const double s_roots_ms = strong_roots_time() * 1000.0;
- const double term_ms = term_time() * 1000.0;
- const size_t alloc_buffer_waste = _g1_par_allocator->alloc_buffer_waste();
- const size_t undo_waste = _g1_par_allocator->undo_waste();
- st->print_cr("%3d %9.2f %9.2f %6.2f "
- "%9.2f %6.2f " SIZE_FORMAT_W(8) " "
- SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7),
- i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms,
- term_ms, term_ms * 100 / elapsed_ms, term_attempts(),
- (alloc_buffer_waste + undo_waste) * HeapWordSize / K,
- alloc_buffer_waste * HeapWordSize / K,
- undo_waste * HeapWordSize / K);
+size_t G1ParScanThreadState::lab_waste() const {
+ return _plab_allocator->lab_waste(InCSetState::Young) +
+ _plab_allocator->lab_waste(InCSetState::Old);
+}
+
+size_t G1ParScanThreadState::lab_undo_waste() const {
+ return _plab_allocator->lab_undo_waste(InCSetState::Young) +
+ _plab_allocator->lab_undo_waste(InCSetState::Old);
}
#ifdef ASSERT
bool G1ParScanThreadState::verify_ref(narrowOop* ref) const {
assert(ref != NULL, "invariant");
@@ -140,12 +118,10 @@
}
}
#endif // ASSERT
void G1ParScanThreadState::trim_queue() {
- assert(_evac_failure_cl != NULL, "not set");
-
StarTask ref;
do {
// Drain the overflow stack first, so other threads can steal.
while (_refs->pop_overflow(ref)) {
dispatch_reference(ref);
@@ -165,12 +141,13 @@
assert(dest->is_in_cset_or_humongous(), err_msg("Unexpected dest: " CSETSTATE_FORMAT, dest->value()));
// Right now we only have two types of regions (young / old) so
// let's keep the logic here simple. We can generalize it when necessary.
if (dest->is_young()) {
- HeapWord* const obj_ptr = _g1_par_allocator->allocate(InCSetState::Old,
- word_sz, context);
+ HeapWord* const obj_ptr = _plab_allocator->allocate(InCSetState::Old,
+ word_sz,
+ context);
if (obj_ptr == NULL) {
return NULL;
}
// Make sure that we won't attempt to copy any other objects out
// of a survivor region (given that apparently we cannot allocate
@@ -207,16 +184,16 @@
(!from_region->is_young() && young_index == 0), "invariant" );
const AllocationContext_t context = from_region->allocation_context();
uint age = 0;
InCSetState dest_state = next_state(state, old_mark, age);
- HeapWord* obj_ptr = _g1_par_allocator->plab_allocate(dest_state, word_sz, context);
+ HeapWord* obj_ptr = _plab_allocator->plab_allocate(dest_state, word_sz, context);
// PLAB allocations should succeed most of the time, so we'll
// normally check against NULL once and that's it.
if (obj_ptr == NULL) {
- obj_ptr = _g1_par_allocator->allocate_direct_or_new_plab(dest_state, word_sz, context);
+ obj_ptr = _plab_allocator->allocate_direct_or_new_plab(dest_state, word_sz, context);
if (obj_ptr == NULL) {
obj_ptr = allocate_in_next_plab(state, &dest_state, word_sz, context);
if (obj_ptr == NULL) {
// This will either forward-to-self, or detect that someone else has
// installed a forwarding pointer.
@@ -229,11 +206,11 @@
#ifndef PRODUCT
// Should this evacuation fail?
if (_g1h->evacuation_should_fail()) {
// Doing this after all the allocation attempts also tests the
// undo_allocation() method too.
- _g1_par_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context);
+ _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context);
return _g1h->handle_evacuation_failure_par(this, old);
}
#endif // !PRODUCT
// We're going to allocate linearly, so might as well prefetch ahead.
@@ -270,11 +247,11 @@
"sanity");
assert(is_to_young == _g1h->heap_region_containing_raw(obj)->is_young(),
"sanity");
G1StringDedup::enqueue_from_evacuation(is_from_young,
is_to_young,
- queue_num(),
+ worker_queue_id(),
obj);
}
size_t* const surv_young_words = surviving_young_words();
surv_young_words[young_index] += word_sz;
@@ -291,9 +268,9 @@
_scanner.set_region(to_region);
obj->oop_iterate_backwards(&_scanner);
}
return obj;
} else {
- _g1_par_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context);
+ _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz, context);
return forward_ptr;
}
}
< prev index next >