src/hotspot/share/gc/g1/g1RemSet.cpp
changeset 59293 5af9fa90cd7b
parent 59290 97d13893ec3c
child 59319 9ee940f1de90
equal deleted inserted replaced
59292:95b1385dd476 59293:5af9fa90cd7b
   195         }
   195         }
   196       }
   196       }
   197     }
   197     }
   198   };
   198   };
   199 
   199 
   200   // Creates a snapshot of the current _top values at the start of collection to
       
   201   // filter out card marks that we do not want to scan.
       
   202   class G1ResetScanTopClosure : public HeapRegionClosure {
       
   203     G1RemSetScanState* _scan_state;
       
   204 
       
   205   public:
       
   206     G1ResetScanTopClosure(G1RemSetScanState* scan_state) : _scan_state(scan_state) { }
       
   207 
       
   208     virtual bool do_heap_region(HeapRegion* r) {
       
   209       uint hrm_index = r->hrm_index();
       
   210       if (r->in_collection_set()) {
       
   211         // Young regions had their card table marked as young at their allocation;
       
   212         // we need to make sure that these marks are cleared at the end of GC, *but*
       
   213         // they should not be scanned for cards.
       
   214         // So directly add them to the "all_dirty_regions".
       
   215         // Same for regions in the (initial) collection set: they may contain cards from
       
   216         // the log buffers, make sure they are cleaned.
       
   217         _scan_state->add_all_dirty_region(hrm_index);
       
   218        } else if (r->is_old_or_humongous_or_archive()) {
       
   219         _scan_state->set_scan_top(hrm_index, r->top());
       
   220        }
       
   221        return false;
       
   222      }
       
   223   };
       
   224   // For each region, contains the maximum top() value to be used during this garbage
   200   // For each region, contains the maximum top() value to be used during this garbage
   225   // collection. Subsumes common checks like filtering out everything but old and
   201   // collection. Subsumes common checks like filtering out everything but old and
   226   // humongous regions outside the collection set.
   202   // humongous regions outside the collection set.
   227   // This is valid because we are not interested in scanning stray remembered set
   203   // This is valid because we are not interested in scanning stray remembered set
   228   // entries from free or archive regions.
   204   // entries from free or archive regions.
   327     _scan_chunks_shift = (uint8_t)log2_intptr(HeapRegion::CardsPerRegion / _scan_chunks_per_region);
   303     _scan_chunks_shift = (uint8_t)log2_intptr(HeapRegion::CardsPerRegion / _scan_chunks_per_region);
   328     _scan_top = NEW_C_HEAP_ARRAY(HeapWord*, max_regions, mtGC);
   304     _scan_top = NEW_C_HEAP_ARRAY(HeapWord*, max_regions, mtGC);
   329   }
   305   }
   330 
   306 
   331   void prepare() {
   307   void prepare() {
   332     for (size_t i = 0; i < _max_regions; i++) {
       
   333       _collection_set_iter_state[i] = false;
       
   334       clear_scan_top((uint)i);
       
   335     }
       
   336 
       
   337     _all_dirty_regions = new G1DirtyRegions(_max_regions);
   308     _all_dirty_regions = new G1DirtyRegions(_max_regions);
   338     _next_dirty_regions = new G1DirtyRegions(_max_regions);
   309     _next_dirty_regions = new G1DirtyRegions(_max_regions);
   339 
       
   340     G1ResetScanTopClosure cl(this);
       
   341     G1CollectedHeap::heap()->heap_region_iterate(&cl);
       
   342   }
   310   }
   343 
   311 
   344   void prepare_for_merge_heap_roots() {
   312   void prepare_for_merge_heap_roots() {
   345     _all_dirty_regions->merge(_next_dirty_regions);
   313     _all_dirty_regions->merge(_next_dirty_regions);
   346 
   314 
   427       cur++;
   395       cur++;
   428       if (cur == _next_dirty_regions->size()) {
   396       if (cur == _next_dirty_regions->size()) {
   429         cur = 0;
   397         cur = 0;
   430       }
   398       }
   431     } while (cur != start_pos);
   399     } while (cur != start_pos);
       
   400   }
       
   401 
       
   402   void reset_region_claim(uint region_idx) {
       
   403     _collection_set_iter_state[region_idx] = false;
   432   }
   404   }
   433 
   405 
   434   // Attempt to claim the given region in the collection set for iteration. Returns true
   406   // Attempt to claim the given region in the collection set for iteration. Returns true
   435   // if this call caused the transition from Unclaimed to Claimed.
   407   // if this call caused the transition from Unclaimed to Claimed.
   436   inline bool claim_collection_set_region(uint region) {
   408   inline bool claim_collection_set_region(uint region) {
   908     p->record_or_add_thread_work_item(scan_phase, worker_id, cl.opt_refs_scanned(), G1GCPhaseTimes::ScanHRScannedOptRefs);
   880     p->record_or_add_thread_work_item(scan_phase, worker_id, cl.opt_refs_scanned(), G1GCPhaseTimes::ScanHRScannedOptRefs);
   909     p->record_or_add_thread_work_item(scan_phase, worker_id, cl.opt_refs_memory_used(), G1GCPhaseTimes::ScanHRUsedMemory);
   881     p->record_or_add_thread_work_item(scan_phase, worker_id, cl.opt_refs_memory_used(), G1GCPhaseTimes::ScanHRUsedMemory);
   910   }
   882   }
   911 }
   883 }
   912 
   884 
       
   885 void G1RemSet::prepare_region_for_scan(HeapRegion* region) {
       
   886   uint hrm_index = region->hrm_index();
       
   887 
       
   888   _scan_state->reset_region_claim(hrm_index);
       
   889   if (region->in_collection_set()) {
       
   890     // Young regions had their card table marked as young at their allocation;
       
   891     // we need to make sure that these marks are cleared at the end of GC, *but*
       
   892     // they should not be scanned for cards.
       
   893     // So directly add them to the "all_dirty_regions".
       
   894     // Same for regions in the (initial) collection set: they may contain cards from
       
   895     // the log buffers, make sure they are cleaned.
       
   896     _scan_state->clear_scan_top(hrm_index);
       
   897     _scan_state->add_all_dirty_region(hrm_index);
       
   898   } else if (region->is_old_or_humongous_or_archive()) {
       
   899     _scan_state->set_scan_top(hrm_index, region->top());
       
   900   } else {
       
   901     assert(region->is_free(), "Should only be free region at this point %s", region->get_type_str());
       
   902   }
       
   903 }
       
   904 
   913 void G1RemSet::prepare_for_scan_heap_roots() {
   905 void G1RemSet::prepare_for_scan_heap_roots() {
   914   G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
   906   G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
   915   dcqs.concatenate_logs();
   907   dcqs.concatenate_logs();
   916 
   908 
   917   _scan_state->prepare();
   909   _scan_state->prepare();
  1235   if (log_is_enabled(Debug, gc, remset)) {
  1227   if (log_is_enabled(Debug, gc, remset)) {
  1236     print_merge_heap_roots_stats();
  1228     print_merge_heap_roots_stats();
  1237   }
  1229   }
  1238 }
  1230 }
  1239 
  1231 
  1240 void G1RemSet::prepare_for_scan_heap_roots(uint region_idx) {
  1232 void G1RemSet::exclude_region_from_scan(uint region_idx) {
  1241   _scan_state->clear_scan_top(region_idx);
  1233   _scan_state->clear_scan_top(region_idx);
  1242 }
  1234 }
  1243 
  1235 
  1244 void G1RemSet::cleanup_after_scan_heap_roots() {
  1236 void G1RemSet::cleanup_after_scan_heap_roots() {
  1245   G1GCPhaseTimes* phase_times = _g1h->phase_times();
  1237   G1GCPhaseTimes* phase_times = _g1h->phase_times();