< prev index next >

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

8196341: Add JFR events for parallel phases of G1

22  */                                                                                                                        
23 
24 #include "precompiled.hpp"                                                                                                 
25 #include "gc/g1/dirtyCardQueue.hpp"                                                                                        
26 #include "gc/g1/g1BarrierSet.hpp"                                                                                          
27 #include "gc/g1/g1BlockOffsetTable.inline.hpp"                                                                             
28 #include "gc/g1/g1CardTable.inline.hpp"                                                                                    
29 #include "gc/g1/g1CollectedHeap.inline.hpp"                                                                                
30 #include "gc/g1/g1ConcurrentRefine.hpp"                                                                                    
31 #include "gc/g1/g1FromCardCache.hpp"                                                                                       
32 #include "gc/g1/g1GCPhaseTimes.hpp"                                                                                        
33 #include "gc/g1/g1HotCardCache.hpp"                                                                                        
34 #include "gc/g1/g1OopClosures.inline.hpp"                                                                                  
35 #include "gc/g1/g1RootClosures.hpp"                                                                                        
36 #include "gc/g1/g1RemSet.hpp"                                                                                              
37 #include "gc/g1/heapRegion.inline.hpp"                                                                                     
38 #include "gc/g1/heapRegionManager.inline.hpp"                                                                              
39 #include "gc/g1/heapRegionRemSet.hpp"                                                                                      
40 #include "gc/shared/gcTraceTime.inline.hpp"                                                                                
41 #include "gc/shared/suspendibleThreadSet.hpp"                                                                              
                                                                                                                           
42 #include "memory/iterator.hpp"                                                                                             
43 #include "memory/resourceArea.hpp"                                                                                         
44 #include "oops/access.inline.hpp"                                                                                          
45 #include "oops/oop.inline.hpp"                                                                                             
46 #include "runtime/os.hpp"                                                                                                  
47 #include "utilities/align.hpp"                                                                                             
48 #include "utilities/globalDefinitions.hpp"                                                                                 
49 #include "utilities/intHisto.hpp"                                                                                          
50 #include "utilities/stack.inline.hpp"                                                                                      
51 #include "utilities/ticks.hpp"                                                                                             
52 
53 // Collects information about the overall remembered set scan progress during an evacuation.                               
54 class G1RemSetScanState : public CHeapObj<mtGC> {                                                                          
55 private:                                                                                                                   
56   class G1ClearCardTableTask : public AbstractGangTask {                                                                   
57     G1CollectedHeap* _g1h;                                                                                                 
58     uint* _dirty_region_list;                                                                                              
59     size_t _num_dirty_regions;                                                                                             
60     size_t _chunk_length;                                                                                                  

22  */
23 
24 #include "precompiled.hpp"
25 #include "gc/g1/dirtyCardQueue.hpp"
26 #include "gc/g1/g1BarrierSet.hpp"
27 #include "gc/g1/g1BlockOffsetTable.inline.hpp"
28 #include "gc/g1/g1CardTable.inline.hpp"
29 #include "gc/g1/g1CollectedHeap.inline.hpp"
30 #include "gc/g1/g1ConcurrentRefine.hpp"
31 #include "gc/g1/g1FromCardCache.hpp"
32 #include "gc/g1/g1GCPhaseTimes.hpp"
33 #include "gc/g1/g1HotCardCache.hpp"
34 #include "gc/g1/g1OopClosures.inline.hpp"
35 #include "gc/g1/g1RootClosures.hpp"
36 #include "gc/g1/g1RemSet.hpp"
37 #include "gc/g1/heapRegion.inline.hpp"
38 #include "gc/g1/heapRegionManager.inline.hpp"
39 #include "gc/g1/heapRegionRemSet.hpp"
40 #include "gc/shared/gcTraceTime.inline.hpp"
41 #include "gc/shared/suspendibleThreadSet.hpp"
42 #include "jfr/jfrEvents.hpp"
43 #include "memory/iterator.hpp"
44 #include "memory/resourceArea.hpp"
45 #include "oops/access.inline.hpp"
46 #include "oops/oop.inline.hpp"
47 #include "runtime/os.hpp"
48 #include "utilities/align.hpp"
49 #include "utilities/globalDefinitions.hpp"
50 #include "utilities/intHisto.hpp"
51 #include "utilities/stack.inline.hpp"
52 #include "utilities/ticks.hpp"
53 
54 // Collects information about the overall remembered set scan progress during an evacuation.
55 class G1RemSetScanState : public CHeapObj<mtGC> {
56 private:
57   class G1ClearCardTableTask : public AbstractGangTask {
58     G1CollectedHeap* _g1h;
59     uint* _dirty_region_list;
60     size_t _num_dirty_regions;
61     size_t _chunk_length;

321   _rem_set_root_scan_time(),                                                                                               
322   _rem_set_trim_partially_time(),                                                                                          
323   _strong_code_root_scan_time(),                                                                                           
324   _strong_code_trim_partially_time() {                                                                                     
325 }                                                                                                                          
326 
327 void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){                              
328   _ct->set_card_claimed(card_index);                                                                                       
329   _scan_state->add_dirty_region(region_idx_for_card);                                                                      
330 }                                                                                                                          
331 
332 void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {                                         
333   HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);                                                    
334   _scan_objs_on_card_cl->set_region(card_region);                                                                          
335   card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);                                          
336   _scan_objs_on_card_cl->trim_queue_partially();                                                                           
337   _cards_scanned++;                                                                                                        
338 }                                                                                                                          
339 
340 void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {                                                         
                                                                                                                           
341   uint const region_idx = r->hrm_index();                                                                                  
342 
343   if (_scan_state->claim_iter(region_idx)) {                                                                               
344     // If we ever free the collection set concurrently, we should also                                                     
345     // clear the card table concurrently therefore we won't need to                                                        
346     // add regions of the collection set to the dirty cards region.                                                        
347     _scan_state->add_dirty_region(region_idx);                                                                             
348   }                                                                                                                        
349 
350   // We claim cards in blocks so as to reduce the contention.                                                              
351   size_t const block_size = G1RSetScanBlockSize;                                                                           
352 
353   HeapRegionRemSetIterator iter(r->rem_set());                                                                             
354   size_t card_index;                                                                                                       
355 
356   size_t claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);                                      
357   for (size_t current_card = 0; iter.has_next(card_index); current_card++) {                                               
358     if (current_card >= claimed_card_block + block_size) {                                                                 
359       claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);                                         

322   _rem_set_root_scan_time(),
323   _rem_set_trim_partially_time(),
324   _strong_code_root_scan_time(),
325   _strong_code_trim_partially_time() {
326 }
327 
328 void G1ScanRSForRegionClosure::claim_card(size_t card_index, const uint region_idx_for_card){
329   _ct->set_card_claimed(card_index);
330   _scan_state->add_dirty_region(region_idx_for_card);
331 }
332 
333 void G1ScanRSForRegionClosure::scan_card(MemRegion mr, uint region_idx_for_card) {
334   HeapRegion* const card_region = _g1h->region_at(region_idx_for_card);
335   _scan_objs_on_card_cl->set_region(card_region);
336   card_region->oops_on_card_seq_iterate_careful<true>(mr, _scan_objs_on_card_cl);
337   _scan_objs_on_card_cl->trim_queue_partially();
338   _cards_scanned++;
339 }
340 
341 void G1ScanRSForRegionClosure::scan_rem_set_roots(HeapRegion* r) {
342   EventGCPhaseParallel event;
343   uint const region_idx = r->hrm_index();
344 
345   if (_scan_state->claim_iter(region_idx)) {
346     // If we ever free the collection set concurrently, we should also
347     // clear the card table concurrently therefore we won't need to
348     // add regions of the collection set to the dirty cards region.
349     _scan_state->add_dirty_region(region_idx);
350   }
351 
352   // We claim cards in blocks so as to reduce the contention.
353   size_t const block_size = G1RSetScanBlockSize;
354 
355   HeapRegionRemSetIterator iter(r->rem_set());
356   size_t card_index;
357 
358   size_t claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);
359   for (size_t current_card = 0; iter.has_next(card_index); current_card++) {
360     if (current_card >= claimed_card_block + block_size) {
361       claimed_card_block = _scan_state->iter_claimed_next(region_idx, block_size);

374 
375     assert(_g1h->region_at(region_idx_for_card)->is_in_reserved(card_start),                                               
376            "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)-
377     HeapWord* const top = _scan_state->scan_top(region_idx_for_card);                                                      
378     if (card_start >= top) {                                                                                               
379       continue;                                                                                                            
380     }                                                                                                                      
381 
382     // We claim lazily (so races are possible but they're benign), which reduces the                                       
383     // number of duplicate scans (the rsets of the regions in the cset can intersect).                                     
384     // Claim the card after checking bounds above: the remembered set may contain                                          
385     // random cards into current survivor, and we would then have an incorrectly                                           
386     // claimed card in survivor space. Card table clear does not reset the card table                                      
387     // of survivor space regions.                                                                                          
388     claim_card(card_index, region_idx_for_card);                                                                           
389 
390     MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));                                         
391 
392     scan_card(mr, region_idx_for_card);                                                                                    
393   }                                                                                                                        
                                                                                                                           
394 }                                                                                                                          
395 
396 void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {                                                     
                                                                                                                           
397   r->strong_code_roots_do(_pss->closures()->weak_codeblobs());                                                             
                                                                                                                           
398 }                                                                                                                          
399 
400 bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {                                                             
401   assert(r->in_collection_set(),                                                                                           
402          "Should only be called on elements of the collection set but region %u is not.",                                  
403          r->hrm_index());                                                                                                  
404   uint const region_idx = r->hrm_index();                                                                                  
405 
406   // Do an early out if we know we are complete.                                                                           
407   if (_scan_state->iter_is_complete(region_idx)) {                                                                         
408     return false;                                                                                                          
409   }                                                                                                                        
410 
411   {                                                                                                                        
412     G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);                     
413     scan_rem_set_roots(r);                                                                                                 
414   }                                                                                                                        
415 
416   if (_scan_state->set_iter_complete(region_idx)) {                                                                        

376 
377     assert(_g1h->region_at(region_idx_for_card)->is_in_reserved(card_start),
378            "Card start " PTR_FORMAT " to scan outside of region %u", p2i(card_start), _g1h->region_at(region_idx_for_card)-
379     HeapWord* const top = _scan_state->scan_top(region_idx_for_card);
380     if (card_start >= top) {
381       continue;
382     }
383 
384     // We claim lazily (so races are possible but they're benign), which reduces the
385     // number of duplicate scans (the rsets of the regions in the cset can intersect).
386     // Claim the card after checking bounds above: the remembered set may contain
387     // random cards into current survivor, and we would then have an incorrectly
388     // claimed card in survivor space. Card table clear does not reset the card table
389     // of survivor space regions.
390     claim_card(card_index, region_idx_for_card);
391 
392     MemRegion const mr(card_start, MIN2(card_start + BOTConstants::N_words, top));
393 
394     scan_card(mr, region_idx_for_card);
395   }
396   event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::ScanRS));
397 }
398 
399 void G1ScanRSForRegionClosure::scan_strong_code_roots(HeapRegion* r) {
400   EventGCPhaseParallel event;
401   r->strong_code_roots_do(_pss->closures()->weak_codeblobs());
402   event.commit(GCId::current(), _worker_i, G1GCPhaseTimes::phase_name(G1GCPhaseTimes::CodeRoots));
403 }
404 
405 bool G1ScanRSForRegionClosure::do_heap_region(HeapRegion* r) {
406   assert(r->in_collection_set(),
407          "Should only be called on elements of the collection set but region %u is not.",
408          r->hrm_index());
409   uint const region_idx = r->hrm_index();
410 
411   // Do an early out if we know we are complete.
412   if (_scan_state->iter_is_complete(region_idx)) {
413     return false;
414   }
415 
416   {
417     G1EvacPhaseWithTrimTimeTracker timer(_pss, _rem_set_root_scan_time, _rem_set_trim_partially_time);
418     scan_rem_set_roots(r);
419   }
420 
421   if (_scan_state->set_iter_complete(region_idx)) {
< prev index next >