< prev index next >

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

Print this page




  35 #include "gc/g1/heapRegionManager.inline.hpp"
  36 #include "gc/g1/heapRegionRemSet.hpp"
  37 #include "memory/iterator.hpp"
  38 #include "oops/oop.inline.hpp"
  39 #include "utilities/globalDefinitions.hpp"
  40 #include "utilities/intHisto.hpp"
  41 #include "utilities/stack.inline.hpp"
  42 
  43 G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
  44   : _g1(g1), _conc_refine_cards(0),
  45     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
  46     _cg1r(g1->concurrent_g1_refine()),
  47     _cset_rs_update_cl(NULL),
  48     _prev_period_summary(),
  49     _into_cset_dirty_card_queue_set(false)
  50 {
  51   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC);
  52   for (uint i = 0; i < n_workers(); i++) {
  53     _cset_rs_update_cl[i] = NULL;
  54   }
  55   if (G1SummarizeRSetStats) {
  56     _prev_period_summary.initialize(this);
  57   }
  58   // Initialize the card queue set used to hold cards containing
  59   // references into the collection set.
  60   _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
  61                                              DirtyCardQ_CBL_mon,
  62                                              DirtyCardQ_FL_lock,
  63                                              -1, // never trigger processing
  64                                              -1, // no limit on length
  65                                              Shared_DirtyCardQ_lock,
  66                                              &JavaThread::dirty_card_queue_set());
  67 }
  68 
  69 G1RemSet::~G1RemSet() {
  70   for (uint i = 0; i < n_workers(); i++) {
  71     assert(_cset_rs_update_cl[i] == NULL, "it should be");
  72   }
  73   FREE_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, _cset_rs_update_cl);
  74 }
  75 


  92 void ScanRSClosure::scanCard(size_t index, HeapRegion *r) {
  93   // Stack allocate the DirtyCardToOopClosure instance
  94   HeapRegionDCTOC cl(_g1h, r, _oc,
  95       CardTableModRefBS::Precise);
  96 
  97   // Set the "from" region in the closure.
  98   _oc->set_region(r);
  99   MemRegion card_region(_bot_shared->address_for_index(index), G1BlockOffsetSharedArray::N_words);
 100   MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
 101   MemRegion mr = pre_gc_allocated.intersection(card_region);
 102   if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
 103     // We make the card as "claimed" lazily (so races are possible
 104     // but they're benign), which reduces the number of duplicate
 105     // scans (the rsets of the regions in the cset can intersect).
 106     _ct_bs->set_card_claimed(index);
 107     _cards_done++;
 108     cl.do_MemRegion(mr);
 109   }
 110 }
 111 
 112 void ScanRSClosure::printCard(HeapRegion* card_region, size_t card_index,
 113     HeapWord* card_start) {
 114   gclog_or_tty->print_cr("T %u Region [" PTR_FORMAT ", " PTR_FORMAT ") "
 115       "RS names card " SIZE_FORMAT_HEX ": "
 116       "[" PTR_FORMAT ", " PTR_FORMAT ")",
 117       _worker_i,
 118       p2i(card_region->bottom()), p2i(card_region->end()),
 119       card_index,
 120       p2i(card_start), p2i(card_start + G1BlockOffsetSharedArray::N_words));
 121 }
 122 
 123 void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
 124   double scan_start = os::elapsedTime();
 125   r->strong_code_roots_do(_code_root_cl);
 126   _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
 127 }
 128 
 129 bool ScanRSClosure::doHeapRegion(HeapRegion* r) {
 130   assert(r->in_collection_set(), "should only be called on elements of CS.");
 131   HeapRegionRemSet* hrrs = r->rem_set();
 132   if (hrrs->iter_is_complete()) return false; // All done.
 133   if (!_try_claimed && !hrrs->claim_iter()) return false;
 134   // If we ever free the collection set concurrently, we should also
 135   // clear the card table concurrently therefore we won't need to
 136   // add regions of the collection set to the dirty cards region.
 137   _g1h->push_dirty_cards_region(r);
 138   // If we didn't return above, then
 139   //   _try_claimed || r->claim_iter()
 140   // is true: either we're supposed to work on claimed-but-not-complete
 141   // regions, or we successfully claimed the region.
 142 
 143   HeapRegionRemSetIterator iter(hrrs);
 144   size_t card_index;
 145 
 146   // We claim cards in block so as to reduce the contention. The block size is determined by
 147   // the G1RSetScanBlockSize parameter.
 148   size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
 149   for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
 150     if (current_card >= jump_to_card + _block_size) {
 151       jump_to_card = hrrs->iter_claimed_next(_block_size);
 152     }
 153     if (current_card < jump_to_card) continue;
 154     HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);
 155 #if 0
 156     gclog_or_tty->print("Rem set iteration yielded card [" PTR_FORMAT ", " PTR_FORMAT ").\n",
 157         card_start, card_start + CardTableModRefBS::card_size_in_words);
 158 #endif
 159 
 160     HeapRegion* card_region = _g1h->heap_region_containing(card_start);
 161     _cards++;
 162 
 163     if (!card_region->is_on_dirty_cards_region_list()) {
 164       _g1h->push_dirty_cards_region(card_region);
 165     }
 166 
 167     // If the card is dirty, then we will scan it during updateRS.
 168     if (!card_region->in_collection_set() &&
 169         !_ct_bs->is_card_dirty(card_index)) {
 170       scanCard(card_index, card_region);
 171     }
 172   }
 173   if (!_try_claimed) {
 174     // Scan the strong code root list attached to the current region
 175     scan_strong_code_roots(r);
 176 
 177     hrrs->set_iter_complete();
 178   }


 509         JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
 510       sdcq->enqueue(card_ptr);
 511     }
 512   } else {
 513     _conc_refine_cards++;
 514   }
 515 
 516   // This gets set to true if the card being refined has
 517   // references that point into the collection set.
 518   bool has_refs_into_cset = trigger_cl.triggered();
 519 
 520   // We should only be detecting that the card contains references
 521   // that point into the collection set if the current thread is
 522   // a GC worker thread.
 523   assert(!has_refs_into_cset || SafepointSynchronize::is_at_safepoint(),
 524            "invalid result at non safepoint");
 525 
 526   return has_refs_into_cset;
 527 }
 528 
 529 void G1RemSet::print_periodic_summary_info(const char* header) {







 530   G1RemSetSummary current;
 531   current.initialize(this);
 532 
 533   _prev_period_summary.subtract_from(&current);
 534   print_summary_info(&_prev_period_summary, header);




 535 
 536   _prev_period_summary.set(&current);

 537 }
 538 
 539 void G1RemSet::print_summary_info() {



 540   G1RemSetSummary current;
 541   current.initialize(this);
 542 
 543   print_summary_info(&current, " Cumulative RS summary");
 544 }
 545 
 546 void G1RemSet::print_summary_info(G1RemSetSummary * summary, const char * header) {
 547   assert(summary != NULL, "just checking");
 548 
 549   if (header != NULL) {
 550     gclog_or_tty->print_cr("%s", header);
 551   }
 552 
 553   summary->print_on(gclog_or_tty);
 554 }
 555 
 556 void G1RemSet::prepare_for_verify() {
 557   if (G1HRRSFlushLogBuffersOnVerify &&
 558       (VerifyBeforeGC || VerifyAfterGC)
 559       &&  (!_g1->collector_state()->full_collection() || G1VerifyRSetsDuringFullGC)) {
 560     cleanupHRRS();
 561     _g1->set_refine_cte_cl_concurrency(false);
 562     if (SafepointSynchronize::is_at_safepoint()) {
 563       DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 564       dcqs.concatenate_logs();
 565     }
 566 
 567     G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
 568     bool use_hot_card_cache = hot_card_cache->use_cache();
 569     hot_card_cache->set_use_cache(false);
 570 
 571     DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
 572     updateRS(&into_cset_dcq, 0);
 573     _into_cset_dirty_card_queue_set.clear();


  35 #include "gc/g1/heapRegionManager.inline.hpp"
  36 #include "gc/g1/heapRegionRemSet.hpp"
  37 #include "memory/iterator.hpp"
  38 #include "oops/oop.inline.hpp"
  39 #include "utilities/globalDefinitions.hpp"
  40 #include "utilities/intHisto.hpp"
  41 #include "utilities/stack.inline.hpp"
  42 
  43 G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
  44   : _g1(g1), _conc_refine_cards(0),
  45     _ct_bs(ct_bs), _g1p(_g1->g1_policy()),
  46     _cg1r(g1->concurrent_g1_refine()),
  47     _cset_rs_update_cl(NULL),
  48     _prev_period_summary(),
  49     _into_cset_dirty_card_queue_set(false)
  50 {
  51   _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC);
  52   for (uint i = 0; i < n_workers(); i++) {
  53     _cset_rs_update_cl[i] = NULL;
  54   }
  55   if (log_is_enabled(Trace, gc, remset)) {
  56     _prev_period_summary.initialize(this);
  57   }
  58   // Initialize the card queue set used to hold cards containing
  59   // references into the collection set.
  60   _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
  61                                              DirtyCardQ_CBL_mon,
  62                                              DirtyCardQ_FL_lock,
  63                                              -1, // never trigger processing
  64                                              -1, // no limit on length
  65                                              Shared_DirtyCardQ_lock,
  66                                              &JavaThread::dirty_card_queue_set());
  67 }
  68 
  69 G1RemSet::~G1RemSet() {
  70   for (uint i = 0; i < n_workers(); i++) {
  71     assert(_cset_rs_update_cl[i] == NULL, "it should be");
  72   }
  73   FREE_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, _cset_rs_update_cl);
  74 }
  75 


  92 void ScanRSClosure::scanCard(size_t index, HeapRegion *r) {
  93   // Stack allocate the DirtyCardToOopClosure instance
  94   HeapRegionDCTOC cl(_g1h, r, _oc,
  95       CardTableModRefBS::Precise);
  96 
  97   // Set the "from" region in the closure.
  98   _oc->set_region(r);
  99   MemRegion card_region(_bot_shared->address_for_index(index), G1BlockOffsetSharedArray::N_words);
 100   MemRegion pre_gc_allocated(r->bottom(), r->scan_top());
 101   MemRegion mr = pre_gc_allocated.intersection(card_region);
 102   if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
 103     // We make the card as "claimed" lazily (so races are possible
 104     // but they're benign), which reduces the number of duplicate
 105     // scans (the rsets of the regions in the cset can intersect).
 106     _ct_bs->set_card_claimed(index);
 107     _cards_done++;
 108     cl.do_MemRegion(mr);
 109   }
 110 }
 111 











 112 void ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
 113   double scan_start = os::elapsedTime();
 114   r->strong_code_roots_do(_code_root_cl);
 115   _strong_code_root_scan_time_sec += (os::elapsedTime() - scan_start);
 116 }
 117 
 118 bool ScanRSClosure::doHeapRegion(HeapRegion* r) {
 119   assert(r->in_collection_set(), "should only be called on elements of CS.");
 120   HeapRegionRemSet* hrrs = r->rem_set();
 121   if (hrrs->iter_is_complete()) return false; // All done.
 122   if (!_try_claimed && !hrrs->claim_iter()) return false;
 123   // If we ever free the collection set concurrently, we should also
 124   // clear the card table concurrently therefore we won't need to
 125   // add regions of the collection set to the dirty cards region.
 126   _g1h->push_dirty_cards_region(r);
 127   // If we didn't return above, then
 128   //   _try_claimed || r->claim_iter()
 129   // is true: either we're supposed to work on claimed-but-not-complete
 130   // regions, or we successfully claimed the region.
 131 
 132   HeapRegionRemSetIterator iter(hrrs);
 133   size_t card_index;
 134 
 135   // We claim cards in block so as to reduce the contention. The block size is determined by
 136   // the G1RSetScanBlockSize parameter.
 137   size_t jump_to_card = hrrs->iter_claimed_next(_block_size);
 138   for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
 139     if (current_card >= jump_to_card + _block_size) {
 140       jump_to_card = hrrs->iter_claimed_next(_block_size);
 141     }
 142     if (current_card < jump_to_card) continue;
 143     HeapWord* card_start = _g1h->bot_shared()->address_for_index(card_index);




 144 
 145     HeapRegion* card_region = _g1h->heap_region_containing(card_start);
 146     _cards++;
 147 
 148     if (!card_region->is_on_dirty_cards_region_list()) {
 149       _g1h->push_dirty_cards_region(card_region);
 150     }
 151 
 152     // If the card is dirty, then we will scan it during updateRS.
 153     if (!card_region->in_collection_set() &&
 154         !_ct_bs->is_card_dirty(card_index)) {
 155       scanCard(card_index, card_region);
 156     }
 157   }
 158   if (!_try_claimed) {
 159     // Scan the strong code root list attached to the current region
 160     scan_strong_code_roots(r);
 161 
 162     hrrs->set_iter_complete();
 163   }


 494         JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
 495       sdcq->enqueue(card_ptr);
 496     }
 497   } else {
 498     _conc_refine_cards++;
 499   }
 500 
 501   // This gets set to true if the card being refined has
 502   // references that point into the collection set.
 503   bool has_refs_into_cset = trigger_cl.triggered();
 504 
 505   // We should only be detecting that the card contains references
 506   // that point into the collection set if the current thread is
 507   // a GC worker thread.
 508   assert(!has_refs_into_cset || SafepointSynchronize::is_at_safepoint(),
 509            "invalid result at non safepoint");
 510 
 511   return has_refs_into_cset;
 512 }
 513 
 514 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
 515   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
 516       (period_count % G1SummarizeRSetStatsPeriod == 0)) {
 517 
 518     if (!_prev_period_summary.initialized()) {
 519       _prev_period_summary.initialize(this);
 520     }
 521 
 522     G1RemSetSummary current;
 523     current.initialize(this);

 524     _prev_period_summary.subtract_from(&current);
 525 
 526     LogHandle(gc, remset) log;
 527     log.trace("%s", header);
 528     ResourceMark rm;
 529     _prev_period_summary.print_on(log.trace_stream());
 530 
 531     _prev_period_summary.set(&current);
 532   }
 533 }
 534 
 535 void G1RemSet::print_summary_info() {
 536   LogHandle(gc, remset, exit) log;
 537   if (log.is_trace()) {
 538     log.trace(" Cumulative RS summary");
 539     G1RemSetSummary current;
 540     current.initialize(this);
 541     ResourceMark rm;
 542     current.print_on(log.trace_stream());







 543   }


 544 }
 545 
 546 void G1RemSet::prepare_for_verify() {
 547   if (G1HRRSFlushLogBuffersOnVerify &&
 548       (VerifyBeforeGC || VerifyAfterGC)
 549       &&  (!_g1->collector_state()->full_collection() || G1VerifyRSetsDuringFullGC)) {
 550     cleanupHRRS();
 551     _g1->set_refine_cte_cl_concurrency(false);
 552     if (SafepointSynchronize::is_at_safepoint()) {
 553       DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 554       dcqs.concatenate_logs();
 555     }
 556 
 557     G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache();
 558     bool use_hot_card_cache = hot_card_cache->use_cache();
 559     hot_card_cache->set_use_cache(false);
 560 
 561     DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
 562     updateRS(&into_cset_dcq, 0);
 563     _into_cset_dirty_card_queue_set.clear();
< prev index next >