comparison src/share/vm/gc_implementation/g1/g1MarkSweep.cpp @ 20295:3f2894c5052e

8048112: G1 Full GC needs to support the case when the very first region is not available Summary: Refactor preparation for compaction during Full GC so that it lazily initializes the first compaction point. This also avoids problems later when the first region may not be committed. Also reviewed by K. Barrett. Reviewed-by: brutisso
author tschatzl
date Mon, 21 Jul 2014 10:00:31 +0200
parents 2c6ef90f030a
children d35872270666
comparison
equal deleted inserted replaced
20294:dd219eaec9cc 20295:3f2894c5052e
198 G1CollectedHeap* _g1h; 198 G1CollectedHeap* _g1h;
199 ModRefBarrierSet* _mrbs; 199 ModRefBarrierSet* _mrbs;
200 CompactPoint _cp; 200 CompactPoint _cp;
201 HeapRegionSetCount _humongous_regions_removed; 201 HeapRegionSetCount _humongous_regions_removed;
202 202
203 void free_humongous_region(HeapRegion* hr) { 203 bool is_cp_initialized() const {
204 HeapWord* end = hr->end(); 204 return _cp.space != NULL;
205 FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep"); 205 }
206 206
207 assert(hr->startsHumongous(), 207 void prepare_for_compaction(HeapRegion* hr, HeapWord* end) {
208 "Only the start of a humongous region should be freed."); 208 // If this is the first live region that we came across which we can compact,
209 209 // initialize the CompactPoint.
210 hr->set_containing_set(NULL); 210 if (!is_cp_initialized()) {
211 _humongous_regions_removed.increment(1u, hr->capacity()); 211 _cp.space = hr;
212 212 _cp.threshold = hr->initialize_threshold();
213 _g1h->free_humongous_region(hr, &dummy_free_list, false /* par */); 213 }
214 hr->prepare_for_compaction(&_cp); 214 hr->prepare_for_compaction(&_cp);
215 // Also clear the part of the card table that will be unused after 215 // Also clear the part of the card table that will be unused after
216 // compaction. 216 // compaction.
217 _mrbs->clear(MemRegion(hr->compaction_top(), end)); 217 _mrbs->clear(MemRegion(hr->compaction_top(), end));
218 }
219
220 void free_humongous_region(HeapRegion* hr) {
221 HeapWord* end = hr->end();
222 FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
223
224 assert(hr->startsHumongous(),
225 "Only the start of a humongous region should be freed.");
226
227 hr->set_containing_set(NULL);
228 _humongous_regions_removed.increment(1u, hr->capacity());
229
230 _g1h->free_humongous_region(hr, &dummy_free_list, false /* par */);
231 prepare_for_compaction(hr, end);
218 dummy_free_list.remove_all(); 232 dummy_free_list.remove_all();
219 } 233 }
220 234
221 public: 235 public:
222 G1PrepareCompactClosure(CompactibleSpace* cs) 236 G1PrepareCompactClosure()
223 : _g1h(G1CollectedHeap::heap()), 237 : _g1h(G1CollectedHeap::heap()),
224 _mrbs(_g1h->g1_barrier_set()), 238 _mrbs(_g1h->g1_barrier_set()),
225 _cp(NULL, cs, cs->initialize_threshold()), 239 _cp(NULL),
226 _humongous_regions_removed() { } 240 _humongous_regions_removed() { }
227 241
228 void update_sets() { 242 void update_sets() {
229 // We'll recalculate total used bytes and recreate the free list 243 // We'll recalculate total used bytes and recreate the free list
230 // at the end of the GC, so no point in updating those values here. 244 // at the end of the GC, so no point in updating those values here.
243 } 257 }
244 } else { 258 } else {
245 assert(hr->continuesHumongous(), "Invalid humongous."); 259 assert(hr->continuesHumongous(), "Invalid humongous.");
246 } 260 }
247 } else { 261 } else {
248 hr->prepare_for_compaction(&_cp); 262 prepare_for_compaction(hr, hr->end());
249 // Also clear the part of the card table that will be unused after
250 // compaction.
251 _mrbs->clear(MemRegion(hr->compaction_top(), hr->end()));
252 } 263 }
253 return false; 264 return false;
254 } 265 }
255 }; 266 };
256 267
264 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 275 G1CollectedHeap* g1h = G1CollectedHeap::heap();
265 276
266 GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id()); 277 GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
267 GenMarkSweep::trace("2"); 278 GenMarkSweep::trace("2");
268 279
269 // find the first region 280 G1PrepareCompactClosure blk;
270 HeapRegion* r = g1h->region_at(0);
271 CompactibleSpace* sp = r;
272 if (r->isHumongous() && oop(r->bottom())->is_gc_marked()) {
273 sp = r->next_compaction_space();
274 }
275
276 G1PrepareCompactClosure blk(sp);
277 g1h->heap_region_iterate(&blk); 281 g1h->heap_region_iterate(&blk);
278 blk.update_sets(); 282 blk.update_sets();
279 } 283 }
280 284
281 class G1AdjustPointersClosure: public HeapRegionClosure { 285 class G1AdjustPointersClosure: public HeapRegionClosure {