hotspot/src/share/vm/gc/g1/g1RemSet.cpp
changeset 46572 fef0d64b2263
parent 46571 c70b36f0730d
child 46575 d6fb8a7a7843
equal deleted inserted replaced
46571:c70b36f0730d 46572:fef0d64b2263
   325     _card_live_data.pretouch();
   325     _card_live_data.pretouch();
   326   }
   326   }
   327 }
   327 }
   328 
   328 
   329 G1ScanRSClosure::G1ScanRSClosure(G1RemSetScanState* scan_state,
   329 G1ScanRSClosure::G1ScanRSClosure(G1RemSetScanState* scan_state,
   330                                  G1ParPushHeapRSClosure* push_heap_cl,
   330                                  G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
   331                                  CodeBlobClosure* code_root_cl,
   331                                  CodeBlobClosure* code_root_cl,
   332                                  uint worker_i) :
   332                                  uint worker_i) :
   333   _scan_state(scan_state),
   333   _scan_state(scan_state),
   334   _push_heap_cl(push_heap_cl),
   334   _scan_objs_on_card_cl(scan_obj_on_card),
   335   _code_root_cl(code_root_cl),
   335   _code_root_cl(code_root_cl),
   336   _strong_code_root_scan_time_sec(0.0),
   336   _strong_code_root_scan_time_sec(0.0),
   337   _cards_claimed(0),
   337   _cards_claimed(0),
   338   _cards_scanned(0),
   338   _cards_scanned(0),
   339   _cards_skipped(0),
   339   _cards_skipped(0),
   351   if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
   351   if (!mr.is_empty() && !_ct_bs->is_card_claimed(index)) {
   352     // We make the card as "claimed" lazily (so races are possible
   352     // We make the card as "claimed" lazily (so races are possible
   353     // but they're benign), which reduces the number of duplicate
   353     // but they're benign), which reduces the number of duplicate
   354     // scans (the rsets of the regions in the cset can intersect).
   354     // scans (the rsets of the regions in the cset can intersect).
   355     _ct_bs->set_card_claimed(index);
   355     _ct_bs->set_card_claimed(index);
   356     _push_heap_cl->set_region(r);
   356     _scan_objs_on_card_cl->set_region(r);
   357     r->oops_on_card_seq_iterate_careful<true>(mr, _push_heap_cl);
   357     r->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
   358     _cards_scanned++;
   358     _cards_scanned++;
   359   }
   359   }
   360 }
   360 }
   361 
   361 
   362 void G1ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
   362 void G1ScanRSClosure::scan_strong_code_roots(HeapRegion* r) {
   411     scan_strong_code_roots(r);
   411     scan_strong_code_roots(r);
   412   }
   412   }
   413   return false;
   413   return false;
   414 }
   414 }
   415 
   415 
   416 void G1RemSet::scan_rem_set(G1ParPushHeapRSClosure* oops_in_heap_closure,
   416 void G1RemSet::scan_rem_set(G1ParScanThreadState* pss,
   417                             CodeBlobClosure* heap_region_codeblobs,
   417                             CodeBlobClosure* heap_region_codeblobs,
   418                             uint worker_i) {
   418                             uint worker_i) {
   419   double rs_time_start = os::elapsedTime();
   419   double rs_time_start = os::elapsedTime();
   420 
   420 
   421   G1ScanRSClosure cl(_scan_state, oops_in_heap_closure, heap_region_codeblobs, worker_i);
   421   G1ScanObjsDuringScanRSClosure scan_cl(_g1, pss);
       
   422   G1ScanRSClosure cl(_scan_state, &scan_cl, heap_region_codeblobs, worker_i);
   422   _g1->collection_set_iterate_from(&cl, worker_i);
   423   _g1->collection_set_iterate_from(&cl, worker_i);
   423 
   424 
   424   double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
   425   double scan_rs_time_sec = (os::elapsedTime() - rs_time_start) -
   425                              cl.strong_code_root_scan_time_sec();
   426                              cl.strong_code_root_scan_time_sec();
   426 
   427 
   439 // evacuation pause.
   440 // evacuation pause.
   440 
   441 
   441 class RefineRecordRefsIntoCSCardTableEntryClosure: public CardTableEntryClosure {
   442 class RefineRecordRefsIntoCSCardTableEntryClosure: public CardTableEntryClosure {
   442   G1RemSet* _g1rs;
   443   G1RemSet* _g1rs;
   443   DirtyCardQueue* _into_cset_dcq;
   444   DirtyCardQueue* _into_cset_dcq;
   444   G1ParPushHeapRSClosure* _cl;
   445   G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
   445 public:
   446 public:
   446   RefineRecordRefsIntoCSCardTableEntryClosure(G1CollectedHeap* g1h,
   447   RefineRecordRefsIntoCSCardTableEntryClosure(G1CollectedHeap* g1h,
   447                                               DirtyCardQueue* into_cset_dcq,
   448                                               DirtyCardQueue* into_cset_dcq,
   448                                               G1ParPushHeapRSClosure* cl) :
   449                                               G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
   449     _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq), _cl(cl)
   450     _g1rs(g1h->g1_rem_set()), _into_cset_dcq(into_cset_dcq), _update_rs_cl(update_rs_cl)
   450   {}
   451   {}
   451 
   452 
   452   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
   453   bool do_card_ptr(jbyte* card_ptr, uint worker_i) {
   453     // The only time we care about recording cards that
   454     // The only time we care about recording cards that
   454     // contain references that point into the collection set
   455     // contain references that point into the collection set
   455     // is during RSet updating within an evacuation pause.
   456     // is during RSet updating within an evacuation pause.
   456     // In this case worker_i should be the id of a GC worker thread.
   457     // In this case worker_i should be the id of a GC worker thread.
   457     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
   458     assert(SafepointSynchronize::is_at_safepoint(), "not during an evacuation pause");
   458     assert(worker_i < ParallelGCThreads, "should be a GC worker");
   459 
   459 
   460     if (_g1rs->refine_card_during_gc(card_ptr, _update_rs_cl)) {
   460     if (_g1rs->refine_card_during_gc(card_ptr, worker_i, _cl)) {
       
   461       // 'card_ptr' contains references that point into the collection
   461       // 'card_ptr' contains references that point into the collection
   462       // set. We need to record the card in the DCQS
   462       // set. We need to record the card in the DCQS
   463       // (_into_cset_dirty_card_queue_set)
   463       // (_into_cset_dirty_card_queue_set)
   464       // that's used for that purpose.
   464       // that's used for that purpose.
   465       //
   465       //
   469     return true;
   469     return true;
   470   }
   470   }
   471 };
   471 };
   472 
   472 
   473 void G1RemSet::update_rem_set(DirtyCardQueue* into_cset_dcq,
   473 void G1RemSet::update_rem_set(DirtyCardQueue* into_cset_dcq,
   474                               G1ParPushHeapRSClosure* oops_in_heap_closure,
   474                               G1ParScanThreadState* pss,
   475                               uint worker_i) {
   475                               uint worker_i) {
   476   RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq, oops_in_heap_closure);
   476   G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1, pss, worker_i);
       
   477   RefineRecordRefsIntoCSCardTableEntryClosure into_cset_update_rs_cl(_g1, into_cset_dcq, &update_rs_cl);
   477 
   478 
   478   G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
   479   G1GCParPhaseTimesTracker x(_g1p->phase_times(), G1GCPhaseTimes::UpdateRS, worker_i);
   479   if (G1HotCardCache::default_use_cache()) {
   480   if (G1HotCardCache::default_use_cache()) {
   480     // Apply the closure to the entries of the hot card cache.
   481     // Apply the closure to the entries of the hot card cache.
   481     G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
   482     G1GCParPhaseTimesTracker y(_g1p->phase_times(), G1GCPhaseTimes::ScanHCC, worker_i);
   487 
   488 
   488 void G1RemSet::cleanupHRRS() {
   489 void G1RemSet::cleanupHRRS() {
   489   HeapRegionRemSet::cleanup();
   490   HeapRegionRemSet::cleanup();
   490 }
   491 }
   491 
   492 
   492 void G1RemSet::oops_into_collection_set_do(G1ParPushHeapRSClosure* cl,
   493 void G1RemSet::oops_into_collection_set_do(G1ParScanThreadState* pss,
   493                                            CodeBlobClosure* heap_region_codeblobs,
   494                                            CodeBlobClosure* heap_region_codeblobs,
   494                                            uint worker_i) {
   495                                            uint worker_i) {
   495   // A DirtyCardQueue that is used to hold cards containing references
   496   // A DirtyCardQueue that is used to hold cards containing references
   496   // that point into the collection set. This DCQ is associated with a
   497   // that point into the collection set. This DCQ is associated with a
   497   // special DirtyCardQueueSet (see g1CollectedHeap.hpp).  Under normal
   498   // special DirtyCardQueueSet (see g1CollectedHeap.hpp).  Under normal
   501   // are wholly 'free' of live objects. In the event of an evacuation
   502   // are wholly 'free' of live objects. In the event of an evacuation
   502   // failure the cards/buffers in this queue set are passed to the
   503   // failure the cards/buffers in this queue set are passed to the
   503   // DirtyCardQueueSet that is used to manage RSet updates
   504   // DirtyCardQueueSet that is used to manage RSet updates
   504   DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
   505   DirtyCardQueue into_cset_dcq(&_into_cset_dirty_card_queue_set);
   505 
   506 
   506   update_rem_set(&into_cset_dcq, cl, worker_i);
   507   update_rem_set(&into_cset_dcq, pss, worker_i);
   507   scan_rem_set(cl, heap_region_codeblobs, worker_i);;
   508   scan_rem_set(pss, heap_region_codeblobs, worker_i);;
   508 }
   509 }
   509 
   510 
   510 void G1RemSet::prepare_for_oops_into_collection_set_do() {
   511 void G1RemSet::prepare_for_oops_into_collection_set_do() {
   511   _g1->set_refine_cte_cl_concurrency(false);
   512   _g1->set_refine_cte_cl_concurrency(false);
   512   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   513   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   576          ct_bs->index_for(ct_bs->addr_for(card_ptr)),
   577          ct_bs->index_for(ct_bs->addr_for(card_ptr)),
   577          p2i(ct_bs->addr_for(card_ptr)),
   578          p2i(ct_bs->addr_for(card_ptr)),
   578          g1->addr_to_region(ct_bs->addr_for(card_ptr)));
   579          g1->addr_to_region(ct_bs->addr_for(card_ptr)));
   579 #endif
   580 #endif
   580 }
   581 }
   581 
       
   582 G1UpdateRSOrPushRefOopClosure::G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
       
   583                                                              G1ParPushHeapRSClosure* push_ref_cl,
       
   584                                                              bool record_refs_into_cset,
       
   585                                                              uint worker_i) :
       
   586   _g1(g1h),
       
   587   _from(NULL),
       
   588   _record_refs_into_cset(record_refs_into_cset),
       
   589   _has_refs_into_cset(false),
       
   590   _push_ref_cl(push_ref_cl),
       
   591   _worker_i(worker_i) { }
       
   592 
   582 
   593 void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
   583 void G1RemSet::refine_card_concurrently(jbyte* card_ptr,
   594                                         uint worker_i) {
   584                                         uint worker_i) {
   595   assert(!_g1->is_gc_active(), "Only call concurrently");
   585   assert(!_g1->is_gc_active(), "Only call concurrently");
   596 
   586 
   738     _conc_refine_cards++;
   728     _conc_refine_cards++;
   739   }
   729   }
   740 }
   730 }
   741 
   731 
   742 bool G1RemSet::refine_card_during_gc(jbyte* card_ptr,
   732 bool G1RemSet::refine_card_during_gc(jbyte* card_ptr,
   743                                      uint worker_i,
   733                                      G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
   744                                      G1ParPushHeapRSClosure*  oops_in_heap_closure) {
       
   745   assert(_g1->is_gc_active(), "Only call during GC");
   734   assert(_g1->is_gc_active(), "Only call during GC");
   746 
   735 
   747   check_card_ptr(card_ptr, _ct_bs);
   736   check_card_ptr(card_ptr, _ct_bs);
   748 
   737 
   749   // If the card is no longer dirty, nothing to do. This covers cards that were already
   738   // If the card is no longer dirty, nothing to do. This covers cards that were already
   773   // a card beyond the heap.
   762   // a card beyond the heap.
   774   HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
   763   HeapWord* card_end = card_start + CardTableModRefBS::card_size_in_words;
   775   MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
   764   MemRegion dirty_region(card_start, MIN2(scan_limit, card_end));
   776   assert(!dirty_region.is_empty(), "sanity");
   765   assert(!dirty_region.is_empty(), "sanity");
   777 
   766 
   778   G1UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1,
   767   update_rs_cl->set_region(r);
   779                                                  oops_in_heap_closure,
   768   update_rs_cl->reset_has_refs_into_cset();
   780                                                  true,
   769 
   781                                                  worker_i);
   770   bool card_processed = r->oops_on_card_seq_iterate_careful<true>(dirty_region, update_rs_cl);
   782   update_rs_oop_cl.set_from(r);
       
   783 
       
   784   bool card_processed =
       
   785     r->oops_on_card_seq_iterate_careful<true>(dirty_region,
       
   786                                               &update_rs_oop_cl);
       
   787   assert(card_processed, "must be");
   771   assert(card_processed, "must be");
   788   _conc_refine_cards++;
   772   _conc_refine_cards++;
   789 
   773 
   790   return update_rs_oop_cl.has_refs_into_cset();
   774   return update_rs_cl->has_refs_into_cset();
   791 }
   775 }
   792 
   776 
   793 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
   777 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
   794   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
   778   if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
   795       (period_count % G1SummarizeRSetStatsPeriod == 0)) {
   779       (period_count % G1SummarizeRSetStatsPeriod == 0)) {