< prev index next >

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

Print this page
rev 13237 : imported patch 8183226-periodic-rem-set-summary-accesses-uninitialized-stuff
rev 13238 : imported patch 8183226-eridk-sjohanss-review
rev 13239 : imported patch 8183128-cleanup-refinecardtableentryclosure


  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/g1/concurrentG1Refine.hpp"
  27 #include "gc/g1/dirtyCardQueue.hpp"
  28 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
  29 #include "gc/g1/g1CollectedHeap.inline.hpp"
  30 #include "gc/g1/g1FromCardCache.hpp"
  31 #include "gc/g1/g1GCPhaseTimes.hpp"
  32 #include "gc/g1/g1HotCardCache.hpp"
  33 #include "gc/g1/g1OopClosures.inline.hpp"
  34 #include "gc/g1/g1RemSet.inline.hpp"
  35 #include "gc/g1/g1SATBCardTableModRefBS.inline.hpp"
  36 #include "gc/g1/heapRegion.inline.hpp"
  37 #include "gc/g1/heapRegionManager.inline.hpp"
  38 #include "gc/g1/heapRegionRemSet.hpp"

  39 #include "gc/shared/gcTraceTime.inline.hpp"
  40 #include "memory/iterator.hpp"
  41 #include "memory/resourceArea.hpp"
  42 #include "oops/oop.inline.hpp"
  43 #include "utilities/align.hpp"
  44 #include "utilities/globalDefinitions.hpp"
  45 #include "utilities/intHisto.hpp"
  46 #include "utilities/stack.inline.hpp"
  47 
  48 // Collects information about the overall remembered set scan progress during an evacuation.
  49 class G1RemSetScanState : public CHeapObj<mtGC> {
  50 private:
  51   class G1ClearCardTableTask : public AbstractGangTask {
  52     G1CollectedHeap* _g1h;
  53     uint* _dirty_region_list;
  54     size_t _num_dirty_regions;
  55     size_t _chunk_length;
  56 
  57     size_t volatile _cur_dirty_regions;
  58   public:


 266 
 267     log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " "
 268                         "units of work for " SIZE_FORMAT " regions.",
 269                         cl.name(), num_workers, num_chunks, _cur_dirty_region);
 270     workers->run_task(&cl, num_workers);
 271 
 272 #ifndef PRODUCT
 273     // Need to synchronize with concurrent cleanup since it needs to
 274     // finish its card table clearing before we can verify.
 275     G1CollectedHeap::heap()->wait_while_free_regions_coming();
 276     G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
 277 #endif
 278   }
 279 };
 280 
 281 G1RemSet::G1RemSet(G1CollectedHeap* g1,
 282                    CardTableModRefBS* ct_bs,
 283                    G1HotCardCache* hot_card_cache) :
 284   _g1(g1),
 285   _scan_state(new G1RemSetScanState()),

 286   _num_conc_refined_cards(0),
 287   _ct_bs(ct_bs),
 288   _g1p(_g1->g1_policy()),
 289   _hot_card_cache(hot_card_cache),
 290   _prev_period_summary(),
 291   _into_cset_dirty_card_queue_set(false)
 292 {
 293   // Initialize the card queue set used to hold cards containing
 294   // references into the collection set.
 295   _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
 296                                              DirtyCardQ_CBL_mon,
 297                                              DirtyCardQ_FL_lock,
 298                                              -1, // never trigger processing
 299                                              -1, // no limit on length
 300                                              Shared_DirtyCardQ_lock,
 301                                              &JavaThread::dirty_card_queue_set());
 302 }
 303 
 304 G1RemSet::~G1RemSet() {
 305   if (_scan_state != NULL) {


 429                             uint worker_i) {
 430   double rs_time_start = os::elapsedTime();
 431 
 432   G1ScanObjsDuringScanRSClosure scan_cl(_g1, pss);
 433   G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, heap_region_codeblobs, worker_i);
 434   _g1->collection_set_iterate_from(&cl, worker_i);
 435 
 436   double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
 437                              cl.strong_code_root_scan_time_sec();
 438 
 439   G1GCPhaseTimes* p = _g1p->phase_times();
 440 
 441   p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
 442   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScannedCards);
 443   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ClaimedCards);
 444   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::SkippedCards);
 445 
 446   p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
 447 }
 448 











 449 // Closure used for updating RSets and recording references that
 450 // point into the collection set. Only called during an
 451 // evacuation pause.
 452 class G1RefineCardClosure: public CardTableEntryClosure {
 453   G1RemSet* _g1rs;
 454   DirtyCardQueue* _into_cset_dcq;
 455   G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
 456 public:
 457   G1RefineCardClosure(G1CollectedHeap* g1h,
 458                       DirtyCardQueue* into_cset_dcq,
 459                       G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
 460     _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq), _update_rs_cl(update_rs_cl)
 461   {}
 462 
 463   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
 464     // The only time we care about recording cards that
 465     // contain references that point into the collection set
 466     // is during RSet updating within an evacuation pause.
 467     // In this case worker_i should be the id of a GC worker thread.
 468     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");


 502 
 503 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
 504                                            CodeBlobClosure* heap_region_codeblobs,
 505                                            uint worker_i) {
 506   // A DirtyCardQueue that is used to hold cards containing references
 507   // that point into the collection set. This DCQ is associated with a
 508   // special DirtyCardQueueSet (see g1CollectedHeap.hpp).  Under normal
 509   // circumstances (i.e. the pause successfully completes), these cards
 510   // are just discarded (there's no need to update the RSets of regions
 511   // that were in the collection set - after the pause these regions
 512   // are wholly 'free' of live objects. In the event of an evacuation
 513   // failure the cards/buffers in this queue set are passed to the
 514   // DirtyCardQueueSet that is used to manage RSet updates
 515   DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
 516 
 517   update_rem_set(&into_cset_dcq, pss, worker_i);
 518   scan_rem_set(pss, heap_region_codeblobs, worker_i);;
 519 }
 520 
 521 void G1RemSet::prepare_for_oops_into_collection_set_do() {
 522   _g1->set_refine_cte_cl_concurrency(false);
 523   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 524   dcqs.concatenate_logs();
 525 
 526   _scan_state->reset();
 527 }
 528 
 529 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
 530   G1GCPhaseTimes* phase_times = _g1->g1_policy()->phase_times();
 531   // Cleanup after copy
 532   _g1->set_refine_cte_cl_concurrency(true);
 533 
 534   // Set all cards back to clean.
 535   double start = os::elapsedTime();
 536   _scan_state->clear_card_table(_g1->workers());
 537   phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
 538 
 539   DirtyCardQueueSet& into_cset_dcqs = _into_cset_dirty_card_queue_set;
 540 
 541   if (_g1->evacuation_failed()) {
 542     double restore_remembered_set_start = os::elapsedTime();
 543 
 544     // Restore remembered sets for the regions pointing into the collection set.
 545     // We just need to transfer the completed buffers from the DirtyCardQueueSet
 546     // used to hold cards that contain references that point into the collection set
 547     // to the DCQS used to hold the deferred RS updates.
 548     _g1->dirty_card_queue_set().merge_bufferlists(&into_cset_dcqs);
 549     phase_times->record_evac_fail_restore_remsets((os::elapsedTime() - restore_remembered_set_start) * 1000.0);
 550   }
 551 
 552   // Free any completed buffers in the DirtyCardQueueSet used to hold cards




  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "gc/g1/concurrentG1Refine.hpp"
  27 #include "gc/g1/dirtyCardQueue.hpp"
  28 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
  29 #include "gc/g1/g1CollectedHeap.inline.hpp"
  30 #include "gc/g1/g1FromCardCache.hpp"
  31 #include "gc/g1/g1GCPhaseTimes.hpp"
  32 #include "gc/g1/g1HotCardCache.hpp"
  33 #include "gc/g1/g1OopClosures.inline.hpp"
  34 #include "gc/g1/g1RemSet.inline.hpp"
  35 #include "gc/g1/g1SATBCardTableModRefBS.inline.hpp"
  36 #include "gc/g1/heapRegion.inline.hpp"
  37 #include "gc/g1/heapRegionManager.inline.hpp"
  38 #include "gc/g1/heapRegionRemSet.hpp"
  39 #include "gc/g1/suspendibleThreadSet.hpp"
  40 #include "gc/shared/gcTraceTime.inline.hpp"
  41 #include "memory/iterator.hpp"
  42 #include "memory/resourceArea.hpp"
  43 #include "oops/oop.inline.hpp"
  44 #include "utilities/align.hpp"
  45 #include "utilities/globalDefinitions.hpp"
  46 #include "utilities/intHisto.hpp"
  47 #include "utilities/stack.inline.hpp"
  48 
  49 // Collects information about the overall remembered set scan progress during an evacuation.
  50 class G1RemSetScanState : public CHeapObj<mtGC> {
  51 private:
  52   class G1ClearCardTableTask : public AbstractGangTask {
  53     G1CollectedHeap* _g1h;
  54     uint* _dirty_region_list;
  55     size_t _num_dirty_regions;
  56     size_t _chunk_length;
  57 
  58     size_t volatile _cur_dirty_regions;
  59   public:


 267 
 268     log_debug(gc, ergo)("Running %s using %u workers for " SIZE_FORMAT " "
 269                         "units of work for " SIZE_FORMAT " regions.",
 270                         cl.name(), num_workers, num_chunks, _cur_dirty_region);
 271     workers->run_task(&cl, num_workers);
 272 
 273 #ifndef PRODUCT
 274     // Need to synchronize with concurrent cleanup since it needs to
 275     // finish its card table clearing before we can verify.
 276     G1CollectedHeap::heap()->wait_while_free_regions_coming();
 277     G1CollectedHeap::heap()->verifier()->verify_card_table_cleanup();
 278 #endif
 279   }
 280 };
 281 
 282 G1RemSet::G1RemSet(G1CollectedHeap* g1,
 283                    CardTableModRefBS* ct_bs,
 284                    G1HotCardCache* hot_card_cache) :
 285   _g1(g1),
 286   _scan_state(new G1RemSetScanState()),
 287   _refine_card_concurrently_cl(),
 288   _num_conc_refined_cards(0),
 289   _ct_bs(ct_bs),
 290   _g1p(_g1->g1_policy()),
 291   _hot_card_cache(hot_card_cache),
 292   _prev_period_summary(),
 293   _into_cset_dirty_card_queue_set(false)
 294 {
 295   // Initialize the card queue set used to hold cards containing
 296   // references into the collection set.
 297   _into_cset_dirty_card_queue_set.initialize(NULL, // Should never be called by the Java code
 298                                              DirtyCardQ_CBL_mon,
 299                                              DirtyCardQ_FL_lock,
 300                                              -1, // never trigger processing
 301                                              -1, // no limit on length
 302                                              Shared_DirtyCardQ_lock,
 303                                              &JavaThread::dirty_card_queue_set());
 304 }
 305 
 306 G1RemSet::~G1RemSet() {
 307   if (_scan_state != NULL) {


 431                             uint worker_i) {
 432   double rs_time_start = os::elapsedTime();
 433 
 434   G1ScanObjsDuringScanRSClosure scan_cl(_g1, pss);
 435   G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, heap_region_codeblobs, worker_i);
 436   _g1->collection_set_iterate_from(&cl, worker_i);
 437 
 438   double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
 439                              cl.strong_code_root_scan_time_sec();
 440 
 441   G1GCPhaseTimes* p = _g1p->phase_times();
 442 
 443   p->record_time_secs(G1GCPhaseTimes::ScanRS, worker_i, scan_rs_time_sec);
 444   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_scanned(), G1GCPhaseTimes::ScannedCards);
 445   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_claimed(), G1GCPhaseTimes::ClaimedCards);
 446   p->record_thread_work_item(G1GCPhaseTimes::ScanRS, worker_i, cl.cards_skipped(), G1GCPhaseTimes::SkippedCards);
 447 
 448   p->record_time_secs(G1GCPhaseTimes::CodeRoots, worker_i, cl.strong_code_root_scan_time_sec());
 449 }
 450 
 451 bool G1RefineCardConcurrentlyClosure::do_card_ptr(jbyte* card_ptr, uint worker_i) {
 452   G1CollectedHeap::heap()->g1_rem_set()->refine_card_concurrently(card_ptr, worker_i);
 453 
 454   if (SuspendibleThreadSet::should_yield()) {
 455     // Caller will actually yield.
 456     return false;
 457   }
 458   // Otherwise, we finished successfully; return true.
 459   return true;
 460 }
 461 
 462 // Closure used for updating RSets and recording references that
 463 // point into the collection set. Only called during an
 464 // evacuation pause.
 465 class G1RefineCardClosure: public CardTableEntryClosure {
 466   G1RemSet* _g1rs;
 467   DirtyCardQueue* _into_cset_dcq;
 468   G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
 469 public:
 470   G1RefineCardClosure(G1CollectedHeap* g1h,
 471                       DirtyCardQueue* into_cset_dcq,
 472                       G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
 473     _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq), _update_rs_cl(update_rs_cl)
 474   {}
 475 
 476   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
 477     // The only time we care about recording cards that
 478     // contain references that point into the collection set
 479     // is during RSet updating within an evacuation pause.
 480     // In this case worker_i should be the id of a GC worker thread.
 481     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");


 515 
 516 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
 517                                            CodeBlobClosure* heap_region_codeblobs,
 518                                            uint worker_i) {
 519   // A DirtyCardQueue that is used to hold cards containing references
 520   // that point into the collection set. This DCQ is associated with a
 521   // special DirtyCardQueueSet (see g1CollectedHeap.hpp).  Under normal
 522   // circumstances (i.e. the pause successfully completes), these cards
 523   // are just discarded (there's no need to update the RSets of regions
 524   // that were in the collection set - after the pause these regions
 525   // are wholly 'free' of live objects. In the event of an evacuation
 526   // failure the cards/buffers in this queue set are passed to the
 527   // DirtyCardQueueSet that is used to manage RSet updates
 528   DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
 529 
 530   update_rem_set(&into_cset_dcq, pss, worker_i);
 531   scan_rem_set(pss, heap_region_codeblobs, worker_i);;
 532 }
 533 
 534 void G1RemSet::prepare_for_oops_into_collection_set_do() {

 535   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
 536   dcqs.concatenate_logs();
 537 
 538   _scan_state->reset();
 539 }
 540 
 541 void G1RemSet::cleanup_after_oops_into_collection_set_do() {
 542   G1GCPhaseTimes* phase_times = _g1->g1_policy()->phase_times();


 543 
 544   // Set all cards back to clean.
 545   double start = os::elapsedTime();
 546   _scan_state->clear_card_table(_g1->workers());
 547   phase_times->record_clear_ct_time((os::elapsedTime() - start) * 1000.0);
 548 
 549   DirtyCardQueueSet& into_cset_dcqs = _into_cset_dirty_card_queue_set;
 550 
 551   if (_g1->evacuation_failed()) {
 552     double restore_remembered_set_start = os::elapsedTime();
 553 
 554     // Restore remembered sets for the regions pointing into the collection set.
 555     // We just need to transfer the completed buffers from the DirtyCardQueueSet
 556     // used to hold cards that contain references that point into the collection set
 557     // to the DCQS used to hold the deferred RS updates.
 558     _g1->dirty_card_queue_set().merge_bufferlists(&into_cset_dcqs);
 559     phase_times->record_evac_fail_restore_remsets((os::elapsedTime() - restore_remembered_set_start) * 1000.0);
 560   }
 561 
 562   // Free any completed buffers in the DirtyCardQueueSet used to hold cards


< prev index next >