Mercurial > hg > graal-compiler
diff src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 1862:b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
Reviewed-by: iveresov, tonyp
author | jcoomes |
---|---|
date | Tue, 12 Oct 2010 11:29:45 -0700 |
parents | c32059ef4dc0 |
children | 35e4e086d5f5 |
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Oct 12 09:36:48 2010 -0700 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Oct 12 11:29:45 2010 -0700 @@ -3845,6 +3845,54 @@ undo_waste() * HeapWordSize / K); } +#ifdef ASSERT +bool G1ParScanThreadState::verify_ref(narrowOop* ref) const { + assert(ref != NULL, "invariant"); + assert(UseCompressedOops, "sanity"); + assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref)); + oop p = oopDesc::load_decode_heap_oop(ref); + assert(_g1h->is_in_g1_reserved(p), + err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); + return true; +} + +bool G1ParScanThreadState::verify_ref(oop* ref) const { + assert(ref != NULL, "invariant"); + if (has_partial_array_mask(ref)) { + // Must be in the collection set--it's already been copied. + oop p = clear_partial_array_mask(ref); + assert(_g1h->obj_in_cs(p), + err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); + } else { + oop p = oopDesc::load_decode_heap_oop(ref); + assert(_g1h->is_in_g1_reserved(p), + err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); + } + return true; +} + +bool G1ParScanThreadState::verify_task(StarTask ref) const { + if (ref.is_narrow()) { + return verify_ref((narrowOop*) ref); + } else { + return verify_ref((oop*) ref); + } +} +#endif // ASSERT + +void G1ParScanThreadState::trim_queue() { + StarTask ref; + do { + // Drain the overflow stack first, so other threads can steal. + while (refs()->pop_overflow(ref)) { + deal_with_reference(ref); + } + while (refs()->pop_local(ref)) { + deal_with_reference(ref); + } + } while (!refs()->is_empty()); +} + G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) : _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()), _par_scan_state(par_scan_state) { } @@ -4047,38 +4095,39 @@ : _g1h(g1h), _par_scan_state(par_scan_state), _queues(queues), _terminator(terminator) {} - void do_void() { - G1ParScanThreadState* pss = par_scan_state(); - while (true) { + void do_void(); + +private: + inline bool offer_termination(); +}; + +bool G1ParEvacuateFollowersClosure::offer_termination() { + G1ParScanThreadState* const pss = par_scan_state(); + pss->start_term_time(); + const bool res = terminator()->offer_termination(); + pss->end_term_time(); + return res; +} + +void G1ParEvacuateFollowersClosure::do_void() { + StarTask stolen_task; + G1ParScanThreadState* const pss = par_scan_state(); + pss->trim_queue(); + + do { + while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { + assert(pss->verify_task(stolen_task), "sanity"); + if (stolen_task.is_narrow()) { + pss->push_on_queue((narrowOop*) stolen_task); + } else { + pss->push_on_queue((oop*) stolen_task); + } pss->trim_queue(); - - StarTask stolen_task; - if (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { - // slightly paranoid tests; I'm trying to catch potential - // problems before we go into push_on_queue to know where the - // problem is coming from - assert((oop*)stolen_task != NULL, "Error"); - if (stolen_task.is_narrow()) { - assert(UseCompressedOops, "Error"); - narrowOop* p = (narrowOop*) stolen_task; - assert(has_partial_array_mask(p) || - _g1h->is_in_g1_reserved(oopDesc::load_decode_heap_oop(p)), "Error"); - pss->push_on_queue(p); - } else { - oop* p = (oop*) stolen_task; - assert(has_partial_array_mask(p) || _g1h->is_in_g1_reserved(*p), "Error"); - pss->push_on_queue(p); - } - continue; - } - pss->start_term_time(); - if (terminator()->offer_termination()) break; - pss->end_term_time(); } - pss->end_term_time(); - pss->retire_alloc_buffers(); - } -}; + } while (!offer_termination()); + + pss->retire_alloc_buffers(); +} class G1ParTask : public AbstractGangTask { protected: @@ -4177,8 +4226,7 @@ pss.print_termination_stats(i); } - assert(pss.refs_to_scan() == 0, "Task queue should be empty"); - assert(pss.overflowed_refs_to_scan() == 0, "Overflow queue should be empty"); + assert(pss.refs()->is_empty(), "should be empty"); double end_time_ms = os::elapsedTime() * 1000.0; _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms); }