hotspot/src/share/vm/gc/g1/g1RemSet.cpp
changeset 46778 f504c6f2eea5
parent 46701 f559541c0daa
child 46993 dd0f91c85ffc
equal deleted inserted replaced
46777:02604fd56ae4 46778:f504c6f2eea5
   427                              cl.strong_code_root_scan_time_sec();
   427                              cl.strong_code_root_scan_time_sec();
   428 
   428 
   429   G1GCPhaseTimes* p = _g1p->phase_times();
   429   G1GCPhaseTimes* p = _g1p->phase_times();
   430 
   430 
   431   p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
   431   p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
   432   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScannedCards);
   432   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
   433   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ClaimedCards);
   433   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
   434   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::SkippedCards);
   434   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
   435 
   435 
   436   p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
   436   p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
   437 }
   437 }
   438 
   438 
   439 // Closure used for updating rem sets. Only called during an evacuation pause.
   439 // Closure used for updating rem sets. Only called during an evacuation pause.
   440 class G1RefineCardClosure: public CardTableEntryClosure {
   440 class G1RefineCardClosure: public CardTableEntryClosure {
   441   G1RemSet* _g1rs;
   441   G1RemSet* _g1rs;
   442   G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
   442   G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
       
   443 
       
   444   size_t _cards_scanned;
       
   445   size_t _cards_skipped;
   443 public:
   446 public:
   444   G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
   447   G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
   445     _g1rs(g1h->g1_rem_set()), _update_rs_cl(update_rs_cl)
   448     _g1rs(g1h->g1_rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
   446   {}
   449   {}
   447 
   450 
   448   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
   451   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
   449     // The only time we care about recording cards that
   452     // The only time we care about recording cards that
   450     // contain references that point into the collection set
   453     // contain references that point into the collection set
   451     // is during RSet updating within an evacuation pause.
   454     // is during RSet updating within an evacuation pause.
   452     // In this case worker_i should be the id of a GC worker thread.
   455     // In this case worker_i should be the id of a GC worker thread.
   453     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
   456     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
   454 
   457 
   455     _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
   458     bool card_scanned = _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
       
   459 
       
   460     if (card_scanned) {
       
   461       _cards_scanned++;
       
   462     } else {
       
   463       _cards_skipped++;
       
   464     }
   456     return true;
   465     return true;
   457   }
   466   }
       
   467 
       
   468   size_t cards_scanned() const { return _cards_scanned; }
       
   469   size_t cards_skipped() const { return _cards_skipped; }
   458 };
   470 };
   459 
   471 
   460 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
   472 void G1RemSet::update_rem_set(G1ParScanThreadState* pss, uint worker_i) {
   461   G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1, pss, worker_i);
   473   G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1, pss, worker_i);
   462   G1RefineCardClosure refine_card_cl(_g1, &update_rs_cl);
   474   G1RefineCardClosure refine_card_cl(_g1, &update_rs_cl);
   467     G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
   479     G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
   468     _g1->iterate_hcc_closure(&refine_card_cl, worker_i);
   480     _g1->iterate_hcc_closure(&refine_card_cl, worker_i);
   469   }
   481   }
   470   // Apply the closure to all remaining log entries.
   482   // Apply the closure to all remaining log entries.
   471   _g1->iterate_dirty_card_closure(&refine_card_cl, worker_i);
   483   _g1->iterate_dirty_card_closure(&refine_card_cl, worker_i);
       
   484 
       
   485   G1GCPhaseTimes* p = _g1p->phase_times();
       
   486   p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
       
   487   p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
   472 }
   488 }
   473 
   489 
   474 void G1RemSet::cleanupHRRS() {
   490 void G1RemSet::cleanupHRRS() {
   475   HeapRegionRemSet::cleanup();
   491   HeapRegionRemSet::cleanup();
   476 }
   492 }
   678   } else {
   694   } else {
   679     _num_conc_refined_cards++; // Unsynchronized update, only used for logging.
   695     _num_conc_refined_cards++; // Unsynchronized update, only used for logging.
   680   }
   696   }
   681 }
   697 }
   682 
   698 
   683 void G1RemSet::refine_card_during_gc(jbyte* card_ptr,
   699 bool G1RemSet::refine_card_during_gc(jbyte* card_ptr,
   684                                      G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
   700                                      G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
   685   assert(_g1->is_gc_active(), "Only call during GC");
   701   assert(_g1->is_gc_active(), "Only call during GC");
   686 
   702 
   687   check_card_ptr(card_ptr, _ct_bs);
   703   check_card_ptr(card_ptr, _ct_bs);
   688 
   704 
   689   // If the card is no longer dirty, nothing to do. This covers cards that were already
   705   // If the card is no longer dirty, nothing to do. This covers cards that were already
   690   // scanned as parts of the remembered sets.
   706   // scanned as parts of the remembered sets.
   691   if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
   707   if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
   692     return;
   708     return false;
   693   }
   709   }
   694 
   710 
   695   // We claim lazily (so races are possible but they're benign), which reduces the
   711   // We claim lazily (so races are possible but they're benign), which reduces the
   696   // number of potential duplicate scans (multiple threads may enqueue the same card twice).
   712   // number of potential duplicate scans (multiple threads may enqueue the same card twice).
   697   *card_ptr = CardTableModRefBS::clean_card_val() | CardTableModRefBS::claimed_card_val();
   713   *card_ptr = CardTableModRefBS::clean_card_val() | CardTableModRefBS::claimed_card_val();
   703 
   719 
   704   _scan_state->add_dirty_region(card_region_idx);
   720   _scan_state->add_dirty_region(card_region_idx);
   705   HeapWord* scan_limit = _scan_state->scan_top(card_region_idx);
   721   HeapWord* scan_limit = _scan_state->scan_top(card_region_idx);
   706   if (scan_limit <= card_start) {
   722   if (scan_limit <= card_start) {
   707     // If the card starts above the area in the region containing objects to scan, skip it.
   723     // If the card starts above the area in the region containing objects to scan, skip it.
   708     return;
   724     return false;
   709   }
   725   }
   710 
   726 
   711   // Don't use addr_for(card_ptr + 1) which can ask for
   727   // Don't use addr_for(card_ptr + 1) which can ask for
   712   // a card beyond the heap.
   728   // a card beyond the heap.
   713   HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
   729   HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
   716 
   732 
   717   HeapRegion* const card_region = _g1->region_at(card_region_idx);
   733   HeapRegion* const card_region = _g1->region_at(card_region_idx);
   718   update_rs_cl->set_region(card_region);
   734   update_rs_cl->set_region(card_region);
   719   bool card_processed = card_region->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
   735   bool card_processed = card_region->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
   720   assert(card_processed, "must be");
   736   assert(card_processed, "must be");
       
   737   return true;
   721 }
   738 }
   722 
   739 
   723 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
   740 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
   724   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
   741   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
   725       (period_count % G1SummarizeRSetStatsPeriod == 0)) {
   742       (period_count % G1SummarizeRSetStatsPeriod == 0)) {