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(); |