--- old/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp 2015-03-05 15:35:41.308546636 +0100 +++ new/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp 2015-03-05 15:35:41.235544466 +0100 @@ -30,18 +30,19 @@ #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) @@ -58,52 +59,29 @@ _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 @@ -142,8 +120,6 @@ #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. @@ -167,8 +143,9 @@ // 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; } @@ -209,12 +186,12 @@ 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) { @@ -231,7 +208,7 @@ 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 @@ -272,7 +249,7 @@ "sanity"); G1StringDedup::enqueue_from_evacuation(is_from_young, is_to_young, - queue_num(), + worker_queue_id(), obj); } @@ -293,7 +270,7 @@ } 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; } }