< prev index next >

src/share/vm/gc/g1/g1RemSet.cpp

Print this page
rev 13167 : imported patch 8179677-rename-conc-refined-cards


 265 
 266     log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " "
 267                         "units of work for " SIZE_FORMAT " regions.",
 268                         cl.name(), num_workers, num_chunks, _cur_dirty_region);
 269     workers->run_task(&cl, num_workers);
 270 
 271 #ifndef PRODUCT
 272     // Need to synchronize with concurrent cleanup since it needs to
 273     // finish its card table clearing before we can verify.
 274     G1CollectedHeap::heap()->wait_while_free_regions_coming();
 275     G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
 276 #endif
 277   }
 278 };
 279 
 280 G1RemSet::G1RemSet(G1CollectedHeap* g1,
 281                    CardTableModRefBS* ct_bs,
 282                    G1HotCardCache* hot_card_cache) :
 283   _g1(g1),
 284   _scan_state(new G1RemSetScanState()),
 285   _conc_refine_cards(0),
 286   _ct_bs(ct_bs),
 287   _g1p(_g1->g1_policy()),
 288   _hot_card_cache(hot_card_cache),
 289   _prev_period_summary(),
 290   _into_cset_dirty_card_queue_set(false)
 291 {
 292   if (log_is_enabled(Trace, gc, remset)) {
 293     _prev_period_summary.initialize(this);
 294   }
 295   // Initialize the card queue set used to hold cards containing
 296   // references into the collection set.
 297   _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
 298                                              DirtyCardQ_CBL_mon,
 299                                              DirtyCardQ_FL_lock,
 300                                              -1, // never trigger processing
 301                                              -1, // no limit on length
 302                                              Shared_DirtyCardQ_lock,
 303                                              &JavaThread::dirty_card_queue_set());
 304 }
 305 


 707   bool card_processed =
 708     r->oops_on_card_seq_iterate_careful<false>(dirty_region, &conc_refine_cl);
 709 
 710   // If unable to process the card then we encountered an unparsable
 711   // part of the heap (e.g. a partially allocated object) while
 712   // processing a stale card.  Despite the card being stale, redirty
 713   // and re-enqueue, because we've already cleaned the card.  Without
 714   // this we could incorrectly discard a non-stale card.
 715   if (!card_processed) {
 716     // The card might have gotten re-dirtied and re-enqueued while we
 717     // worked.  (In fact, it's pretty likely.)
 718     if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
 719       *card_ptr = CardTableModRefBS::dirty_card_val();
 720       MutexLockerEx x(Shared_DirtyCardQ_lock,
 721                       Mutex::_no_safepoint_check_flag);
 722       DirtyCardQueue* sdcq =
 723         JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
 724       sdcq->enqueue(card_ptr);
 725     }
 726   } else {
 727     _conc_refine_cards++;
 728   }
 729 }
 730 
 731 bool G1RemSet::refine_card_during_gc(jbyte* card_ptr,
 732                                      G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
 733   assert(_g1->is_gc_active(), "Only call during GC");
 734 
 735   check_card_ptr(card_ptr, _ct_bs);
 736 
 737   // If the card is no longer dirty, nothing to do. This covers cards that were already
 738   // scanned as parts of the remembered sets.
 739   if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
 740     // No need to return that this card contains refs that point
 741     // into the collection set.
 742     return false;
 743   }
 744 
 745   // During GC we can immediately clean the card since we will not re-enqueue stale
 746   // cards as we know they can be disregarded.
 747   *card_ptr = CardTableModRefBS::clean_card_val();


 751   // And find the region containing it.
 752   HeapRegion* r = _g1->heap_region_containing(card_start);
 753 
 754   HeapWord* scan_limit = _scan_state->scan_top(r->hrm_index());
 755   if (scan_limit <= card_start) {
 756     // If the card starts above the area in the region containing objects to scan, skip it.
 757     return false;
 758   }
 759 
 760   // Don't use addr_for(card_ptr + 1) which can ask for
 761   // a card beyond the heap.
 762   HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
 763   MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
 764   assert(!dirty_region.is_empty(), "sanity");
 765 
 766   update_rs_cl->set_region(r);
 767   update_rs_cl->reset_has_refs_into_cset();
 768 
 769   bool card_processed = r->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
 770   assert(card_processed, "must be");
 771   _conc_refine_cards++;
 772 
 773   return update_rs_cl->has_refs_into_cset();
 774 }
 775 
 776 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
 777   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
 778       (period_count % G1SummarizeRSetStatsPeriod == 0)) {
 779 
 780     if (!_prev_period_summary.initialized()) {
 781       _prev_period_summary.initialize(this);
 782     }
 783 
 784     G1RemSetSummary current;
 785     current.initialize(this);
 786     _prev_period_summary.subtract_from(&current);
 787 
 788     Log(gc, remset) log;
 789     log.trace("%s", header);
 790     ResourceMark rm;
 791     _prev_period_summary.print_on(log.trace_stream());




 265 
 266     log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " "
 267                         "units of work for " SIZE_FORMAT " regions.",
 268                         cl.name(), num_workers, num_chunks, _cur_dirty_region);
 269     workers->run_task(&cl, num_workers);
 270 
 271 #ifndef PRODUCT
 272     // Need to synchronize with concurrent cleanup since it needs to
 273     // finish its card table clearing before we can verify.
 274     G1CollectedHeap::heap()->wait_while_free_regions_coming();
 275     G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
 276 #endif
 277   }
 278 };
 279 
 280 G1RemSet::G1RemSet(G1CollectedHeap* g1,
 281                    CardTableModRefBS* ct_bs,
 282                    G1HotCardCache* hot_card_cache) :
 283   _g1(g1),
 284   _scan_state(new G1RemSetScanState()),
 285   _num_conc_refined_cards(0),
 286   _ct_bs(ct_bs),
 287   _g1p(_g1->g1_policy()),
 288   _hot_card_cache(hot_card_cache),
 289   _prev_period_summary(),
 290   _into_cset_dirty_card_queue_set(false)
 291 {
 292   if (log_is_enabled(Trace, gc, remset)) {
 293     _prev_period_summary.initialize(this);
 294   }
 295   // Initialize the card queue set used to hold cards containing
 296   // references into the collection set.
 297   _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
 298                                              DirtyCardQ_CBL_mon,
 299                                              DirtyCardQ_FL_lock,
 300                                              -1, // never trigger processing
 301                                              -1, // no limit on length
 302                                              Shared_DirtyCardQ_lock,
 303                                              &JavaThread::dirty_card_queue_set());
 304 }
 305 


 707   bool card_processed =
 708     r->oops_on_card_seq_iterate_careful<false>(dirty_region, &conc_refine_cl);
 709 
 710   // If unable to process the card then we encountered an unparsable
 711   // part of the heap (e.g. a partially allocated object) while
 712   // processing a stale card.  Despite the card being stale, redirty
 713   // and re-enqueue, because we've already cleaned the card.  Without
 714   // this we could incorrectly discard a non-stale card.
 715   if (!card_processed) {
 716     // The card might have gotten re-dirtied and re-enqueued while we
 717     // worked.  (In fact, it's pretty likely.)
 718     if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
 719       *card_ptr = CardTableModRefBS::dirty_card_val();
 720       MutexLockerEx x(Shared_DirtyCardQ_lock,
 721                       Mutex::_no_safepoint_check_flag);
 722       DirtyCardQueue* sdcq =
 723         JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
 724       sdcq->enqueue(card_ptr);
 725     }
 726   } else {
 727     _num_conc_refined_cards++;
 728   }
 729 }
 730 
 731 bool G1RemSet::refine_card_during_gc(jbyte* card_ptr,
 732                                      G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
 733   assert(_g1->is_gc_active(), "Only call during GC");
 734 
 735   check_card_ptr(card_ptr, _ct_bs);
 736 
 737   // If the card is no longer dirty, nothing to do. This covers cards that were already
 738   // scanned as parts of the remembered sets.
 739   if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
 740     // No need to return that this card contains refs that point
 741     // into the collection set.
 742     return false;
 743   }
 744 
 745   // During GC we can immediately clean the card since we will not re-enqueue stale
 746   // cards as we know they can be disregarded.
 747   *card_ptr = CardTableModRefBS::clean_card_val();


 751   // And find the region containing it.
 752   HeapRegion* r = _g1->heap_region_containing(card_start);
 753 
 754   HeapWord* scan_limit = _scan_state->scan_top(r->hrm_index());
 755   if (scan_limit <= card_start) {
 756     // If the card starts above the area in the region containing objects to scan, skip it.
 757     return false;
 758   }
 759 
 760   // Don't use addr_for(card_ptr + 1) which can ask for
 761   // a card beyond the heap.
 762   HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
 763   MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
 764   assert(!dirty_region.is_empty(), "sanity");
 765 
 766   update_rs_cl->set_region(r);
 767   update_rs_cl->reset_has_refs_into_cset();
 768 
 769   bool card_processed = r->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
 770   assert(card_processed, "must be");

 771 
 772   return update_rs_cl->has_refs_into_cset();
 773 }
 774 
 775 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
 776   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
 777       (period_count % G1SummarizeRSetStatsPeriod == 0)) {
 778 
 779     if (!_prev_period_summary.initialized()) {
 780       _prev_period_summary.initialize(this);
 781     }
 782 
 783     G1RemSetSummary current;
 784     current.initialize(this);
 785     _prev_period_summary.subtract_from(&current);
 786 
 787     Log(gc, remset) log;
 788     log.trace("%s", header);
 789     ResourceMark rm;
 790     _prev_period_summary.print_on(log.trace_stream());


< prev index next >