210 }
211
212 _heap->set_bytes_allocated_since_cm(0);
213
214 _heap->set_need_update_refs(false);
215
216 _heap->set_full_gc_in_progress(false);
217 }
218
219 _gc_timer->register_gc_end();
220
221 policy->record_full_gc();
222
223 policy->record_phase_start(ShenandoahCollectorPolicy::full_gc_heapdumps);
224 _heap->post_full_gc_dump(_gc_timer);
225 policy->record_phase_end(ShenandoahCollectorPolicy::full_gc_heapdumps);
226
227 policy->record_phase_end(ShenandoahCollectorPolicy::full_gc);
228
229 oopDesc::set_bs(old_bs);
230 }
231
232 #ifdef ASSERT
233 class VerifyNotForwardedPointersClosure : public MetadataAwareOopClosure {
234 private:
235 template <class T>
236 inline void do_oop_work(T* p) {
237 T o = oopDesc::load_heap_oop(p);
238 if (! oopDesc::is_null(o)) {
239 oop obj = oopDesc::decode_heap_oop_not_null(o);
240 assert(oopDesc::unsafe_equals(obj, ShenandoahBarrierSet::resolve_oop_static_not_null(obj)),
241 "expect forwarded oop");
242 ShenandoahHeap* heap = ShenandoahHeap::heap();
243 if (! heap->is_marked_complete(obj)) {
244 tty->print_cr("ref region humongous? %s", BOOL_TO_STR(heap->heap_region_containing(p)->is_humongous()));
245 }
246 assert(heap->is_marked_complete(obj), "must be marked");
247 assert(! heap->allocated_after_complete_mark_start((HeapWord*) obj), "must be truly marked");
248 }
249 }
477 GCTraceTime(Info, gc, phases) time("Phase 2: Compute new object addresses", _gc_timer);
478 ShenandoahHeap* heap = ShenandoahHeap::heap();
479
480 ShenandoahMCReclaimHumongousRegionClosure cl;
481 heap->heap_region_iterate(&cl);
482
483 // Initialize copy queues.
484 for (uint i = 0; i < heap->max_workers(); i++) {
485 copy_queues[i] = new ShenandoahHeapRegionSet(heap->max_regions());
486 }
487
488 ShenandoahHeapRegionSet* from_regions = heap->regions();
489 from_regions->clear_current_index();
490 ShenandoahPrepareForCompactionTask prepare_task(from_regions, copy_queues);
491 heap->workers()->run_task(&prepare_task);
492 }
493
494 class ShenandoahAdjustPointersClosure : public MetadataAwareOopClosure {
495 private:
496 ShenandoahHeap* _heap;
497
498 public:
499
500 ShenandoahAdjustPointersClosure() : _heap(ShenandoahHeap::heap()) {
501 }
502
503 private:
504 template <class T>
505 inline void do_oop_work(T* p) {
506 T o = oopDesc::load_heap_oop(p);
507 if (! oopDesc::is_null(o)) {
508 oop obj = oopDesc::decode_heap_oop_not_null(o);
509 assert(_heap->is_marked_complete(obj), "must be marked");
510 oop forw = oop(BrooksPointer::get_raw(obj));
511 oopDesc::encode_store_heap_oop(p, forw);
512 }
513 }
514 public:
515 void do_oop(oop* p) {
516 do_oop_work(p);
517 }
518 void do_oop(narrowOop* p) {
519 do_oop_work(p);
520 }
521 };
522
523 class ShenandoahAdjustPointersObjectClosure : public ObjectClosure {
524 private:
525 ShenandoahAdjustPointersClosure* _cl;
526 ShenandoahHeap* _heap;
527 public:
528 ShenandoahAdjustPointersObjectClosure(ShenandoahAdjustPointersClosure* cl) :
529 _cl(cl), _heap(ShenandoahHeap::heap()) {
530 }
531 void do_object(oop p) {
532 assert(_heap->is_marked_complete(p), "must be marked");
533 p->oop_iterate(_cl);
534 }
535 };
536
537 class ShenandoahAdjustPointersTask : public AbstractGangTask {
538 private:
539 ShenandoahHeapRegionSet* _regions;
540 public:
541
542 ShenandoahAdjustPointersTask(ShenandoahHeapRegionSet* regions) :
543 AbstractGangTask("Shenandoah Adjust Pointers Task"),
544 _regions(regions) {
545 }
546
547 void work(uint worker_id) {
548 ShenandoahHeap* heap = ShenandoahHeap::heap();
549 ShenandoahHeapRegion* r = _regions->claim_next();
550 ShenandoahAdjustPointersClosure cl;
551 ShenandoahAdjustPointersObjectClosure obj_cl(&cl);
552 while (r != NULL) {
553 if (! r->is_humongous_continuation()) {
554 heap->marked_object_iterate(r, &obj_cl);
555 }
556 r = _regions->claim_next();
557 }
558 }
559 };
560
561 class ShenandoahAdjustRootPointersTask : public AbstractGangTask {
562 private:
563 ShenandoahRootProcessor* _rp;
564
565 public:
566
567 ShenandoahAdjustRootPointersTask(ShenandoahRootProcessor* rp) :
568 AbstractGangTask("Shenandoah Adjust Root Pointers Task"),
569 _rp(rp) {
570 }
571
572 void work(uint worker_id) {
573 ShenandoahAdjustPointersClosure cl;
574 CLDToOopClosure adjust_cld_closure(&cl, true);
575 MarkingCodeBlobClosure adjust_code_closure(&cl,
576 CodeBlobToOopClosure::FixRelocations);
577
578 _rp->process_all_roots(&cl, &cl,
579 &adjust_cld_closure,
580 &adjust_code_closure, worker_id);
581 }
582 };
583
584 void ShenandoahMarkCompact::phase3_update_references() {
585 GCTraceTime(Info, gc, phases) time("Phase 2: Adjust pointers", _gc_timer);
586 ShenandoahHeap* heap = ShenandoahHeap::heap();
587
588 // Need cleared claim bits for the roots processing
589 ClassLoaderDataGraph::clear_claimed_marks();
590
591 WorkGang* workers = heap->workers();
592 uint nworkers = workers->active_workers();
593 {
594 COMPILER2_PRESENT(DerivedPointerTable::clear());
595
596 ShenandoahRootProcessor rp(heap, nworkers);
597 ShenandoahAdjustRootPointersTask task(&rp);
598 workers->run_task(&task);
599 COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
600 }
601
602 ShenandoahHeapRegionSet* regions = heap->regions();
603 regions->clear_current_index();
604 ShenandoahAdjustPointersTask adjust_pointers_task(regions);
605 workers->run_task(&adjust_pointers_task);
606 }
|
210 }
211
212 _heap->set_bytes_allocated_since_cm(0);
213
214 _heap->set_need_update_refs(false);
215
216 _heap->set_full_gc_in_progress(false);
217 }
218
219 _gc_timer->register_gc_end();
220
221 policy->record_full_gc();
222
223 policy->record_phase_start(ShenandoahCollectorPolicy::full_gc_heapdumps);
224 _heap->post_full_gc_dump(_gc_timer);
225 policy->record_phase_end(ShenandoahCollectorPolicy::full_gc_heapdumps);
226
227 policy->record_phase_end(ShenandoahCollectorPolicy::full_gc);
228
229 oopDesc::set_bs(old_bs);
230
231 if (UseShenandoahMatrix) {
232 if (PrintShenandoahMatrix) {
233 outputStream* log = Log(gc)::info_stream();
234 _heap->connection_matrix()->print_on(log);
235 }
236 }
237 }
238
239 #ifdef ASSERT
240 class VerifyNotForwardedPointersClosure : public MetadataAwareOopClosure {
241 private:
242 template <class T>
243 inline void do_oop_work(T* p) {
244 T o = oopDesc::load_heap_oop(p);
245 if (! oopDesc::is_null(o)) {
246 oop obj = oopDesc::decode_heap_oop_not_null(o);
247 assert(oopDesc::unsafe_equals(obj, ShenandoahBarrierSet::resolve_oop_static_not_null(obj)),
248 "expect forwarded oop");
249 ShenandoahHeap* heap = ShenandoahHeap::heap();
250 if (! heap->is_marked_complete(obj)) {
251 tty->print_cr("ref region humongous? %s", BOOL_TO_STR(heap->heap_region_containing(p)->is_humongous()));
252 }
253 assert(heap->is_marked_complete(obj), "must be marked");
254 assert(! heap->allocated_after_complete_mark_start((HeapWord*) obj), "must be truly marked");
255 }
256 }
484 GCTraceTime(Info, gc, phases) time("Phase 2: Compute new object addresses", _gc_timer);
485 ShenandoahHeap* heap = ShenandoahHeap::heap();
486
487 ShenandoahMCReclaimHumongousRegionClosure cl;
488 heap->heap_region_iterate(&cl);
489
490 // Initialize copy queues.
491 for (uint i = 0; i < heap->max_workers(); i++) {
492 copy_queues[i] = new ShenandoahHeapRegionSet(heap->max_regions());
493 }
494
495 ShenandoahHeapRegionSet* from_regions = heap->regions();
496 from_regions->clear_current_index();
497 ShenandoahPrepareForCompactionTask prepare_task(from_regions, copy_queues);
498 heap->workers()->run_task(&prepare_task);
499 }
500
501 class ShenandoahAdjustPointersClosure : public MetadataAwareOopClosure {
502 private:
503 ShenandoahHeap* _heap;
504 uint _from_idx;
505 public:
506
507 ShenandoahAdjustPointersClosure() : _heap(ShenandoahHeap::heap()) {
508 }
509
510 private:
511 template <class T>
512 inline void do_oop_work(T* p) {
513 T o = oopDesc::load_heap_oop(p);
514 if (! oopDesc::is_null(o)) {
515 oop obj = oopDesc::decode_heap_oop_not_null(o);
516 assert(_heap->is_marked_complete(obj), "must be marked");
517 oop forw = oop(BrooksPointer::get_raw(obj));
518 oopDesc::encode_store_heap_oop(p, forw);
519 if (UseShenandoahMatrix) {
520 if (_heap->is_in_reserved(p)) {
521 assert(_heap->is_in_reserved(forw), "must be in heap");
522 uint to_idx = _heap->heap_region_index_containing(forw);
523 _heap->connection_matrix()->set_connected(_from_idx, to_idx, true);
524 }
525 }
526 }
527 }
528 public:
529 void do_oop(oop* p) {
530 do_oop_work(p);
531 }
532 void do_oop(narrowOop* p) {
533 do_oop_work(p);
534 }
535 void set_from_idx(uint from_idx) {
536 _from_idx = from_idx;
537 }
538 };
539
540 class ShenandoahAdjustPointersObjectClosure : public ObjectClosure {
541 private:
542 ShenandoahAdjustPointersClosure _cl;
543 ShenandoahHeap* _heap;
544 public:
545 ShenandoahAdjustPointersObjectClosure() :
546 _heap(ShenandoahHeap::heap()) {
547 }
548 void do_object(oop p) {
549 assert(_heap->is_marked_complete(p), "must be marked");
550 oop forw = oop(BrooksPointer::get_raw(p));
551 uint from_idx = _heap->heap_region_index_containing(forw);
552 _cl.set_from_idx(from_idx);
553 p->oop_iterate(&_cl);
554 }
555 };
556
557 class ShenandoahAdjustPointersTask : public AbstractGangTask {
558 private:
559 ShenandoahHeapRegionSet* _regions;
560 public:
561
562 ShenandoahAdjustPointersTask(ShenandoahHeapRegionSet* regions) :
563 AbstractGangTask("Shenandoah Adjust Pointers Task"),
564 _regions(regions) {
565 }
566
567 void work(uint worker_id) {
568 ShenandoahHeap* heap = ShenandoahHeap::heap();
569 ShenandoahHeapRegion* r = _regions->claim_next();
570 ShenandoahAdjustPointersObjectClosure obj_cl;
571 while (r != NULL) {
572 if (! r->is_humongous_continuation()) {
573 heap->marked_object_iterate(r, &obj_cl);
574 }
575 r = _regions->claim_next();
576 }
577 }
578 };
579
580 class ShenandoahAdjustRootPointersTask : public AbstractGangTask {
581 private:
582 ShenandoahRootProcessor* _rp;
583
584 public:
585
586 ShenandoahAdjustRootPointersTask(ShenandoahRootProcessor* rp) :
587 AbstractGangTask("Shenandoah Adjust Root Pointers Task"),
588 _rp(rp) {
589 }
590
591 void work(uint worker_id) {
592 ShenandoahAdjustPointersClosure cl;
593 CLDToOopClosure adjust_cld_closure(&cl, true);
594 MarkingCodeBlobClosure adjust_code_closure(&cl,
595 CodeBlobToOopClosure::FixRelocations);
596
597 _rp->process_all_roots(&cl, &cl,
598 &adjust_cld_closure,
599 &adjust_code_closure, worker_id);
600 }
601 };
602
603 void ShenandoahMarkCompact::phase3_update_references() {
604 GCTraceTime(Info, gc, phases) time("Phase 2: Adjust pointers", _gc_timer);
605 ShenandoahHeap* heap = ShenandoahHeap::heap();
606
607 if (UseShenandoahMatrix) {
608 heap->connection_matrix()->clear_all();
609 }
610
611 // Need cleared claim bits for the roots processing
612 ClassLoaderDataGraph::clear_claimed_marks();
613
614 WorkGang* workers = heap->workers();
615 uint nworkers = workers->active_workers();
616 {
617 COMPILER2_PRESENT(DerivedPointerTable::clear());
618
619 ShenandoahRootProcessor rp(heap, nworkers);
620 ShenandoahAdjustRootPointersTask task(&rp);
621 workers->run_task(&task);
622 COMPILER2_PRESENT(DerivedPointerTable::update_pointers());
623 }
624
625 ShenandoahHeapRegionSet* regions = heap->regions();
626 regions->clear_current_index();
627 ShenandoahAdjustPointersTask adjust_pointers_task(regions);
628 workers->run_task(&adjust_pointers_task);
629 }
|