217 // Then thread t will start at region t * floor (n/p)
218
219 HeapRegion* G1RemSet::calculateStartRegion(int worker_i) {
220 HeapRegion* result = _g1p->collection_set();
221 if (ParallelGCThreads > 0) {
222 size_t cs_size = _g1p->collection_set_size();
223 int n_workers = _g1->workers()->total_workers();
224 size_t cs_spans = cs_size / n_workers;
225 size_t ind = cs_spans * worker_i;
226 for (size_t i = 0; i < ind; i++)
227 result = result->next_in_collection_set();
228 }
229 return result;
230 }
231
232 void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
233 double rs_time_start = os::elapsedTime();
234 HeapRegion *startRegion = calculateStartRegion(worker_i);
235
236 ScanRSClosure scanRScl(oc, worker_i);
237 _g1->collection_set_iterate_from(startRegion, &scanRScl);
238 scanRScl.set_try_claimed();
239 _g1->collection_set_iterate_from(startRegion, &scanRScl);
240
241 double scan_rs_time_sec = os::elapsedTime() - rs_time_start;
242
243 assert( _cards_scanned != NULL, "invariant" );
244 _cards_scanned[worker_i] = scanRScl.cards_done();
245
246 _g1p->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
247 }
248
249 // Closure used for updating RSets and recording references that
250 // point into the collection set. Only called during an
251 // evacuation pause.
252
253 class RefineRecordRefsIntoCSCardTableEntryClosure: public CardTableEntryClosure {
254 G1RemSet* _g1rs;
255 DirtyCardQueue* _into_cset_dcq;
256 public:
266 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
267 assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
268
269 if (_g1rs->concurrentRefineOneCard(card_ptr, worker_i, true)) {
270 // 'card_ptr' contains references that point into the collection
271 // set. We need to record the card in the DCQS
272 // (G1CollectedHeap::into_cset_dirty_card_queue_set())
273 // that's used for that purpose.
274 //
275 // Enqueue the card
276 _into_cset_dcq->enqueue(card_ptr);
277 }
278 return true;
279 }
280 };
281
282 void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) {
283 double start = os::elapsedTime();
284 // Apply the given closure to all remaining log entries.
285 RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
286 _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i);
287
288 // Now there should be no dirty cards.
289 if (G1RSLogCheckCardTable) {
290 CountNonCleanMemRegionClosure cl(_g1);
291 _ct_bs->mod_card_iterate(&cl);
292 // XXX This isn't true any more: keeping cards of young regions
293 // marked dirty broke it. Need some reasonable fix.
294 guarantee(cl.n() == 0, "Card table should be clean.");
295 }
296
297 _g1p->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
298 }
299
300 class CountRSSizeClosure: public HeapRegionClosure {
301 size_t _n;
302 size_t _tot;
303 size_t _max;
304 HeapRegion* _max_r;
305 enum {
449 G1CollectedHeap* _g1;
450 CardTableModRefBS* _ct_bs;
451 public:
452 UpdateRSetCardTableEntryIntoCSetClosure(G1CollectedHeap* g1,
453 CardTableModRefBS* bs):
454 _g1(g1), _ct_bs(bs)
455 { }
456
457 bool do_card_ptr(jbyte* card_ptr, int worker_i) {
458 // Construct the region representing the card.
459 HeapWord* start = _ct_bs->addr_for(card_ptr);
460 // And find the region containing it.
461 HeapRegion* r = _g1->heap_region_containing(start);
462 assert(r != NULL, "unexpected null");
463
464 // Scan oops in the card looking for references into the collection set
465 HeapWord* end = _ct_bs->addr_for(card_ptr + 1);
466 MemRegion scanRegion(start, end);
467
468 UpdateRSetImmediate update_rs_cl(_g1->g1_rem_set());
469 FilterIntoCSClosure update_rs_cset_oop_cl(NULL, _g1, &update_rs_cl);
470 FilterOutOfRegionClosure filter_then_update_rs_cset_oop_cl(r, &update_rs_cset_oop_cl);
471
472 // We can pass false as the "filter_young" parameter here as:
473 // * we should be in a STW pause,
474 // * the DCQS to which this closure is applied is used to hold
475 // references that point into the collection set from the prior
476 // RSet updating,
477 // * the post-write barrier shouldn't be logging updates to young
478 // regions (but there is a situation where this can happen - see
479 // the comment in G1RemSet::concurrentRefineOneCard below -
480 // that should not be applicable here), and
481 // * during actual RSet updating, the filtering of cards in young
482 // regions in HeapRegion::oops_on_card_seq_iterate_careful is
483 // employed.
484 // As a result, when this closure is applied to "refs into cset"
485 // DCQS, we shouldn't see any cards in young regions.
486 update_rs_cl.set_region(r);
487 HeapWord* stop_point =
488 r->oops_on_card_seq_iterate_careful(scanRegion,
489 &filter_then_update_rs_cset_oop_cl,
625 HeapRegion* r = _g1->heap_region_containing(start);
626 assert(r != NULL, "unexpected null");
627
628 HeapWord* end = _ct_bs->addr_for(card_ptr + 1);
629 MemRegion dirtyRegion(start, end);
630
631 #if CARD_REPEAT_HISTO
632 init_ct_freq_table(_g1->max_capacity());
633 ct_freq_note_card(_ct_bs->index_for(start));
634 #endif
635
636 assert(!check_for_refs_into_cset || _cset_rs_update_cl[worker_i] != NULL, "sanity");
637 UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1,
638 _g1->g1_rem_set(),
639 _cset_rs_update_cl[worker_i],
640 check_for_refs_into_cset,
641 worker_i);
642 update_rs_oop_cl.set_from(r);
643
644 TriggerClosure trigger_cl;
645 FilterIntoCSClosure into_cs_cl(NULL, _g1, &trigger_cl);
646 InvokeIfNotTriggeredClosure invoke_cl(&trigger_cl, &into_cs_cl);
647 Mux2Closure mux(&invoke_cl, &update_rs_oop_cl);
648
649 FilterOutOfRegionClosure filter_then_update_rs_oop_cl(r,
650 (check_for_refs_into_cset ?
651 (OopClosure*)&mux :
652 (OopClosure*)&update_rs_oop_cl));
653
654 // The region for the current card may be a young region. The
655 // current card may have been a card that was evicted from the
656 // card cache. When the card was inserted into the cache, we had
657 // determined that its region was non-young. While in the cache,
658 // the region may have been freed during a cleanup pause, reallocated
659 // and tagged as young.
660 //
661 // We wish to filter out cards for such a region but the current
662 // thread, if we're running concurrently, may "see" the young type
663 // change at any time (so an earlier "is_young" check may pass or
664 // fail arbitrarily). We tell the iteration code to perform this
665 // filtering when it has been determined that there has been an actual
|
217 // Then thread t will start at region t * floor (n/p)
218
219 HeapRegion* G1RemSet::calculateStartRegion(int worker_i) {
220 HeapRegion* result = _g1p->collection_set();
221 if (ParallelGCThreads > 0) {
222 size_t cs_size = _g1p->collection_set_size();
223 int n_workers = _g1->workers()->total_workers();
224 size_t cs_spans = cs_size / n_workers;
225 size_t ind = cs_spans * worker_i;
226 for (size_t i = 0; i < ind; i++)
227 result = result->next_in_collection_set();
228 }
229 return result;
230 }
231
232 void G1RemSet::scanRS(OopsInHeapRegionClosure* oc, int worker_i) {
233 double rs_time_start = os::elapsedTime();
234 HeapRegion *startRegion = calculateStartRegion(worker_i);
235
236 ScanRSClosure scanRScl(oc, worker_i);
237
238 _g1->collection_set_iterate_from(startRegion, &scanRScl);
239 scanRScl.set_try_claimed();
240 _g1->collection_set_iterate_from(startRegion, &scanRScl);
241
242 double scan_rs_time_sec = os::elapsedTime() - rs_time_start;
243
244 assert( _cards_scanned != NULL, "invariant" );
245 _cards_scanned[worker_i] = scanRScl.cards_done();
246
247 _g1p->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
248 }
249
250 // Closure used for updating RSets and recording references that
251 // point into the collection set. Only called during an
252 // evacuation pause.
253
254 class RefineRecordRefsIntoCSCardTableEntryClosure: public CardTableEntryClosure {
255 G1RemSet* _g1rs;
256 DirtyCardQueue* _into_cset_dcq;
257 public:
267 assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
268 assert(worker_i < (int) (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
269
270 if (_g1rs->concurrentRefineOneCard(card_ptr, worker_i, true)) {
271 // 'card_ptr' contains references that point into the collection
272 // set. We need to record the card in the DCQS
273 // (G1CollectedHeap::into_cset_dirty_card_queue_set())
274 // that's used for that purpose.
275 //
276 // Enqueue the card
277 _into_cset_dcq->enqueue(card_ptr);
278 }
279 return true;
280 }
281 };
282
283 void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, int worker_i) {
284 double start = os::elapsedTime();
285 // Apply the given closure to all remaining log entries.
286 RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
287
288 _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i);
289
290 // Now there should be no dirty cards.
291 if (G1RSLogCheckCardTable) {
292 CountNonCleanMemRegionClosure cl(_g1);
293 _ct_bs->mod_card_iterate(&cl);
294 // XXX This isn't true any more: keeping cards of young regions
295 // marked dirty broke it. Need some reasonable fix.
296 guarantee(cl.n() == 0, "Card table should be clean.");
297 }
298
299 _g1p->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
300 }
301
302 class CountRSSizeClosure: public HeapRegionClosure {
303 size_t _n;
304 size_t _tot;
305 size_t _max;
306 HeapRegion* _max_r;
307 enum {
451 G1CollectedHeap* _g1;
452 CardTableModRefBS* _ct_bs;
453 public:
454 UpdateRSetCardTableEntryIntoCSetClosure(G1CollectedHeap* g1,
455 CardTableModRefBS* bs):
456 _g1(g1), _ct_bs(bs)
457 { }
458
459 bool do_card_ptr(jbyte* card_ptr, int worker_i) {
460 // Construct the region representing the card.
461 HeapWord* start = _ct_bs->addr_for(card_ptr);
462 // And find the region containing it.
463 HeapRegion* r = _g1->heap_region_containing(start);
464 assert(r != NULL, "unexpected null");
465
466 // Scan oops in the card looking for references into the collection set
467 HeapWord* end = _ct_bs->addr_for(card_ptr + 1);
468 MemRegion scanRegion(start, end);
469
470 UpdateRSetImmediate update_rs_cl(_g1->g1_rem_set());
471 FilterIntoCSClosure update_rs_cset_oop_cl(NULL, _g1, &update_rs_cl, NULL /* rp */);
472 FilterOutOfRegionClosure filter_then_update_rs_cset_oop_cl(r, &update_rs_cset_oop_cl);
473
474 // We can pass false as the "filter_young" parameter here as:
475 // * we should be in a STW pause,
476 // * the DCQS to which this closure is applied is used to hold
477 // references that point into the collection set from the prior
478 // RSet updating,
479 // * the post-write barrier shouldn't be logging updates to young
480 // regions (but there is a situation where this can happen - see
481 // the comment in G1RemSet::concurrentRefineOneCard below -
482 // that should not be applicable here), and
483 // * during actual RSet updating, the filtering of cards in young
484 // regions in HeapRegion::oops_on_card_seq_iterate_careful is
485 // employed.
486 // As a result, when this closure is applied to "refs into cset"
487 // DCQS, we shouldn't see any cards in young regions.
488 update_rs_cl.set_region(r);
489 HeapWord* stop_point =
490 r->oops_on_card_seq_iterate_careful(scanRegion,
491 &filter_then_update_rs_cset_oop_cl,
627 HeapRegion* r = _g1->heap_region_containing(start);
628 assert(r != NULL, "unexpected null");
629
630 HeapWord* end = _ct_bs->addr_for(card_ptr + 1);
631 MemRegion dirtyRegion(start, end);
632
633 #if CARD_REPEAT_HISTO
634 init_ct_freq_table(_g1->max_capacity());
635 ct_freq_note_card(_ct_bs->index_for(start));
636 #endif
637
638 assert(!check_for_refs_into_cset || _cset_rs_update_cl[worker_i] != NULL, "sanity");
639 UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1,
640 _g1->g1_rem_set(),
641 _cset_rs_update_cl[worker_i],
642 check_for_refs_into_cset,
643 worker_i);
644 update_rs_oop_cl.set_from(r);
645
646 TriggerClosure trigger_cl;
647 FilterIntoCSClosure into_cs_cl(NULL, _g1, &trigger_cl, NULL /* rp */);
648 InvokeIfNotTriggeredClosure invoke_cl(&trigger_cl, &into_cs_cl);
649 Mux2Closure mux(&invoke_cl, &update_rs_oop_cl);
650
651 FilterOutOfRegionClosure filter_then_update_rs_oop_cl(r,
652 (check_for_refs_into_cset ?
653 (OopClosure*)&mux :
654 (OopClosure*)&update_rs_oop_cl));
655
656 // The region for the current card may be a young region. The
657 // current card may have been a card that was evicted from the
658 // card cache. When the card was inserted into the cache, we had
659 // determined that its region was non-young. While in the cache,
660 // the region may have been freed during a cleanup pause, reallocated
661 // and tagged as young.
662 //
663 // We wish to filter out cards for such a region but the current
664 // thread, if we're running concurrently, may "see" the young type
665 // change at any time (so an earlier "is_young" check may pass or
666 // fail arbitrarily). We tell the iteration code to perform this
667 // filtering when it has been determined that there has been an actual
|