264 // Note: we can verify only the heap here. When an object is 265 // marked, the previous value of the mark word (including 266 // identity hash values, ages, etc) is preserved, and the mark 267 // word is set to markOop::marked_value - effectively removing 268 // any hash values from the mark word. These hash values are 269 // used when verifying the dictionaries and so removing them 270 // from the mark word can make verification of the dictionaries 271 // fail. At the end of the GC, the original mark word values 272 // (including hash values) are restored to the appropriate 273 // objects. 274 // Universe::heap()->verify(VerifySilently, VerifyOption_G1UseMarkWord); 275 _heap->verify(VerifyOption_G1UseMarkWord); 276 } 277 278 #ifdef ASSERT 279 ShenandoahMCVerifyAfterMarkingRegionClosure cl; 280 _heap->heap_region_iterate(&cl); 281 #endif 282 } 283 284 class ShenandoahPrepareForCompactionObjectClosure : public ObjectClosure { 285 286 private: 287 288 ShenandoahHeap* _heap; 289 ShenandoahHeapRegionSet* _to_regions; 290 ShenandoahHeapRegion* _to_region; 291 ShenandoahHeapRegion* _from_region; 292 HeapWord* _compact_point; 293 294 public: 295 296 ShenandoahPrepareForCompactionObjectClosure(ShenandoahHeapRegionSet* to_regions, ShenandoahHeapRegion* to_region) : 297 _heap(ShenandoahHeap::heap()), 298 _to_regions(to_regions), 299 _to_region(to_region), 300 _from_region(NULL), 301 _compact_point(to_region->bottom()) { 302 } 303 381 from_region = next_from_region(copy_queue); 382 } 383 assert(cl.to_region() != NULL, "should not happen"); 384 cl.to_region()->set_new_top(cl.compact_point()); 385 while (to_regions->count() > 0) { 386 ShenandoahHeapRegion* r = to_regions->next(); 387 if (r == NULL) { 388 to_regions->print(); 389 } 390 assert(r != NULL, "should not happen"); 391 r->set_new_top(r->bottom()); 392 } 393 delete to_regions; 394 } 395 }; 396 397 void ShenandoahMarkCompact::phase2_calculate_target_addresses(ShenandoahHeapRegionSet** copy_queues) { 398 GCTraceTime(Info, gc, phases) time("Phase 2: Compute new object addresses", _gc_timer); 399 ShenandoahHeap* heap = ShenandoahHeap::heap(); 400 401 // Initialize copy queues. 402 for (uint i = 0; i < heap->max_parallel_workers(); i++) { 403 copy_queues[i] = new ShenandoahHeapRegionSet(heap->max_regions()); 404 } 405 406 ShenandoahHeapRegionSet* from_regions = heap->regions(); 407 from_regions->clear_current_index(); 408 ShenandoahPrepareForCompactionTask prepare_task(from_regions, copy_queues); 409 heap->workers()->run_task(&prepare_task); 410 } 411 412 class ShenandoahAdjustPointersClosure : public MetadataAwareOopClosure { 413 private: 414 ShenandoahHeap* _heap; 415 416 public: 417 418 ShenandoahAdjustPointersClosure() : _heap(ShenandoahHeap::heap()) { 419 } 420 561 } 562 } 563 }; 564 565 class ShenandoahPostCompactClosure : public ShenandoahHeapRegionClosure { 566 size_t _live; 567 ShenandoahHeap* _heap; 568 public: 569 570 ShenandoahPostCompactClosure() : _live(0), _heap(ShenandoahHeap::heap()) { 571 _heap->clear_free_regions(); 572 } 573 574 bool doHeapRegion(ShenandoahHeapRegion* r) { 575 // Need to reset the complete-top-at-mark-start pointer here because 576 // the complete marking bitmap is no longer valid. This ensures 577 // size-based iteration in marked_object_iterate(). 578 _heap->set_complete_top_at_mark_start(r->bottom(), r->bottom()); 579 r->set_in_collection_set(false); 580 if (r->is_humongous()) { 581 if (r->is_humongous_start()) { 582 oop humongous_obj = oop(r->bottom() + BrooksPointer::word_size()); 583 if (! _heap->is_marked_complete(humongous_obj)) { 584 _heap->reclaim_humongous_region_at(r); 585 } else { 586 _live += ShenandoahHeapRegion::RegionSizeBytes; 587 } 588 } else { 589 _live += ShenandoahHeapRegion::RegionSizeBytes; 590 } 591 592 } else { 593 size_t live = r->used(); 594 if (live == 0) { 595 r->recycle(); 596 _heap->add_free_region(r); 597 } 598 r->set_live_data(live); 599 _live += live; 600 } 601 return false; 602 } 603 604 size_t get_live() { return _live; } 605 606 }; 607 608 void ShenandoahMarkCompact::phase4_compact_objects(ShenandoahHeapRegionSet** copy_queues) { 609 GCTraceTime(Info, gc, phases) time("Phase 4: Move objects", _gc_timer); 610 ShenandoahHeap* heap = ShenandoahHeap::heap(); 611 ShenandoahCompactObjectsTask compact_task(copy_queues); | 264 // Note: we can verify only the heap here. When an object is 265 // marked, the previous value of the mark word (including 266 // identity hash values, ages, etc) is preserved, and the mark 267 // word is set to markOop::marked_value - effectively removing 268 // any hash values from the mark word. These hash values are 269 // used when verifying the dictionaries and so removing them 270 // from the mark word can make verification of the dictionaries 271 // fail. At the end of the GC, the original mark word values 272 // (including hash values) are restored to the appropriate 273 // objects. 274 // Universe::heap()->verify(VerifySilently, VerifyOption_G1UseMarkWord); 275 _heap->verify(VerifyOption_G1UseMarkWord); 276 } 277 278 #ifdef ASSERT 279 ShenandoahMCVerifyAfterMarkingRegionClosure cl; 280 _heap->heap_region_iterate(&cl); 281 #endif 282 } 283 284 class ShenandoahMCReclaimHumongousRegionClosure : public ShenandoahHeapRegionClosure { 285 private: 286 ShenandoahHeap* _heap; 287 public: 288 ShenandoahMCReclaimHumongousRegionClosure() : _heap(ShenandoahHeap::heap()) { 289 } 290 291 bool doHeapRegion(ShenandoahHeapRegion* r) { 292 if (r->is_humongous_start()) { 293 oop humongous_obj = oop(r->bottom() + BrooksPointer::word_size()); 294 if (! _heap->is_marked_complete(humongous_obj)) { 295 _heap->reclaim_humongous_region_at(r); 296 } 297 } 298 return false; 299 } 300 }; 301 302 303 class ShenandoahPrepareForCompactionObjectClosure : public ObjectClosure { 304 305 private: 306 307 ShenandoahHeap* _heap; 308 ShenandoahHeapRegionSet* _to_regions; 309 ShenandoahHeapRegion* _to_region; 310 ShenandoahHeapRegion* _from_region; 311 HeapWord* _compact_point; 312 313 public: 314 315 ShenandoahPrepareForCompactionObjectClosure(ShenandoahHeapRegionSet* to_regions, ShenandoahHeapRegion* to_region) : 316 _heap(ShenandoahHeap::heap()), 317 _to_regions(to_regions), 318 _to_region(to_region), 319 _from_region(NULL), 320 _compact_point(to_region->bottom()) { 321 } 322 400 from_region = next_from_region(copy_queue); 401 } 402 assert(cl.to_region() != NULL, "should not happen"); 403 cl.to_region()->set_new_top(cl.compact_point()); 404 while (to_regions->count() > 0) { 405 ShenandoahHeapRegion* r = to_regions->next(); 406 if (r == NULL) { 407 to_regions->print(); 408 } 409 assert(r != NULL, "should not happen"); 410 r->set_new_top(r->bottom()); 411 } 412 delete to_regions; 413 } 414 }; 415 416 void ShenandoahMarkCompact::phase2_calculate_target_addresses(ShenandoahHeapRegionSet** copy_queues) { 417 GCTraceTime(Info, gc, phases) time("Phase 2: Compute new object addresses", _gc_timer); 418 ShenandoahHeap* heap = ShenandoahHeap::heap(); 419 420 ShenandoahMCReclaimHumongousRegionClosure cl; 421 heap->heap_region_iterate(&cl); 422 423 // Initialize copy queues. 424 for (uint i = 0; i < heap->max_parallel_workers(); i++) { 425 copy_queues[i] = new ShenandoahHeapRegionSet(heap->max_regions()); 426 } 427 428 ShenandoahHeapRegionSet* from_regions = heap->regions(); 429 from_regions->clear_current_index(); 430 ShenandoahPrepareForCompactionTask prepare_task(from_regions, copy_queues); 431 heap->workers()->run_task(&prepare_task); 432 } 433 434 class ShenandoahAdjustPointersClosure : public MetadataAwareOopClosure { 435 private: 436 ShenandoahHeap* _heap; 437 438 public: 439 440 ShenandoahAdjustPointersClosure() : _heap(ShenandoahHeap::heap()) { 441 } 442 583 } 584 } 585 }; 586 587 class ShenandoahPostCompactClosure : public ShenandoahHeapRegionClosure { 588 size_t _live; 589 ShenandoahHeap* _heap; 590 public: 591 592 ShenandoahPostCompactClosure() : _live(0), _heap(ShenandoahHeap::heap()) { 593 _heap->clear_free_regions(); 594 } 595 596 bool doHeapRegion(ShenandoahHeapRegion* r) { 597 // Need to reset the complete-top-at-mark-start pointer here because 598 // the complete marking bitmap is no longer valid. This ensures 599 // size-based iteration in marked_object_iterate(). 600 _heap->set_complete_top_at_mark_start(r->bottom(), r->bottom()); 601 r->set_in_collection_set(false); 602 if (r->is_humongous()) { 603 _live += ShenandoahHeapRegion::RegionSizeBytes; 604 } else { 605 size_t live = r->used(); 606 if (live == 0) { 607 r->recycle(); 608 _heap->add_free_region(r); 609 } 610 r->set_live_data(live); 611 _live += live; 612 } 613 return false; 614 } 615 616 size_t get_live() { return _live; } 617 618 }; 619 620 void ShenandoahMarkCompact::phase4_compact_objects(ShenandoahHeapRegionSet** copy_queues) { 621 GCTraceTime(Info, gc, phases) time("Phase 4: Move objects", _gc_timer); 622 ShenandoahHeap* heap = ShenandoahHeap::heap(); 623 ShenandoahCompactObjectsTask compact_task(copy_queues); |