src/share/vm/gc/g1/g1CollectedHeap.cpp

Print this page




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