< prev index next >

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

Print this page




 299   return G1DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads() + MAX2(ConcGCThreads, ParallelGCThreads);
 300 }
 301 
 302 void G1RemSet::initialize(size_t capacity, uint max_regions) {
 303   G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
 304   _scan_state->initialize(max_regions);
 305 }
 306 
 307 G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
 308                                                    G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
 309                                                    G1ParScanThreadState* pss,
 310                                                    G1GCPhaseTimes::GCParPhases phase,
 311                                                    uint worker_i) :
 312   _g1h(G1CollectedHeap::heap()),
 313   _ct(_g1h->card_table()),
 314   _pss(pss),
 315   _scan_objs_on_card_cl(scan_obj_on_card),
 316   _scan_state(scan_state),
 317   _phase(phase),
 318   _worker_i(worker_i),
 319   _opt_refs_scanned(0),
 320   _opt_refs_memory_used(0),
 321   _cards_scanned(0),
 322   _cards_claimed(0),
 323   _cards_skipped(0),
 324   _rem_set_root_scan_time(),
 325   _rem_set_trim_partially_time(),
 326   _strong_code_root_scan_time(),
 327   _strong_code_trim_partially_time() {
 328 }
 329 
 330 void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
 331   _ct->set_card_claimed(card_index);
 332   _scan_state->add_dirty_region(region_idx_for_card);
 333 }
 334 
 335 void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
 336   HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
 337   assert(!card_region->is_young(), "Should not scan card in young region %u", region_idx_for_card);
 338   card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
 339   _scan_objs_on_card_cl->trim_queue_partially();
 340   _cards_scanned++;
 341 }
 342 
 343 void G1ScanRSForRegionClosure::scan_opt_rem_set_roots(HeapRegion* r) {
 344   EventGCPhaseParallel event;
 345 
 346   G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region(r);
 347 
 348   G1ScanObjsDuringScanRSClosure scan_cl(_g1h, _pss);
 349   G1ScanRSForOptionalClosure cl(&scan_cl);
 350   _opt_refs_scanned += opt_rem_set_list->oops_do(&cl, _pss->closures()->raw_strong_oops());
 351   _opt_refs_memory_used += opt_rem_set_list->used_memory();
 352 
 353   event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
 354 }
 355 
 356 void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {
 357   EventGCPhaseParallel event;
 358   uint const region_idx = r->hrm_index();
 359 
 360   if (_scan_state->claim_iter(region_idx)) {
 361     // If we ever free the collection set concurrently, we should also
 362     // clear the card table concurrently therefore we won't need to
 363     // add regions of the collection set to the dirty cards region.
 364     _scan_state->add_dirty_region(region_idx);
 365   }
 366 
 367   if (r->rem_set()->cardset_is_empty()) {
 368     return;
 369   }
 370 
 371   // We claim cards in blocks so as to reduce the contention.
 372   size_t const block_size = G1RSetScanBlockSize;
 373 
 374   HeapRegionRemSetIterator iter(r->rem_set());
 375   size_t card_index;


 412     claim_card(card_index, region_idx_for_card);
 413 
 414     MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
 415 
 416     scan_card(mr, region_idx_for_card);
 417   }
 418   event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
 419 }
 420 
 421 void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
 422   EventGCPhaseParallel event;
 423   // We pass a weak code blobs closure to the remembered set scanning because we want to avoid
 424   // treating the nmethods visited to act as roots for concurrent marking.
 425   // We only want to make sure that the oops in the nmethods are adjusted with regard to the
 426   // objects copied by the current evacuation.
 427   r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
 428   event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::CodeRoots));
 429 }
 430 
 431 bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
 432   assert(r->in_collection_set(), "Region %u is not in the collection set.", r->hrm_index());


 433   uint const region_idx = r->hrm_index();
 434 
 435   // The individual references for the optional remembered set are per-worker, so we
 436   // always need to scan them.
 437   if (r->has_index_in_opt_cset()) {
 438     G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
 439     scan_opt_rem_set_roots(r);
 440   }
 441 
 442   // Do an early out if we know we are complete.
 443   if (_scan_state->iter_is_complete(region_idx)) {
 444     return false;
 445   }
 446 
 447   {
 448     G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
 449     scan_rem_set_roots(r);
 450   }
 451 
 452   if (_scan_state->set_iter_complete(region_idx)) {
 453     G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time);
 454     // Scan the strong code root list attached to the current region
 455     scan_strong_code_roots(r);
 456   }
 457   return false;
 458 }
 459 
 460 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
 461                             uint worker_i,
 462                             G1GCPhaseTimes::GCParPhases scan_phase,
 463                             G1GCPhaseTimes::GCParPhases objcopy_phase,
 464                             G1GCPhaseTimes::GCParPhases coderoots_phase) {
 465   assert(pss->trim_ticks().value() == 0, "Queues must have been trimmed before entering.");
 466 
 467   G1ScanObjsDuringScanRSClosure scan_cl(_g1h, pss);
 468   G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, pss, scan_phase, worker_i);
 469   _g1h->collection_set_iterate_increment_from(&cl, worker_i);
 470 
 471   G1GCPhaseTimes* p = _g1p->phase_times();
 472 
 473   p->record_or_add_time_secs(objcopy_phase, worker_i, cl.rem_set_trim_partially_time().seconds());

 474 
 475   p->record_or_add_time_secs(scan_phase, worker_i, cl.rem_set_root_scan_time().seconds());
 476   p->record_or_add_thread_work_item(scan_phase, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
 477   p->record_or_add_thread_work_item(scan_phase, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
 478   p->record_or_add_thread_work_item(scan_phase, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
 479   // At this time we only record some metrics for the optional remembered set.
 480   if (scan_phase == G1GCPhaseTimes::OptScanRS) {
 481     p->record_or_add_thread_work_item(scan_phase, worker_i, cl.opt_refs_scanned(), G1GCPhaseTimes::ScanRSScannedOptRefs);
 482     p->record_or_add_thread_work_item(scan_phase, worker_i, cl.opt_refs_memory_used(), G1GCPhaseTimes::ScanRSUsedMemory);
 483   }
 484 
 485   p->record_or_add_time_secs(coderoots_phase, worker_i, cl.strong_code_root_scan_time().seconds());
 486   p->add_time_secs(objcopy_phase, worker_i, cl.strong_code_root_trim_partially_time().seconds());
 487 }
 488 
 489 // Closure used for updating rem sets. Only called during an evacuation pause.
 490 class G1RefineCardClosure: public G1CardTableEntryClosure {
 491   G1RemSet* _g1rs;
 492   G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
 493 
 494   size_t _cards_scanned;
 495   size_t _cards_skipped;
 496 public:
 497   G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
 498     _g1rs(g1h->rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
 499   {}
 500 
 501   bool do_card_ptr(CardValue* card_ptr, uint worker_i) {
 502     // The only time we care about recording cards that
 503     // contain references that point into the collection set
 504     // is during RSet updating within an evacuation pause.
 505     // In this case worker_i should be the id of a GC worker thread.
 506     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");


 526   // Apply closure to log entries in the HCC.
 527   if (G1HotCardCache::default_use_cache()) {
 528     G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::ScanHCC, worker_i);
 529 
 530     G1ScanObjsDuringUpdateRSClosure scan_hcc_cl(_g1h, pss);
 531     G1RefineCardClosure refine_card_cl(_g1h, &scan_hcc_cl);
 532     _g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
 533   }
 534 
 535   // Now apply the closure to all remaining log entries.
 536   {
 537     G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::UpdateRS, worker_i);
 538 
 539     G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1h, pss);
 540     G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
 541     _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
 542 
 543     p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
 544     p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
 545   }





 546 }
 547 
 548 void G1RemSet::prepare_for_oops_into_collection_set_do() {
 549   G1BarrierSet::dirty_card_queue_set().concatenate_logs();
 550   _scan_state->reset();
 551 }
 552 
 553 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
 554   G1GCPhaseTimes* phase_times = _g1h->phase_times();
 555 
 556   // Set all cards back to clean.
 557   double start = os::elapsedTime();
 558   _scan_state->clear_card_table(_g1h->workers());
 559   phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
 560 }
 561 
 562 inline void check_card_ptr(CardTable::CardValue* card_ptr, G1CardTable* ct) {
 563 #ifdef ASSERT
 564   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 565   assert(g1h->is_in_exact(ct->addr_for(card_ptr)),




 299   return G1DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads() + MAX2(ConcGCThreads, ParallelGCThreads);
 300 }
 301 
 302 void G1RemSet::initialize(size_t capacity, uint max_regions) {
 303   G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
 304   _scan_state->initialize(max_regions);
 305 }
 306 
 307 G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
 308                                                    G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
 309                                                    G1ParScanThreadState* pss,
 310                                                    G1GCPhaseTimes::GCParPhases phase,
 311                                                    uint worker_i) :
 312   _g1h(G1CollectedHeap::heap()),
 313   _ct(_g1h->card_table()),
 314   _pss(pss),
 315   _scan_objs_on_card_cl(scan_obj_on_card),
 316   _scan_state(scan_state),
 317   _phase(phase),
 318   _worker_i(worker_i),


 319   _cards_scanned(0),
 320   _cards_claimed(0),
 321   _cards_skipped(0),
 322   _rem_set_root_scan_time(),
 323   _rem_set_trim_partially_time(),
 324   _strong_code_root_scan_time(),
 325   _strong_code_trim_partially_time() {
 326 }
 327 
 328 void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
 329   _ct->set_card_claimed(card_index);
 330   _scan_state->add_dirty_region(region_idx_for_card);
 331 }
 332 
 333 void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
 334   HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
 335   assert(!card_region->is_young(), "Should not scan card in young region %u", region_idx_for_card);
 336   card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
 337   _scan_objs_on_card_cl->trim_queue_partially();
 338   _cards_scanned++;
 339 }
 340 













 341 void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {
 342   EventGCPhaseParallel event;
 343   uint const region_idx = r->hrm_index();
 344 
 345   if (_scan_state->claim_iter(region_idx)) {
 346     // If we ever free the collection set concurrently, we should also
 347     // clear the card table concurrently therefore we won't need to
 348     // add regions of the collection set to the dirty cards region.
 349     _scan_state->add_dirty_region(region_idx);
 350   }
 351 
 352   if (r->rem_set()->cardset_is_empty()) {
 353     return;
 354   }
 355 
 356   // We claim cards in blocks so as to reduce the contention.
 357   size_t const block_size = G1RSetScanBlockSize;
 358 
 359   HeapRegionRemSetIterator iter(r->rem_set());
 360   size_t card_index;


 397     claim_card(card_index, region_idx_for_card);
 398 
 399     MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
 400 
 401     scan_card(mr, region_idx_for_card);
 402   }
 403   event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(_phase));
 404 }
 405 
 406 void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
 407   EventGCPhaseParallel event;
 408   // We pass a weak code blobs closure to the remembered set scanning because we want to avoid
 409   // treating the nmethods visited to act as roots for concurrent marking.
 410   // We only want to make sure that the oops in the nmethods are adjusted with regard to the
 411   // objects copied by the current evacuation.
 412   r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
 413   event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::CodeRoots));
 414 }
 415 
 416 bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
 417   assert(r->in_collection_set(),
 418          "Should only be called on elements of the collection set but region %u is not.",
 419          r->hrm_index());
 420   uint const region_idx = r->hrm_index();
 421 







 422   // Do an early out if we know we are complete.
 423   if (_scan_state->iter_is_complete(region_idx)) {
 424     return false;
 425   }
 426 
 427   {
 428     G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
 429     scan_rem_set_roots(r);
 430   }
 431 
 432   if (_scan_state->set_iter_complete(region_idx)) {
 433     G1EvacPhaseWithTrimTimeTracker timer(_pss, _strong_code_root_scan_time, _strong_code_trim_partially_time);
 434     // Scan the strong code root list attached to the current region
 435     scan_strong_code_roots(r);
 436   }
 437   return false;
 438 }
 439 
 440 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss, uint worker_i) {






 441   G1ScanObjsDuringScanRSClosure scan_cl(_g1h, pss);
 442   G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, pss, G1GCPhaseTimes::ScanRS, worker_i);
 443   _g1h->collection_set_iterate_from(&cl, worker_i);
 444 
 445   G1GCPhaseTimes* p = _g1p->phase_times();
 446 
 447   p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, cl.rem_set_root_scan_time().seconds());
 448   p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, cl.rem_set_trim_partially_time().seconds());
 449 
 450   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
 451   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
 452   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);






 453 
 454   p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time().seconds());
 455   p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, cl.strong_code_root_trim_partially_time().seconds());
 456 }
 457 
 458 // Closure used for updating rem sets. Only called during an evacuation pause.
 459 class G1RefineCardClosure: public G1CardTableEntryClosure {
 460   G1RemSet* _g1rs;
 461   G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
 462 
 463   size_t _cards_scanned;
 464   size_t _cards_skipped;
 465 public:
 466   G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
 467     _g1rs(g1h->rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
 468   {}
 469 
 470   bool do_card_ptr(CardValue* card_ptr, uint worker_i) {
 471     // The only time we care about recording cards that
 472     // contain references that point into the collection set
 473     // is during RSet updating within an evacuation pause.
 474     // In this case worker_i should be the id of a GC worker thread.
 475     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");


 495   // Apply closure to log entries in the HCC.
 496   if (G1HotCardCache::default_use_cache()) {
 497     G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::ScanHCC, worker_i);
 498 
 499     G1ScanObjsDuringUpdateRSClosure scan_hcc_cl(_g1h, pss);
 500     G1RefineCardClosure refine_card_cl(_g1h, &scan_hcc_cl);
 501     _g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
 502   }
 503 
 504   // Now apply the closure to all remaining log entries.
 505   {
 506     G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::UpdateRS, worker_i);
 507 
 508     G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1h, pss);
 509     G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
 510     _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
 511 
 512     p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
 513     p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
 514   }
 515 }
 516 
 517 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss, uint worker_i) {
 518   update_rem_set(pss, worker_i);
 519   scan_rem_set(pss, worker_i);;
 520 }
 521 
 522 void G1RemSet::prepare_for_oops_into_collection_set_do() {
 523   G1BarrierSet::dirty_card_queue_set().concatenate_logs();
 524   _scan_state->reset();
 525 }
 526 
 527 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
 528   G1GCPhaseTimes* phase_times = _g1h->phase_times();
 529 
 530   // Set all cards back to clean.
 531   double start = os::elapsedTime();
 532   _scan_state->clear_card_table(_g1h->workers());
 533   phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
 534 }
 535 
 536 inline void check_card_ptr(CardTable::CardValue* card_ptr, G1CardTable* ct) {
 537 #ifdef ASSERT
 538   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 539   assert(g1h->is_in_exact(ct->addr_for(card_ptr)),


< prev index next >