src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp

Print this page
rev 6279 : imported patch fast-cset-uses-biasedarray
rev 6282 : 8028710: G1 does not retire allocation buffers after reference processing work
Summary: G1 does not retire allocation buffers after reference processing work when -XX:+ParallelRefProcEnabled is enabled.
Reviewed-by:
rev 6283 : 8019342: G1: High "Other" time most likely due to card redirtying
Summary: Parallelize card redirtying to decrease the time it takes.
Reviewed-by: tbd, tbd
rev 6284 : [mq]: fixes-cleanup
rev 6285 : 8040002: Clean up code and code duplication in re-diryting cards for verification
Summary: Card re-dirtying code for verification and actual redirtying uses two different, almost completely identical card closures. Also the verification code still assumes a perm gen.
Reviewed-by: tbd, tbd

*** 114,170 **** void set_concurrent(bool b) { _concurrent = b; } }; class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { ! int _calls; ! G1CollectedHeap* _g1h; CardTableModRefBS* _ctbs; int _histo[256]; ! public: ClearLoggedCardTableEntryClosure() : ! _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) { for (int i = 0; i < 256; i++) _histo[i] = 0; } bool do_card_ptr(jbyte* card_ptr, uint worker_i) { - if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { - _calls++; unsigned char* ujb = (unsigned char*)card_ptr; int ind = (int)(*ujb); _histo[ind]++; ! *card_ptr = -1; ! } return true; } ! int calls() { return _calls; } void print_histo() { gclog_or_tty->print_cr("Card table value histogram:"); for (int i = 0; i < 256; i++) { if (_histo[i] != 0) { gclog_or_tty->print_cr(" %d: %d", i, _histo[i]); } } } }; ! class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure { ! int _calls; ! G1CollectedHeap* _g1h; ! CardTableModRefBS* _ctbs; ! public: ! RedirtyLoggedCardTableEntryClosure() : ! _calls(0), _g1h(G1CollectedHeap::heap()), _ctbs(_g1h->g1_barrier_set()) {} bool do_card_ptr(jbyte* card_ptr, uint worker_i) { ! if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { ! _calls++; ! *card_ptr = 0; ! } return true; } ! int calls() { return _calls; } }; YoungList::YoungList(G1CollectedHeap* g1h) : _g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0), _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) { --- 114,171 ---- void set_concurrent(bool b) { _concurrent = b; } }; class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { ! size_t _num_processed; CardTableModRefBS* _ctbs; int _histo[256]; ! ! public: ClearLoggedCardTableEntryClosure() : ! _num_processed(0), _ctbs(G1CollectedHeap::heap()->g1_barrier_set()) { for (int i = 0; i < 256; i++) _histo[i] = 0; } + bool do_card_ptr(jbyte* card_ptr, uint worker_i) { unsigned char* ujb = (unsigned char*)card_ptr; int ind = (int)(*ujb); _histo[ind]++; ! ! *card_ptr = (jbyte)CardTableModRefBS::clean_card_val(); ! _num_processed++; ! return true; } ! ! size_t num_processed() { return _num_processed; } ! void print_histo() { gclog_or_tty->print_cr("Card table value histogram:"); for (int i = 0; i < 256; i++) { if (_histo[i] != 0) { gclog_or_tty->print_cr(" %d: %d", i, _histo[i]); } } } }; ! class RedirtyLoggedCardTableEntryClosure : public CardTableEntryClosure { ! private: ! size_t _num_processed; ! ! public: ! RedirtyLoggedCardTableEntryClosure() : CardTableEntryClosure(), _num_processed(0) { } bool do_card_ptr(jbyte* card_ptr, uint worker_i) { ! *card_ptr = CardTableModRefBS::dirty_card_val(); ! _num_processed++; return true; } ! ! size_t num_processed() const { return _num_processed; } }; YoungList::YoungList(G1CollectedHeap* g1h) : _g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0), _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) {
*** 489,501 **** RedirtyLoggedCardTableEntryClosure redirty; dcqs.apply_closure_to_all_completed_buffers(&redirty); dcqs.iterate_closure_all_threads(&redirty, false); gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.", ! clear.calls(), orig_count); ! guarantee(redirty.calls() == clear.calls(), ! "Or else mechanism is broken."); CountNonCleanMemRegionClosure count3(this); ct_bs->mod_card_iterate(&count3); if (count3.n() != orig_count) { gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.", --- 490,503 ---- RedirtyLoggedCardTableEntryClosure redirty; dcqs.apply_closure_to_all_completed_buffers(&redirty); dcqs.iterate_closure_all_threads(&redirty, false); gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.", ! clear.num_processed(), orig_count); ! guarantee(redirty.num_processed() == clear.num_processed(), ! err_msg("Redirtied "SIZE_FORMAT" cards, bug cleared "SIZE_FORMAT, ! redirty.num_processed(), clear.num_processed())); CountNonCleanMemRegionClosure count3(this); ct_bs->mod_card_iterate(&count3); if (count3.n() != orig_count) { gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.",
*** 5252,5287 **** if (G1StringDedup::is_enabled()) { G1StringDedup::unlink(is_alive); } } - class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure { - private: - size_t _num_processed; - - public: - RedirtyLoggedCardTableEntryFastClosure() : CardTableEntryClosure(), _num_processed(0) { } - - bool do_card_ptr(jbyte* card_ptr, uint worker_i) { - *card_ptr = CardTableModRefBS::dirty_card_val(); - _num_processed++; - return true; - } - - size_t num_processed() const { return _num_processed; } - }; - class G1RedirtyLoggedCardsTask : public AbstractGangTask { private: DirtyCardQueueSet* _queue; public: G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { } virtual void work(uint worker_id) { double start_time = os::elapsedTime(); ! RedirtyLoggedCardTableEntryFastClosure cl; if (G1CollectedHeap::heap()->use_parallel_gc_threads()) { _queue->par_apply_closure_to_all_completed_buffers(&cl); } else { _queue->apply_closure_to_all_completed_buffers(&cl); } --- 5254,5273 ---- if (G1StringDedup::is_enabled()) { G1StringDedup::unlink(is_alive); } } class G1RedirtyLoggedCardsTask : public AbstractGangTask { private: DirtyCardQueueSet* _queue; public: G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue) : AbstractGangTask("Redirty Cards"), _queue(queue) { } virtual void work(uint worker_id) { double start_time = os::elapsedTime(); ! RedirtyLoggedCardTableEntryClosure cl; if (G1CollectedHeap::heap()->use_parallel_gc_threads()) { _queue->par_apply_closure_to_all_completed_buffers(&cl); } else { _queue->apply_closure_to_all_completed_buffers(&cl); }