< prev index next >

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

Print this page
rev 13237 : imported patch 8183226-periodic-rem-set-summary-accesses-uninitialized-stuff
rev 13238 : imported patch 8183226-eridk-sjohanss-review
rev 13239 : imported patch 8183226-eridk-review2
rev 13240 : imported patch 8183128-cleanup-refinecardtableentryclosure
rev 13241 : imported patch 8183128-erikd-review
rev 13242 : imported patch 8183539-remove-into-cset-dcqs
rev 13243 : [mq]: 8183121-add-information-about-scanned-skipped-cards-during-updaters


 413     scan_strong_code_roots(r);
 414   }
 415   return false;
 416 }
 417 
 418 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
 419                             CodeBlobClosure* heap_region_codeblobs,
 420                             uint worker_i) {
 421   double rs_time_start = os::elapsedTime();
 422 
 423   G1ScanObjsDuringScanRSClosure scan_cl(_g1, pss);
 424   G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, heap_region_codeblobs, worker_i);
 425   _g1->collection_set_iterate_from(&cl, worker_i);
 426 
 427   double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
 428                              cl.strong_code_root_scan_time_sec();
 429 
 430   G1GCPhaseTimes* p = _g1p->phase_times();
 431 
 432   p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
 433   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScannedCards);
 434   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ClaimedCards);
 435   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::SkippedCards);
 436 
 437   p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
 438 }
 439 
 440 // Closure used for updating rem sets. Only called during an evacuation pause.
 441 class G1RefineCardClosure: public CardTableEntryClosure {
 442   G1RemSet* _g1rs;
 443   G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;



 444 public:
 445   G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
 446     _g1rs(g1h->g1_rem_set()), _update_rs_cl(update_rs_cl)
 447   {}
 448 
 449   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
 450     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
 451 
 452     _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);






 453     return true;
 454   }



 455 };
 456 
 457 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
 458   G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1, pss, worker_i);
 459   G1RefineCardClosure refine_card_cl(_g1, &update_rs_cl);
 460 
 461   G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
 462   if (G1HotCardCache::default_use_cache()) {
 463     // Apply the closure to the entries of the hot card cache.
 464     G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
 465     _g1->iterate_hcc_closure(&refine_card_cl, worker_i);
 466   }
 467   // Apply the closure to all remaining log entries.
 468   _g1->iterate_dirty_card_closure(&refine_card_cl, worker_i);




 469 }
 470 
 471 void G1RemSet::cleanupHRRS() {
 472   HeapRegionRemSet::cleanup();
 473 }
 474 
 475 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
 476                                            CodeBlobClosure* heap_region_codeblobs,
 477                                            uint worker_i) {
 478   update_rem_set(pss, worker_i);
 479   scan_rem_set(pss, heap_region_codeblobs, worker_i);;
 480 }
 481 
 482 void G1RemSet::prepare_for_oops_into_collection_set_do() {
 483   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 484   dcqs.concatenate_logs();
 485 
 486   _scan_state->reset();
 487 }
 488 


 660   // part of the heap (e.g. a partially allocated object) while
 661   // processing a stale card.  Despite the card being stale, redirty
 662   // and re-enqueue, because we've already cleaned the card.  Without
 663   // this we could incorrectly discard a non-stale card.
 664   if (!card_processed) {
 665     // The card might have gotten re-dirtied and re-enqueued while we
 666     // worked.  (In fact, it's pretty likely.)
 667     if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
 668       *card_ptr = CardTableModRefBS::dirty_card_val();
 669       MutexLockerEx x(Shared_DirtyCardQ_lock,
 670                       Mutex::_no_safepoint_check_flag);
 671       DirtyCardQueue* sdcq =
 672         JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
 673       sdcq->enqueue(card_ptr);
 674     }
 675   } else {
 676     _num_conc_refined_cards++; // Unsynchronized update, only used for logging.
 677   }
 678 }
 679 
 680 void G1RemSet::refine_card_during_gc(jbyte* card_ptr,
 681                                      G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
 682   assert(_g1->is_gc_active(), "Only call during GC");
 683 
 684   check_card_ptr(card_ptr, _ct_bs);
 685 
 686   // If the card is no longer dirty, nothing to do. This covers cards that were already
 687   // scanned as parts of the remembered sets.
 688   if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
 689     return;
 690   }
 691 
 692   // During GC we can immediately clean the card since we will not re-enqueue stale
 693   // cards as we know they can be disregarded.
 694   *card_ptr = CardTableModRefBS::clean_card_val();
 695 
 696   // Construct the region representing the card.
 697   HeapWord* card_start = _ct_bs->addr_for(card_ptr);
 698   // And find the region containing it.
 699   HeapRegion* r = _g1->heap_region_containing(card_start);
 700 
 701   HeapWord* scan_limit = _scan_state->scan_top(r->hrm_index());
 702   if (scan_limit <= card_start) {
 703     // If the card starts above the area in the region containing objects to scan, skip it.
 704     return;
 705   }
 706 
 707   // Don't use addr_for(card_ptr + 1) which can ask for
 708   // a card beyond the heap.
 709   HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
 710   MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
 711   assert(!dirty_region.is_empty(), "sanity");
 712 
 713   update_rs_cl->set_region(r);
 714   bool card_processed = r->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
 715   assert(card_processed, "must be");

 716 }
 717 
 718 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
 719   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
 720       (period_count % G1SummarizeRSetStatsPeriod == 0)) {
 721 
 722     G1RemSetSummary current(this);
 723     _prev_period_summary.subtract_from(&current);
 724 
 725     Log(gc, remset) log;
 726     log.trace("%s", header);
 727     ResourceMark rm;
 728     _prev_period_summary.print_on(log.trace_stream());
 729 
 730     _prev_period_summary.set(&current);
 731   }
 732 }
 733 
 734 void G1RemSet::print_summary_info() {
 735   Log(gc, remset, exit) log;




 413     scan_strong_code_roots(r);
 414   }
 415   return false;
 416 }
 417 
 418 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
 419                             CodeBlobClosure* heap_region_codeblobs,
 420                             uint worker_i) {
 421   double rs_time_start = os::elapsedTime();
 422 
 423   G1ScanObjsDuringScanRSClosure scan_cl(_g1, pss);
 424   G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, heap_region_codeblobs, worker_i);
 425   _g1->collection_set_iterate_from(&cl, worker_i);
 426 
 427   double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
 428                              cl.strong_code_root_scan_time_sec();
 429 
 430   G1GCPhaseTimes* p = _g1p->phase_times();
 431 
 432   p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
 433   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
 434   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
 435   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
 436 
 437   p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
 438 }
 439 
 440 // Closure used for updating rem sets. Only called during an evacuation pause.
 441 class G1RefineCardClosure: public CardTableEntryClosure {
 442   G1RemSet* _g1rs;
 443   G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
 444 
 445   size_t _cards_scanned;
 446   size_t _cards_skipped;
 447 public:
 448   G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
 449     _g1rs(g1h->g1_rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
 450   {}
 451 
 452   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
 453     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
 454 
 455     bool card_scanned = _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
 456 
 457     if (card_scanned) {
 458       _cards_scanned++;
 459     } else {
 460       _cards_skipped++;
 461     }
 462     return true;
 463   }
 464 
 465   size_t cards_scanned() const { return _cards_scanned; }
 466   size_t cards_skipped() const { return _cards_skipped; }
 467 };
 468 
 469 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
 470   G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1, pss, worker_i);
 471   G1RefineCardClosure refine_card_cl(_g1, &update_rs_cl);
 472 
 473   G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
 474   if (G1HotCardCache::default_use_cache()) {
 475     // Apply the closure to the entries of the hot card cache.
 476     G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
 477     _g1->iterate_hcc_closure(&refine_card_cl, worker_i);
 478   }
 479   // Apply the closure to all remaining log entries.
 480   _g1->iterate_dirty_card_closure(&refine_card_cl, worker_i);
 481 
 482   G1GCPhaseTimes* p = _g1p->phase_times();
 483   p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
 484   p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
 485 }
 486 
 487 void G1RemSet::cleanupHRRS() {
 488   HeapRegionRemSet::cleanup();
 489 }
 490 
 491 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
 492                                            CodeBlobClosure* heap_region_codeblobs,
 493                                            uint worker_i) {
 494   update_rem_set(pss, worker_i);
 495   scan_rem_set(pss, heap_region_codeblobs, worker_i);;
 496 }
 497 
 498 void G1RemSet::prepare_for_oops_into_collection_set_do() {
 499   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 500   dcqs.concatenate_logs();
 501 
 502   _scan_state->reset();
 503 }
 504 


 676   // part of the heap (e.g. a partially allocated object) while
 677   // processing a stale card.  Despite the card being stale, redirty
 678   // and re-enqueue, because we've already cleaned the card.  Without
 679   // this we could incorrectly discard a non-stale card.
 680   if (!card_processed) {
 681     // The card might have gotten re-dirtied and re-enqueued while we
 682     // worked.  (In fact, it's pretty likely.)
 683     if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
 684       *card_ptr = CardTableModRefBS::dirty_card_val();
 685       MutexLockerEx x(Shared_DirtyCardQ_lock,
 686                       Mutex::_no_safepoint_check_flag);
 687       DirtyCardQueue* sdcq =
 688         JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
 689       sdcq->enqueue(card_ptr);
 690     }
 691   } else {
 692     _num_conc_refined_cards++; // Unsynchronized update, only used for logging.
 693   }
 694 }
 695 
 696 bool G1RemSet::refine_card_during_gc(jbyte* card_ptr,
 697                                      G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
 698   assert(_g1->is_gc_active(), "Only call during GC");
 699 
 700   check_card_ptr(card_ptr, _ct_bs);
 701 
 702   // If the card is no longer dirty, nothing to do. This covers cards that were already
 703   // scanned as parts of the remembered sets.
 704   if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
 705     return false;
 706   }
 707 
 708   // During GC we can immediately clean the card since we will not re-enqueue stale
 709   // cards as we know they can be disregarded.
 710   *card_ptr = CardTableModRefBS::clean_card_val();
 711 
 712   // Construct the region representing the card.
 713   HeapWord* card_start = _ct_bs->addr_for(card_ptr);
 714   // And find the region containing it.
 715   HeapRegion* r = _g1->heap_region_containing(card_start);
 716 
 717   HeapWord* scan_limit = _scan_state->scan_top(r->hrm_index());
 718   if (scan_limit <= card_start) {
 719     // If the card starts above the area in the region containing objects to scan, skip it.
 720     return false;
 721   }
 722 
 723   // Don't use addr_for(card_ptr + 1) which can ask for
 724   // a card beyond the heap.
 725   HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
 726   MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
 727   assert(!dirty_region.is_empty(), "sanity");
 728 
 729   update_rs_cl->set_region(r);
 730   bool card_processed = r->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
 731   assert(card_processed, "must be");
 732   return true;
 733 }
 734 
 735 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
 736   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
 737       (period_count % G1SummarizeRSetStatsPeriod == 0)) {
 738 
 739     G1RemSetSummary current(this);
 740     _prev_period_summary.subtract_from(&current);
 741 
 742     Log(gc, remset) log;
 743     log.trace("%s", header);
 744     ResourceMark rm;
 745     _prev_period_summary.print_on(log.trace_stream());
 746 
 747     _prev_period_summary.set(&current);
 748   }
 749 }
 750 
 751 void G1RemSet::print_summary_info() {
 752   Log(gc, remset, exit) log;


< prev index next >