index

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

Print this page
rev 7209 : 6979279


  63 static IntHistogram card_repeat_count(10, 10);
  64 
  65 void ct_freq_update_histo_and_reset() {
  66   for (size_t j = 0; j < ct_freq_sz; j++) {
  67     card_repeat_count.add_entry(ct_freq[j]);
  68     ct_freq[j] = 0;
  69   }
  70 
  71 }
  72 #endif
  73 
  74 G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
  75   : _g1(g1), _conc_refine_cards(0),
  76     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
  77     _cg1r(g1->concurrent_g1_refine()),
  78     _cset_rs_update_cl(NULL),
  79     _cards_scanned(NULL), _total_cards_scanned(0),
  80     _prev_period_summary()
  81 {
  82   _seq_task = new SubTasksDone(NumSeqTasks);
  83   guarantee(n_workers() > 0, "There should be some workers");
  84   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC);
  85   for (uint i = 0; i < n_workers(); i++) {
  86     _cset_rs_update_cl[i] = NULL;
  87   }
  88   if (G1SummarizeRSetStats) {
  89     _prev_period_summary.initialize(this);
  90   }
  91 }
  92 
  93 G1RemSet::~G1RemSet() {
  94   delete _seq_task;
  95   for (uint i = 0; i < n_workers(); i++) {
  96     assert(_cset_rs_update_cl[i] == NULL, "it should be");
  97   }
  98   FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC);
  99 }
 100 
 101 void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) {
 102   if (_g1->is_in_g1_reserved(mr.start())) {
 103     _n += (int) ((mr.byte_size() / CardTableModRefBS::card_size));


 265 }
 266 
 267 // Closure used for updating RSets and recording references that
 268 // point into the collection set. Only called during an
 269 // evacuation pause.
 270 
 271 class RefineRecordRefsIntoCSCardTableEntryClosure: public CardTableEntryClosure {
 272   G1RemSet* _g1rs;
 273   DirtyCardQueue* _into_cset_dcq;
 274 public:
 275   RefineRecordRefsIntoCSCardTableEntryClosure(G1CollectedHeap* g1h,
 276                                               DirtyCardQueue* into_cset_dcq) :
 277     _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq)
 278   {}
 279   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
 280     // The only time we care about recording cards that
 281     // contain references that point into the collection set
 282     // is during RSet updating within an evacuation pause.
 283     // In this case worker_i should be the id of a GC worker thread.
 284     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
 285     assert(worker_i < (ParallelGCThreads == 0 ? 1 : ParallelGCThreads), "should be a GC worker");
 286 
 287     if (_g1rs->refine_card(card_ptr, worker_i, true)) {
 288       // 'card_ptr' contains references that point into the collection
 289       // set. We need to record the card in the DCQS
 290       // (G1CollectedHeap::into_cset_dirty_card_queue_set())
 291       // that's used for that purpose.
 292       //
 293       // Enqueue the card
 294       _into_cset_dcq->enqueue(card_ptr);
 295     }
 296     return true;
 297   }
 298 };
 299 
 300 void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i) {
 301   double start = os::elapsedTime();
 302   // Apply the given closure to all remaining log entries.
 303   RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
 304 
 305   _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i);


 326 #if CARD_REPEAT_HISTO
 327   ct_freq_update_histo_and_reset();
 328 #endif
 329 
 330   // We cache the value of 'oc' closure into the appropriate slot in the
 331   // _cset_rs_update_cl for this worker
 332   assert(worker_i < n_workers(), "sanity");
 333   _cset_rs_update_cl[worker_i] = oc;
 334 
 335   // A DirtyCardQueue that is used to hold cards containing references
 336   // that point into the collection set. This DCQ is associated with a
 337   // special DirtyCardQueueSet (see g1CollectedHeap.hpp).  Under normal
 338   // circumstances (i.e. the pause successfully completes), these cards
 339   // are just discarded (there's no need to update the RSets of regions
 340   // that were in the collection set - after the pause these regions
 341   // are wholly 'free' of live objects. In the event of an evacuation
 342   // failure the cards/buffers in this queue set are passed to the
 343   // DirtyCardQueueSet that is used to manage RSet updates
 344   DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
 345 
 346   assert((ParallelGCThreads > 0) || worker_i == 0, "invariant");
 347 
 348   updateRS(&into_cset_dcq, worker_i);
 349   scanRS(oc, code_root_cl, worker_i);
 350 
 351   // We now clear the cached values of _cset_rs_update_cl for this worker
 352   _cset_rs_update_cl[worker_i] = NULL;
 353 }
 354 
 355 void G1RemSet::prepare_for_oops_into_collection_set_do() {
 356   cleanupHRRS();
 357   _g1->set_refine_cte_cl_concurrency(false);
 358   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 359   dcqs.concatenate_logs();
 360 
 361   guarantee( _cards_scanned == NULL, "invariant" );
 362   _cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers(), mtGC);
 363   for (uint i = 0; i < n_workers(); ++i) {
 364     _cards_scanned[i] = 0;
 365   }
 366   _total_cards_scanned = 0;
 367 }


 403 
 404 class ScrubRSClosure: public HeapRegionClosure {
 405   G1CollectedHeap* _g1h;
 406   BitMap* _region_bm;
 407   BitMap* _card_bm;
 408   CardTableModRefBS* _ctbs;
 409 public:
 410   ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
 411     _g1h(G1CollectedHeap::heap()),
 412     _region_bm(region_bm), _card_bm(card_bm),
 413     _ctbs(_g1h->g1_barrier_set()) {}
 414 
 415   bool doHeapRegion(HeapRegion* r) {
 416     if (!r->is_continues_humongous()) {
 417       r->rem_set()->scrub(_ctbs, _region_bm, _card_bm);
 418     }
 419     return false;
 420   }
 421 };
 422 
 423 void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm) {
 424   ScrubRSClosure scrub_cl(region_bm, card_bm);
 425   _g1->heap_region_iterate(&scrub_cl);
 426 }
 427 
 428 void G1RemSet::scrub_par(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
 429   ScrubRSClosure scrub_cl(region_bm, card_bm);
 430   _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
 431 }
 432 
 433 G1TriggerClosure::G1TriggerClosure() :
 434   _triggered(false) { }
 435 
 436 G1InvokeIfNotTriggeredClosure::G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t_cl,
 437                                                              OopClosure* oop_cl)  :
 438   _trigger_cl(t_cl), _oop_cl(oop_cl) { }
 439 
 440 G1Mux2Closure::G1Mux2Closure(OopClosure *c1, OopClosure *c2) :
 441   _c1(c1), _c2(c2) { }
 442 
 443 G1UpdateRSOrPushRefOopClosure::
 444 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
 445                               G1RemSet* rs,
 446                               OopsInHeapRegionClosure* push_ref_cl,
 447                               bool record_refs_into_cset,
 448                               uint worker_i) :




  63 static IntHistogram card_repeat_count(10, 10);
  64 
  65 void ct_freq_update_histo_and_reset() {
  66   for (size_t j = 0; j < ct_freq_sz; j++) {
  67     card_repeat_count.add_entry(ct_freq[j]);
  68     ct_freq[j] = 0;
  69   }
  70 
  71 }
  72 #endif
  73 
  74 G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
  75   : _g1(g1), _conc_refine_cards(0),
  76     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
  77     _cg1r(g1->concurrent_g1_refine()),
  78     _cset_rs_update_cl(NULL),
  79     _cards_scanned(NULL), _total_cards_scanned(0),
  80     _prev_period_summary()
  81 {
  82   _seq_task = new SubTasksDone(NumSeqTasks);

  83   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC);
  84   for (uint i = 0; i < n_workers(); i++) {
  85     _cset_rs_update_cl[i] = NULL;
  86   }
  87   if (G1SummarizeRSetStats) {
  88     _prev_period_summary.initialize(this);
  89   }
  90 }
  91 
  92 G1RemSet::~G1RemSet() {
  93   delete _seq_task;
  94   for (uint i = 0; i < n_workers(); i++) {
  95     assert(_cset_rs_update_cl[i] == NULL, "it should be");
  96   }
  97   FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC);
  98 }
  99 
 100 void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) {
 101   if (_g1->is_in_g1_reserved(mr.start())) {
 102     _n += (int) ((mr.byte_size() / CardTableModRefBS::card_size));


 264 }
 265 
 266 // Closure used for updating RSets and recording references that
 267 // point into the collection set. Only called during an
 268 // evacuation pause.
 269 
 270 class RefineRecordRefsIntoCSCardTableEntryClosure: public CardTableEntryClosure {
 271   G1RemSet* _g1rs;
 272   DirtyCardQueue* _into_cset_dcq;
 273 public:
 274   RefineRecordRefsIntoCSCardTableEntryClosure(G1CollectedHeap* g1h,
 275                                               DirtyCardQueue* into_cset_dcq) :
 276     _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq)
 277   {}
 278   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
 279     // The only time we care about recording cards that
 280     // contain references that point into the collection set
 281     // is during RSet updating within an evacuation pause.
 282     // In this case worker_i should be the id of a GC worker thread.
 283     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
 284     assert(worker_i < ParallelGCThreads, "should be a GC worker");
 285 
 286     if (_g1rs->refine_card(card_ptr, worker_i, true)) {
 287       // 'card_ptr' contains references that point into the collection
 288       // set. We need to record the card in the DCQS
 289       // (G1CollectedHeap::into_cset_dirty_card_queue_set())
 290       // that's used for that purpose.
 291       //
 292       // Enqueue the card
 293       _into_cset_dcq->enqueue(card_ptr);
 294     }
 295     return true;
 296   }
 297 };
 298 
 299 void G1RemSet::updateRS(DirtyCardQueue* into_cset_dcq, uint worker_i) {
 300   double start = os::elapsedTime();
 301   // Apply the given closure to all remaining log entries.
 302   RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq);
 303 
 304   _g1->iterate_dirty_card_closure(&into_cset_update_rs_cl, into_cset_dcq, false, worker_i);


 325 #if CARD_REPEAT_HISTO
 326   ct_freq_update_histo_and_reset();
 327 #endif
 328 
 329   // We cache the value of 'oc' closure into the appropriate slot in the
 330   // _cset_rs_update_cl for this worker
 331   assert(worker_i < n_workers(), "sanity");
 332   _cset_rs_update_cl[worker_i] = oc;
 333 
 334   // A DirtyCardQueue that is used to hold cards containing references
 335   // that point into the collection set. This DCQ is associated with a
 336   // special DirtyCardQueueSet (see g1CollectedHeap.hpp).  Under normal
 337   // circumstances (i.e. the pause successfully completes), these cards
 338   // are just discarded (there's no need to update the RSets of regions
 339   // that were in the collection set - after the pause these regions
 340   // are wholly 'free' of live objects. In the event of an evacuation
 341   // failure the cards/buffers in this queue set are passed to the
 342   // DirtyCardQueueSet that is used to manage RSet updates
 343   DirtyCardQueue into_cset_dcq(&_g1->into_cset_dirty_card_queue_set());
 344 


 345   updateRS(&into_cset_dcq, worker_i);
 346   scanRS(oc, code_root_cl, worker_i);
 347 
 348   // We now clear the cached values of _cset_rs_update_cl for this worker
 349   _cset_rs_update_cl[worker_i] = NULL;
 350 }
 351 
 352 void G1RemSet::prepare_for_oops_into_collection_set_do() {
 353   cleanupHRRS();
 354   _g1->set_refine_cte_cl_concurrency(false);
 355   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 356   dcqs.concatenate_logs();
 357 
 358   guarantee( _cards_scanned == NULL, "invariant" );
 359   _cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers(), mtGC);
 360   for (uint i = 0; i < n_workers(); ++i) {
 361     _cards_scanned[i] = 0;
 362   }
 363   _total_cards_scanned = 0;
 364 }


 400 
 401 class ScrubRSClosure: public HeapRegionClosure {
 402   G1CollectedHeap* _g1h;
 403   BitMap* _region_bm;
 404   BitMap* _card_bm;
 405   CardTableModRefBS* _ctbs;
 406 public:
 407   ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
 408     _g1h(G1CollectedHeap::heap()),
 409     _region_bm(region_bm), _card_bm(card_bm),
 410     _ctbs(_g1h->g1_barrier_set()) {}
 411 
 412   bool doHeapRegion(HeapRegion* r) {
 413     if (!r->is_continues_humongous()) {
 414       r->rem_set()->scrub(_ctbs, _region_bm, _card_bm);
 415     }
 416     return false;
 417   }
 418 };
 419 
 420 void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {





 421   ScrubRSClosure scrub_cl(region_bm, card_bm);
 422   _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
 423 }
 424 
 425 G1TriggerClosure::G1TriggerClosure() :
 426   _triggered(false) { }
 427 
 428 G1InvokeIfNotTriggeredClosure::G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t_cl,
 429                                                              OopClosure* oop_cl)  :
 430   _trigger_cl(t_cl), _oop_cl(oop_cl) { }
 431 
 432 G1Mux2Closure::G1Mux2Closure(OopClosure *c1, OopClosure *c2) :
 433   _c1(c1), _c2(c2) { }
 434 
 435 G1UpdateRSOrPushRefOopClosure::
 436 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
 437                               G1RemSet* rs,
 438                               OopsInHeapRegionClosure* push_ref_cl,
 439                               bool record_refs_into_cset,
 440                               uint worker_i) :


index