272
273 log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " "
274 "units of work for " SIZE_FORMAT " regions.",
275 cl.name(), num_workers, num_chunks, _cur_dirty_region);
276 workers->run_task(&cl, num_workers);
277
278 #ifndef PRODUCT
279 G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
280 #endif
281 }
282 };
283
284 G1RemSet::G1RemSet(G1CollectedHeap* g1h,
285 G1CardTable* ct,
286 G1HotCardCache* hot_card_cache) :
287 _scan_state(new G1RemSetScanState()),
288 _prev_period_summary(),
289 _g1h(g1h),
290 _num_conc_refined_cards(0),
291 _ct(ct),
292 _g1p(_g1h->g1_policy()),
293 _hot_card_cache(hot_card_cache) {
294 }
295
296 G1RemSet::~G1RemSet() {
297 if (_scan_state != NULL) {
298 delete _scan_state;
299 }
300 }
301
302 uint G1RemSet::num_par_rem_sets() {
303 return G1DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads() + MAX2(ConcGCThreads, ParallelGCThreads);
304 }
305
306 void G1RemSet::initialize(size_t capacity, uint max_regions) {
307 G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
308 _scan_state->initialize(max_regions);
309 }
310
311 G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
312 G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
451 p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, cl.rem_set_root_scan_time().seconds());
452 p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, cl.rem_set_trim_partially_time().seconds());
453
454 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
455 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
456 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
457
458 p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time().seconds());
459 p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, cl.strong_code_root_trim_partially_time().seconds());
460 }
461
462 // Closure used for updating rem sets. Only called during an evacuation pause.
463 class G1RefineCardClosure: public G1CardTableEntryClosure {
464 G1RemSet* _g1rs;
465 G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
466
467 size_t _cards_scanned;
468 size_t _cards_skipped;
469 public:
470 G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
471 _g1rs(g1h->g1_rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
472 {}
473
474 bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
475 // The only time we care about recording cards that
476 // contain references that point into the collection set
477 // is during RSet updating within an evacuation pause.
478 // In this case worker_i should be the id of a GC worker thread.
479 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
480
481 bool card_scanned = _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
482
483 if (card_scanned) {
484 _update_rs_cl->trim_queue_partially();
485 _cards_scanned++;
486 } else {
487 _cards_skipped++;
488 }
489 return true;
490 }
491
514 _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
515
516 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
517 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
518 }
519 }
520
521 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss, uint worker_i) {
522 update_rem_set(pss, worker_i);
523 scan_rem_set(pss, worker_i);;
524 }
525
526 void G1RemSet::prepare_for_oops_into_collection_set_do() {
527 G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
528 dcqs.concatenate_logs();
529
530 _scan_state->reset();
531 }
532
533 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
534 G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
535
536 // Set all cards back to clean.
537 double start = os::elapsedTime();
538 _scan_state->clear_card_table(_g1h->workers());
539 phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
540 }
541
542 inline void check_card_ptr(jbyte* card_ptr, G1CardTable* ct) {
543 #ifdef ASSERT
544 G1CollectedHeap* g1h = G1CollectedHeap::heap();
545 assert(g1h->is_in_exact(ct->addr_for(card_ptr)),
546 "Card at " PTR_FORMAT " index " SIZE_FORMAT " representing heap at " PTR_FORMAT " (%u) must be in committed heap",
547 p2i(card_ptr),
548 ct->index_for(ct->addr_for(card_ptr)),
549 p2i(ct->addr_for(card_ptr)),
550 g1h->addr_to_region(ct->addr_for(card_ptr)));
551 #endif
552 }
553
554 void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
|
272
273 log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " "
274 "units of work for " SIZE_FORMAT " regions.",
275 cl.name(), num_workers, num_chunks, _cur_dirty_region);
276 workers->run_task(&cl, num_workers);
277
278 #ifndef PRODUCT
279 G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
280 #endif
281 }
282 };
283
284 G1RemSet::G1RemSet(G1CollectedHeap* g1h,
285 G1CardTable* ct,
286 G1HotCardCache* hot_card_cache) :
287 _scan_state(new G1RemSetScanState()),
288 _prev_period_summary(),
289 _g1h(g1h),
290 _num_conc_refined_cards(0),
291 _ct(ct),
292 _g1p(_g1h->policy()),
293 _hot_card_cache(hot_card_cache) {
294 }
295
296 G1RemSet::~G1RemSet() {
297 if (_scan_state != NULL) {
298 delete _scan_state;
299 }
300 }
301
302 uint G1RemSet::num_par_rem_sets() {
303 return G1DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads() + MAX2(ConcGCThreads, ParallelGCThreads);
304 }
305
306 void G1RemSet::initialize(size_t capacity, uint max_regions) {
307 G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
308 _scan_state->initialize(max_regions);
309 }
310
311 G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
312 G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
451 p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, cl.rem_set_root_scan_time().seconds());
452 p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, cl.rem_set_trim_partially_time().seconds());
453
454 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScanRSScannedCards);
455 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ScanRSClaimedCards);
456 p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::ScanRSSkippedCards);
457
458 p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time().seconds());
459 p->add_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, cl.strong_code_root_trim_partially_time().seconds());
460 }
461
462 // Closure used for updating rem sets. Only called during an evacuation pause.
463 class G1RefineCardClosure: public G1CardTableEntryClosure {
464 G1RemSet* _g1rs;
465 G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
466
467 size_t _cards_scanned;
468 size_t _cards_skipped;
469 public:
470 G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
471 _g1rs(g1h->rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
472 {}
473
474 bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
475 // The only time we care about recording cards that
476 // contain references that point into the collection set
477 // is during RSet updating within an evacuation pause.
478 // In this case worker_i should be the id of a GC worker thread.
479 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
480
481 bool card_scanned = _g1rs->refine_card_during_gc(card_ptr, _update_rs_cl);
482
483 if (card_scanned) {
484 _update_rs_cl->trim_queue_partially();
485 _cards_scanned++;
486 } else {
487 _cards_skipped++;
488 }
489 return true;
490 }
491
514 _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
515
516 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_scanned(), G1GCPhaseTimes::UpdateRSScannedCards);
517 p->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, refine_card_cl.cards_skipped(), G1GCPhaseTimes::UpdateRSSkippedCards);
518 }
519 }
520
521 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss, uint worker_i) {
522 update_rem_set(pss, worker_i);
523 scan_rem_set(pss, worker_i);;
524 }
525
526 void G1RemSet::prepare_for_oops_into_collection_set_do() {
527 G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
528 dcqs.concatenate_logs();
529
530 _scan_state->reset();
531 }
532
533 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
534 G1GCPhaseTimes* phase_times = _g1h->policy()->phase_times();
535
536 // Set all cards back to clean.
537 double start = os::elapsedTime();
538 _scan_state->clear_card_table(_g1h->workers());
539 phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
540 }
541
542 inline void check_card_ptr(jbyte* card_ptr, G1CardTable* ct) {
543 #ifdef ASSERT
544 G1CollectedHeap* g1h = G1CollectedHeap::heap();
545 assert(g1h->is_in_exact(ct->addr_for(card_ptr)),
546 "Card at " PTR_FORMAT " index " SIZE_FORMAT " representing heap at " PTR_FORMAT " (%u) must be in committed heap",
547 p2i(card_ptr),
548 ct->index_for(ct->addr_for(card_ptr)),
549 p2i(ct->addr_for(card_ptr)),
550 g1h->addr_to_region(ct->addr_for(card_ptr)));
551 #endif
552 }
553
554 void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
|