comparison src/share/vm/gc_implementation/g1/g1MarkSweep.cpp @ 20417:d35872270666

8057658: Enable G1 FullGC extensions Summary: Refactored the G1 FullGC code to enable it to be extended. Reviewed-by: mgerdin, brutisso
author sjohanss
date Tue, 09 Sep 2014 00:05:25 +0200
parents 3f2894c5052e
children 7848fc12602b 38d6febe66af
comparison
equal deleted inserted replaced
20416:99f0593d8c9f 20417:d35872270666
192 } 192 }
193 193
194 gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive); 194 gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
195 } 195 }
196 196
197 class G1PrepareCompactClosure: public HeapRegionClosure {
198 G1CollectedHeap* _g1h;
199 ModRefBarrierSet* _mrbs;
200 CompactPoint _cp;
201 HeapRegionSetCount _humongous_regions_removed;
202
203 bool is_cp_initialized() const {
204 return _cp.space != NULL;
205 }
206
207 void prepare_for_compaction(HeapRegion* hr, HeapWord* end) {
208 // If this is the first live region that we came across which we can compact,
209 // initialize the CompactPoint.
210 if (!is_cp_initialized()) {
211 _cp.space = hr;
212 _cp.threshold = hr->initialize_threshold();
213 }
214 hr->prepare_for_compaction(&_cp);
215 // Also clear the part of the card table that will be unused after
216 // compaction.
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);
232 dummy_free_list.remove_all();
233 }
234
235 public:
236 G1PrepareCompactClosure()
237 : _g1h(G1CollectedHeap::heap()),
238 _mrbs(_g1h->g1_barrier_set()),
239 _cp(NULL),
240 _humongous_regions_removed() { }
241
242 void update_sets() {
243 // We'll recalculate total used bytes and recreate the free list
244 // at the end of the GC, so no point in updating those values here.
245 HeapRegionSetCount empty_set;
246 _g1h->remove_from_old_sets(empty_set, _humongous_regions_removed);
247 }
248
249 bool doHeapRegion(HeapRegion* hr) {
250 if (hr->isHumongous()) {
251 if (hr->startsHumongous()) {
252 oop obj = oop(hr->bottom());
253 if (obj->is_gc_marked()) {
254 obj->forward_to(obj);
255 } else {
256 free_humongous_region(hr);
257 }
258 } else {
259 assert(hr->continuesHumongous(), "Invalid humongous.");
260 }
261 } else {
262 prepare_for_compaction(hr, hr->end());
263 }
264 return false;
265 }
266 };
267 197
268 void G1MarkSweep::mark_sweep_phase2() { 198 void G1MarkSweep::mark_sweep_phase2() {
269 // Now all live objects are marked, compute the new object addresses. 199 // Now all live objects are marked, compute the new object addresses.
270 200
271 // It is not required that we traverse spaces in the same order in 201 // It is not required that we traverse spaces in the same order in
272 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops 202 // phase2, phase3 and phase4, but the ValidateMarkSweep live oops
273 // tracking expects us to do so. See comment under phase4. 203 // tracking expects us to do so. See comment under phase4.
274 204
275 G1CollectedHeap* g1h = G1CollectedHeap::heap();
276
277 GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id()); 205 GCTraceTime tm("phase 2", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
278 GenMarkSweep::trace("2"); 206 GenMarkSweep::trace("2");
279 207
280 G1PrepareCompactClosure blk; 208 prepare_compaction();
281 g1h->heap_region_iterate(&blk);
282 blk.update_sets();
283 } 209 }
284 210
285 class G1AdjustPointersClosure: public HeapRegionClosure { 211 class G1AdjustPointersClosure: public HeapRegionClosure {
286 public: 212 public:
287 bool doHeapRegion(HeapRegion* r) { 213 bool doHeapRegion(HeapRegion* r) {
372 298
373 G1SpaceCompactClosure blk; 299 G1SpaceCompactClosure blk;
374 g1h->heap_region_iterate(&blk); 300 g1h->heap_region_iterate(&blk);
375 301
376 } 302 }
303
304 void G1MarkSweep::prepare_compaction_work(G1PrepareCompactClosure* blk) {
305 G1CollectedHeap* g1h = G1CollectedHeap::heap();
306 g1h->heap_region_iterate(blk);
307 blk->update_sets();
308 }
309
310 void G1PrepareCompactClosure::free_humongous_region(HeapRegion* hr) {
311 HeapWord* end = hr->end();
312 FreeRegionList dummy_free_list("Dummy Free List for G1MarkSweep");
313
314 assert(hr->startsHumongous(),
315 "Only the start of a humongous region should be freed.");
316
317 hr->set_containing_set(NULL);
318 _humongous_regions_removed.increment(1u, hr->capacity());
319
320 _g1h->free_humongous_region(hr, &dummy_free_list, false /* par */);
321 prepare_for_compaction(hr, end);
322 dummy_free_list.remove_all();
323 }
324
325 void G1PrepareCompactClosure::prepare_for_compaction(HeapRegion* hr, HeapWord* end) {
326 // If this is the first live region that we came across which we can compact,
327 // initialize the CompactPoint.
328 if (!is_cp_initialized()) {
329 _cp.space = hr;
330 _cp.threshold = hr->initialize_threshold();
331 }
332 prepare_for_compaction_work(&_cp, hr, end);
333 }
334
335 void G1PrepareCompactClosure::prepare_for_compaction_work(CompactPoint* cp,
336 HeapRegion* hr,
337 HeapWord* end) {
338 hr->prepare_for_compaction(cp);
339 // Also clear the part of the card table that will be unused after
340 // compaction.
341 _mrbs->clear(MemRegion(hr->compaction_top(), end));
342 }
343
344 void G1PrepareCompactClosure::update_sets() {
345 // We'll recalculate total used bytes and recreate the free list
346 // at the end of the GC, so no point in updating those values here.
347 HeapRegionSetCount empty_set;
348 _g1h->remove_from_old_sets(empty_set, _humongous_regions_removed);
349 }
350
351 bool G1PrepareCompactClosure::doHeapRegion(HeapRegion* hr) {
352 if (hr->isHumongous()) {
353 if (hr->startsHumongous()) {
354 oop obj = oop(hr->bottom());
355 if (obj->is_gc_marked()) {
356 obj->forward_to(obj);
357 } else {
358 free_humongous_region(hr);
359 }
360 } else {
361 assert(hr->continuesHumongous(), "Invalid humongous.");
362 }
363 } else {
364 prepare_for_compaction(hr, hr->end());
365 }
366 return false;
367 }