src/share/vm/gc/g1/g1RemSet.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/gc/g1

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

Print this page




 112   _oc->set_region(r);
 113   MemRegion card_region(_bot->address_for_index(index), BOTConstants::N_words);
 114   MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
 115   MemRegion mr = pre_gc_allocated.intersection(card_region);
 116   if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
 117     // We make the card as "claimed" lazily (so races are possible
 118     // but they're benign), which reduces the number of duplicate
 119     // scans (the rsets of the regions in the cset can intersect).
 120     _ct_bs->set_card_claimed(index);
 121     _cards_done++;
 122     cl.do_MemRegion(mr);
 123   }
 124 }
 125 
 126 void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
 127   double scan_start = os::elapsedTime();
 128   r->strong_code_roots_do(_code_root_cl);
 129   _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
 130 }
 131 
 132 bool ScanRSClosure::doHeapRegion(HeapRegion* r) {
 133   assert(r->in_collection_set(), "should only be called on elements of CS.");
 134   HeapRegionRemSet* hrrs = r->rem_set();
 135   if (hrrs->iter_is_complete()) return false; // All done.
 136   if (!_try_claimed && !hrrs->claim_iter()) return false;
 137   // If we ever free the collection set concurrently, we should also
 138   // clear the card table concurrently therefore we won't need to
 139   // add regions of the collection set to the dirty cards region.
 140   _g1h->push_dirty_cards_region(r);
 141   // If we didn't return above, then
 142   //   _try_claimed || r->claim_iter()
 143   // is true: either we're supposed to work on claimed-but-not-complete
 144   // regions, or we successfully claimed the region.
 145 
 146   HeapRegionRemSetIterator iter(hrrs);
 147   size_t card_index;
 148 
 149   // We claim cards in block so as to reduce the contention. The block size is determined by
 150   // the G1RSetScanBlockSize parameter.
 151   size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
 152   for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
 153     if (current_card >= jump_to_card + _block_size) {
 154       jump_to_card = hrrs->iter_claimed_next(_block_size);
 155     }
 156     if (current_card < jump_to_card) continue;


 158 
 159     HeapRegion* card_region = _g1h->heap_region_containing(card_start);
 160     _cards++;
 161 
 162     if (!card_region->is_on_dirty_cards_region_list()) {
 163       _g1h->push_dirty_cards_region(card_region);
 164     }
 165 
 166     // If the card is dirty, then we will scan it during updateRS.
 167     if (!card_region->in_collection_set() &&
 168         !_ct_bs->is_card_dirty(card_index)) {
 169       scanCard(card_index, card_region);
 170     }
 171   }
 172   if (!_try_claimed) {
 173     // Scan the strong code root list attached to the current region
 174     scan_strong_code_roots(r);
 175 
 176     hrrs->set_iter_complete();
 177   }
 178   return false;
 179 }
 180 
 181 size_t G1RemSet::scanRS(G1ParPushHeapRSClosure* oc,
 182                         CodeBlobClosure* heap_region_codeblobs,
 183                         uint worker_i) {
 184   double rs_time_start = os::elapsedTime();
 185 
 186   HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i);
 187 
 188   ScanRSClosure scanRScl(oc, heap_region_codeblobs, worker_i);
 189 
 190   _g1->collection_set_iterate_from(startRegion, &scanRScl);
 191   scanRScl.set_try_claimed();
 192   _g1->collection_set_iterate_from(startRegion, &scanRScl);
 193 
 194   double scan_rs_time_sec = (os::elapsedTime() - rs_time_start)
 195                             - scanRScl.strong_code_root_scan_time_sec();
 196 
 197   _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
 198   _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, scanRScl.strong_code_root_scan_time_sec());


 305 
 306   // Free any completed buffers in the DirtyCardQueueSet used to hold cards
 307   // which contain references that point into the collection.
 308   _into_cset_dirty_card_queue_set.clear();
 309   assert(_into_cset_dirty_card_queue_set.completed_buffers_num() == 0,
 310          "all buffers should be freed");
 311   _into_cset_dirty_card_queue_set.clear_n_completed_buffers();
 312 }
 313 
 314 class ScrubRSClosure: public HeapRegionClosure {
 315   G1CollectedHeap* _g1h;
 316   BitMap* _region_bm;
 317   BitMap* _card_bm;
 318   CardTableModRefBS* _ctbs;
 319 public:
 320   ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
 321     _g1h(G1CollectedHeap::heap()),
 322     _region_bm(region_bm), _card_bm(card_bm),
 323     _ctbs(_g1h->g1_barrier_set()) {}
 324 
 325   bool doHeapRegion(HeapRegion* r) {
 326     if (!r->is_continues_humongous()) {
 327       r->rem_set()->scrub(_ctbs, _region_bm, _card_bm);
 328     }
 329     return false;
 330   }
 331 };
 332 
 333 void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
 334   ScrubRSClosure scrub_cl(region_bm, card_bm);
 335   _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
 336 }
 337 
 338 G1TriggerClosure::G1TriggerClosure() :
 339   _triggered(false) { }
 340 
 341 G1InvokeIfNotTriggeredClosure::G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t_cl,
 342                                                              OopClosure* oop_cl)  :
 343   _trigger_cl(t_cl), _oop_cl(oop_cl) { }
 344 
 345 G1Mux2Closure::G1Mux2Closure(OopClosure *c1, OopClosure *c2) :
 346   _c1(c1), _c2(c2) { }
 347 
 348 G1UpdateRSOrPushRefOopClosure::
 349 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,




 112   _oc->set_region(r);
 113   MemRegion card_region(_bot->address_for_index(index), BOTConstants::N_words);
 114   MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
 115   MemRegion mr = pre_gc_allocated.intersection(card_region);
 116   if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
 117     // We make the card as "claimed" lazily (so races are possible
 118     // but they're benign), which reduces the number of duplicate
 119     // scans (the rsets of the regions in the cset can intersect).
 120     _ct_bs->set_card_claimed(index);
 121     _cards_done++;
 122     cl.do_MemRegion(mr);
 123   }
 124 }
 125 
 126 void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
 127   double scan_start = os::elapsedTime();
 128   r->strong_code_roots_do(_code_root_cl);
 129   _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
 130 }
 131 
 132 void ScanRSClosure::doHeapRegion(HeapRegion* r) {
 133   assert(r->in_collection_set(), "should only be called on elements of CS.");
 134   HeapRegionRemSet* hrrs = r->rem_set();
 135   if (hrrs->iter_is_complete()) return; // All done.
 136   if (!_try_claimed && !hrrs->claim_iter()) return;
 137   // If we ever free the collection set concurrently, we should also
 138   // clear the card table concurrently therefore we won't need to
 139   // add regions of the collection set to the dirty cards region.
 140   _g1h->push_dirty_cards_region(r);
 141   // If we didn't return above, then
 142   //   _try_claimed || r->claim_iter()
 143   // is true: either we're supposed to work on claimed-but-not-complete
 144   // regions, or we successfully claimed the region.
 145 
 146   HeapRegionRemSetIterator iter(hrrs);
 147   size_t card_index;
 148 
 149   // We claim cards in block so as to reduce the contention. The block size is determined by
 150   // the G1RSetScanBlockSize parameter.
 151   size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
 152   for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
 153     if (current_card >= jump_to_card + _block_size) {
 154       jump_to_card = hrrs->iter_claimed_next(_block_size);
 155     }
 156     if (current_card < jump_to_card) continue;


 158 
 159     HeapRegion* card_region = _g1h->heap_region_containing(card_start);
 160     _cards++;
 161 
 162     if (!card_region->is_on_dirty_cards_region_list()) {
 163       _g1h->push_dirty_cards_region(card_region);
 164     }
 165 
 166     // If the card is dirty, then we will scan it during updateRS.
 167     if (!card_region->in_collection_set() &&
 168         !_ct_bs->is_card_dirty(card_index)) {
 169       scanCard(card_index, card_region);
 170     }
 171   }
 172   if (!_try_claimed) {
 173     // Scan the strong code root list attached to the current region
 174     scan_strong_code_roots(r);
 175 
 176     hrrs->set_iter_complete();
 177   }

 178 }
 179 
 180 size_t G1RemSet::scanRS(G1ParPushHeapRSClosure* oc,
 181                         CodeBlobClosure* heap_region_codeblobs,
 182                         uint worker_i) {
 183   double rs_time_start = os::elapsedTime();
 184 
 185   HeapRegion *startRegion = _g1->start_cset_region_for_worker(worker_i);
 186 
 187   ScanRSClosure scanRScl(oc, heap_region_codeblobs, worker_i);
 188 
 189   _g1->collection_set_iterate_from(startRegion, &scanRScl);
 190   scanRScl.set_try_claimed();
 191   _g1->collection_set_iterate_from(startRegion, &scanRScl);
 192 
 193   double scan_rs_time_sec = (os::elapsedTime() - rs_time_start)
 194                             - scanRScl.strong_code_root_scan_time_sec();
 195 
 196   _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
 197   _g1p->phase_times()->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, scanRScl.strong_code_root_scan_time_sec());


 304 
 305   // Free any completed buffers in the DirtyCardQueueSet used to hold cards
 306   // which contain references that point into the collection.
 307   _into_cset_dirty_card_queue_set.clear();
 308   assert(_into_cset_dirty_card_queue_set.completed_buffers_num() == 0,
 309          "all buffers should be freed");
 310   _into_cset_dirty_card_queue_set.clear_n_completed_buffers();
 311 }
 312 
 313 class ScrubRSClosure: public HeapRegionClosure {
 314   G1CollectedHeap* _g1h;
 315   BitMap* _region_bm;
 316   BitMap* _card_bm;
 317   CardTableModRefBS* _ctbs;
 318 public:
 319   ScrubRSClosure(BitMap* region_bm, BitMap* card_bm) :
 320     _g1h(G1CollectedHeap::heap()),
 321     _region_bm(region_bm), _card_bm(card_bm),
 322     _ctbs(_g1h->g1_barrier_set()) {}
 323 
 324   void doHeapRegion(HeapRegion* r) {
 325     if (!r->is_continues_humongous()) {
 326       r->rem_set()->scrub(_ctbs, _region_bm, _card_bm);
 327     }

 328   }
 329 };
 330 
 331 void G1RemSet::scrub(BitMap* region_bm, BitMap* card_bm, uint worker_num, HeapRegionClaimer *hrclaimer) {
 332   ScrubRSClosure scrub_cl(region_bm, card_bm);
 333   _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
 334 }
 335 
 336 G1TriggerClosure::G1TriggerClosure() :
 337   _triggered(false) { }
 338 
 339 G1InvokeIfNotTriggeredClosure::G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t_cl,
 340                                                              OopClosure* oop_cl)  :
 341   _trigger_cl(t_cl), _oop_cl(oop_cl) { }
 342 
 343 G1Mux2Closure::G1Mux2Closure(OopClosure *c1, OopClosure *c2) :
 344   _c1(c1), _c2(c2) { }
 345 
 346 G1UpdateRSOrPushRefOopClosure::
 347 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,


src/share/vm/gc/g1/g1RemSet.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File