1092 assert(hrrs->occupied() == 0, "RSet should be empty"); 1093 } else { 1094 hrrs->clear(); 1095 } 1096 // You might think here that we could clear just the cards 1097 // corresponding to the used region. But no: if we leave a dirty card 1098 // in a region we might allocate into, then it would prevent that card 1099 // from being enqueued, and cause it to be missed. 1100 // Re: the performance cost: we shouldn't be doing full GC anyway! 1101 _mr_bs->clear(MemRegion(r->bottom(), r->end())); 1102 1103 return false; 1104 } 1105 }; 1106 1107 void G1CollectedHeap::clear_rsets_post_compaction() { 1108 PostMCRemSetClearClosure rs_clear(this, g1_barrier_set()); 1109 heap_region_iterate(&rs_clear); 1110 } 1111 1112 class RebuildRSOutOfRegionClosure: public HeapRegionClosure { 1113 G1CollectedHeap* _g1h; 1114 UpdateRSOopClosure _cl; 1115 public: 1116 RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, uint worker_i = 0) : 1117 _cl(g1->g1_rem_set(), worker_i), 1118 _g1h(g1) 1119 { } 1120 1121 bool doHeapRegion(HeapRegion* r) { 1122 if (!r->is_continues_humongous()) { 1123 _cl.set_from(r); 1124 r->oop_iterate(&_cl); 1125 } 1126 return false; 1127 } 1128 }; 1129 1130 class ParRebuildRSTask: public AbstractGangTask { 1131 G1CollectedHeap* _g1; 1132 HeapRegionClaimer _hrclaimer; 1133 1134 public: 1135 ParRebuildRSTask(G1CollectedHeap* g1) : 1136 AbstractGangTask("ParRebuildRSTask"), _g1(g1), _hrclaimer(g1->workers()->active_workers()) {} 1137 1138 void work(uint worker_id) { 1139 RebuildRSOutOfRegionClosure rebuild_rs(_g1, worker_id); 1140 _g1->heap_region_par_iterate(&rebuild_rs, worker_id, &_hrclaimer); 1141 } 1142 }; 1143 1144 class PostCompactionPrinterClosure: public HeapRegionClosure { 1145 private: 1146 G1HRPrinter* _hr_printer; 1147 public: 1148 bool doHeapRegion(HeapRegion* hr) { 1149 assert(!hr->is_young(), "not expecting to find young regions"); 1150 _hr_printer->post_compaction(hr); 1151 return false; 1152 } 1153 1154 PostCompactionPrinterClosure(G1HRPrinter* hr_printer) 1155 : _hr_printer(hr_printer) { } 1156 }; 1157 1158 void G1CollectedHeap::print_hrm_post_compaction() { 1159 if (_hr_printer.is_active()) { 1160 PostCompactionPrinterClosure cl(hr_printer()); 4583 if (old_regions_removed > 0 || humongous_regions_removed > 0) { 4584 MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag); 4585 _old_set.bulk_remove(old_regions_removed); 4586 _humongous_set.bulk_remove(humongous_regions_removed); 4587 } 4588 4589 } 4590 4591 void G1CollectedHeap::prepend_to_freelist(FreeRegionList* list) { 4592 assert(list != NULL, "list can't be null"); 4593 if (!list->is_empty()) { 4594 MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); 4595 _hrm.insert_list_into_free_list(list); 4596 } 4597 } 4598 4599 void G1CollectedHeap::decrement_summary_bytes(size_t bytes) { 4600 decrease_used(bytes); 4601 } 4602 4603 class G1ParScrubRemSetTask: public AbstractGangTask { 4604 protected: 4605 G1RemSet* _g1rs; 4606 HeapRegionClaimer _hrclaimer; 4607 4608 public: 4609 G1ParScrubRemSetTask(G1RemSet* g1_rs, uint num_workers) : 4610 AbstractGangTask("G1 ScrubRS"), 4611 _g1rs(g1_rs), 4612 _hrclaimer(num_workers) { 4613 } 4614 4615 void work(uint worker_id) { 4616 _g1rs->scrub(worker_id, &_hrclaimer); 4617 } 4618 }; 4619 4620 void G1CollectedHeap::scrub_rem_set() { 4621 uint num_workers = workers()->active_workers(); 4622 G1ParScrubRemSetTask g1_par_scrub_rs_task(g1_rem_set(), num_workers); 4623 workers()->run_task(&g1_par_scrub_rs_task); 4624 } 4625 4626 class G1FreeCollectionSetTask : public AbstractGangTask { 4627 private: 4628 4629 // Closure applied to all regions in the collection set to do work that needs to 4630 // be done serially in a single thread. 4631 class G1SerialFreeCollectionSetClosure : public HeapRegionClosure { 4632 private: 4633 EvacuationInfo* _evacuation_info; 4634 const size_t* _surviving_young_words; 4635 4636 // Bytes used in successfully evacuated regions before the evacuation. 4637 size_t _before_used_bytes; 4638 // Bytes used in unsucessfully evacuated regions before the evacuation 4639 size_t _after_used_bytes; 4640 4641 size_t _bytes_allocated_in_old_since_last_gc; 4642 | 1092 assert(hrrs->occupied() == 0, "RSet should be empty"); 1093 } else { 1094 hrrs->clear(); 1095 } 1096 // You might think here that we could clear just the cards 1097 // corresponding to the used region. But no: if we leave a dirty card 1098 // in a region we might allocate into, then it would prevent that card 1099 // from being enqueued, and cause it to be missed. 1100 // Re: the performance cost: we shouldn't be doing full GC anyway! 1101 _mr_bs->clear(MemRegion(r->bottom(), r->end())); 1102 1103 return false; 1104 } 1105 }; 1106 1107 void G1CollectedHeap::clear_rsets_post_compaction() { 1108 PostMCRemSetClearClosure rs_clear(this, g1_barrier_set()); 1109 heap_region_iterate(&rs_clear); 1110 } 1111 1112 class ParRebuildRSTask: public G1ParallelizeByRegionsTask { 1113 class RebuildRSOutOfRegionClosure: public HeapRegionClosure { 1114 UpdateRSOopClosure _cl; 1115 public: 1116 RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, uint worker_i = 0) : 1117 _cl(g1->g1_rem_set(), worker_i) {} 1118 1119 bool doHeapRegion(HeapRegion* r) { 1120 if (!r->is_continues_humongous()) { 1121 _cl.set_from(r); 1122 r->oop_iterate(&_cl); 1123 } 1124 return false; 1125 } 1126 }; 1127 1128 public: 1129 ParRebuildRSTask(G1CollectedHeap* g1) : 1130 G1ParallelizeByRegionsTask("ParRebuildRSTask", g1->workers()->active_workers()) {} 1131 1132 void work(uint worker_id) { 1133 G1CollectedHeap* g1 = G1CollectedHeap::heap(); 1134 RebuildRSOutOfRegionClosure rebuild_rs(g1, worker_id); 1135 all_heap_regions_work(&rebuild_rs, worker_id); 1136 } 1137 }; 1138 1139 class PostCompactionPrinterClosure: public HeapRegionClosure { 1140 private: 1141 G1HRPrinter* _hr_printer; 1142 public: 1143 bool doHeapRegion(HeapRegion* hr) { 1144 assert(!hr->is_young(), "not expecting to find young regions"); 1145 _hr_printer->post_compaction(hr); 1146 return false; 1147 } 1148 1149 PostCompactionPrinterClosure(G1HRPrinter* hr_printer) 1150 : _hr_printer(hr_printer) { } 1151 }; 1152 1153 void G1CollectedHeap::print_hrm_post_compaction() { 1154 if (_hr_printer.is_active()) { 1155 PostCompactionPrinterClosure cl(hr_printer()); 4578 if (old_regions_removed > 0 || humongous_regions_removed > 0) { 4579 MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag); 4580 _old_set.bulk_remove(old_regions_removed); 4581 _humongous_set.bulk_remove(humongous_regions_removed); 4582 } 4583 4584 } 4585 4586 void G1CollectedHeap::prepend_to_freelist(FreeRegionList* list) { 4587 assert(list != NULL, "list can't be null"); 4588 if (!list->is_empty()) { 4589 MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); 4590 _hrm.insert_list_into_free_list(list); 4591 } 4592 } 4593 4594 void G1CollectedHeap::decrement_summary_bytes(size_t bytes) { 4595 decrease_used(bytes); 4596 } 4597 4598 class G1ParScrubRemSetTask: public G1ParallelizeByRegionsTask { 4599 class G1ScrubRSClosure: public HeapRegionClosure { 4600 G1CardLiveData* _live_data; 4601 public: 4602 G1ScrubRSClosure(G1CardLiveData* live_data) : 4603 _live_data(live_data) {} 4604 4605 bool doHeapRegion(HeapRegion* r) { 4606 if (!r->is_continues_humongous()) { 4607 r->rem_set()->scrub(_live_data); 4608 } 4609 return false; 4610 } 4611 }; 4612 4613 public: 4614 G1ParScrubRemSetTask(uint num_workers) : 4615 G1ParallelizeByRegionsTask("G1 ScrubRS", num_workers) {} 4616 4617 void work(uint worker_id) { 4618 G1CollectedHeap* g1 = G1CollectedHeap::heap(); 4619 G1ScrubRSClosure scrub_cl(&g1->g1_rem_set()->_card_live_data); 4620 all_heap_regions_work(&scrub_cl, worker_id); 4621 } 4622 }; 4623 4624 void G1CollectedHeap::scrub_rem_set() { 4625 uint num_workers = workers()->active_workers(); 4626 G1ParScrubRemSetTask g1_par_scrub_rs_task(num_workers); 4627 workers()->run_task(&g1_par_scrub_rs_task); 4628 } 4629 4630 class G1FreeCollectionSetTask : public AbstractGangTask { 4631 private: 4632 4633 // Closure applied to all regions in the collection set to do work that needs to 4634 // be done serially in a single thread. 4635 class G1SerialFreeCollectionSetClosure : public HeapRegionClosure { 4636 private: 4637 EvacuationInfo* _evacuation_info; 4638 const size_t* _surviving_young_words; 4639 4640 // Bytes used in successfully evacuated regions before the evacuation. 4641 size_t _before_used_bytes; 4642 // Bytes used in unsucessfully evacuated regions before the evacuation 4643 size_t _after_used_bytes; 4644 4645 size_t _bytes_allocated_in_old_since_last_gc; 4646 |