1952 size_t n_completed_buffers = 0; |
1952 size_t n_completed_buffers = 0; |
1953 while (dcqs.apply_closure_during_gc(cl, worker_i)) { |
1953 while (dcqs.apply_closure_during_gc(cl, worker_i)) { |
1954 n_completed_buffers++; |
1954 n_completed_buffers++; |
1955 } |
1955 } |
1956 assert(dcqs.completed_buffers_num() == 0, "Completed buffers exist!"); |
1956 assert(dcqs.completed_buffers_num() == 0, "Completed buffers exist!"); |
1957 phase_times()->record_thread_work_item(G1GCPhaseTimes::UpdateRS, worker_i, n_completed_buffers, G1GCPhaseTimes::UpdateRSProcessedBuffers); |
1957 phase_times()->record_thread_work_item(G1GCPhaseTimes::MergeLB, worker_i, n_completed_buffers, G1GCPhaseTimes::MergeLBProcessedBuffers); |
1958 } |
1958 } |
1959 |
1959 |
1960 // Computes the sum of the storage used by the various regions. |
1960 // Computes the sum of the storage used by the various regions. |
1961 size_t G1CollectedHeap::used() const { |
1961 size_t G1CollectedHeap::used() const { |
1962 size_t result = _summary_bytes_used + _allocator->used_in_alloc_regions(); |
1962 size_t result = _summary_bytes_used + _allocator->used_in_alloc_regions(); |
2236 |
2236 |
2237 void G1CollectedHeap::collection_set_iterate_all(HeapRegionClosure* cl) { |
2237 void G1CollectedHeap::collection_set_iterate_all(HeapRegionClosure* cl) { |
2238 _collection_set.iterate(cl); |
2238 _collection_set.iterate(cl); |
2239 } |
2239 } |
2240 |
2240 |
2241 void G1CollectedHeap::collection_set_iterate_increment_from(HeapRegionClosure *cl, uint worker_id) { |
2241 void G1CollectedHeap::collection_set_iterate_increment_from(HeapRegionClosure *cl, HeapRegionClaimer* hr_claimer, uint worker_id) { |
2242 _collection_set.iterate_incremental_part_from(cl, worker_id, workers()->active_workers()); |
2242 _collection_set.iterate_incremental_part_from(cl, hr_claimer, worker_id, workers()->active_workers()); |
2243 } |
2243 } |
2244 |
2244 |
2245 HeapWord* G1CollectedHeap::block_start(const void* addr) const { |
2245 HeapWord* G1CollectedHeap::block_start(const void* addr) const { |
2246 HeapRegion* hr = heap_region_containing(addr); |
2246 HeapRegion* hr = heap_region_containing(addr); |
2247 return hr->block_start(addr); |
2247 return hr->block_start(addr); |
2627 |
2627 |
2628 class RegisterRegionsWithRegionAttrTableClosure : public HeapRegionClosure { |
2628 class RegisterRegionsWithRegionAttrTableClosure : public HeapRegionClosure { |
2629 private: |
2629 private: |
2630 size_t _total_humongous; |
2630 size_t _total_humongous; |
2631 size_t _candidate_humongous; |
2631 size_t _candidate_humongous; |
2632 |
|
2633 G1DirtyCardQueue _dcq; |
|
2634 |
2632 |
2635 bool humongous_region_is_candidate(G1CollectedHeap* g1h, HeapRegion* region) const { |
2633 bool humongous_region_is_candidate(G1CollectedHeap* g1h, HeapRegion* region) const { |
2636 assert(region->is_starts_humongous(), "Must start a humongous object"); |
2634 assert(region->is_starts_humongous(), "Must start a humongous object"); |
2637 |
2635 |
2638 oop obj = oop(region->bottom()); |
2636 oop obj = oop(region->bottom()); |
2705 |
2702 |
2706 bool is_candidate = humongous_region_is_candidate(g1h, r); |
2703 bool is_candidate = humongous_region_is_candidate(g1h, r); |
2707 uint rindex = r->hrm_index(); |
2704 uint rindex = r->hrm_index(); |
2708 g1h->set_humongous_reclaim_candidate(rindex, is_candidate); |
2705 g1h->set_humongous_reclaim_candidate(rindex, is_candidate); |
2709 if (is_candidate) { |
2706 if (is_candidate) { |
|
2707 g1h->register_humongous_region_with_region_attr(rindex); |
2710 _candidate_humongous++; |
2708 _candidate_humongous++; |
2711 g1h->register_humongous_region_with_region_attr(rindex); |
2709 // We will later handle the remembered sets of these regions. |
2712 // Is_candidate already filters out humongous object with large remembered sets. |
|
2713 // If we have a humongous object with a few remembered sets, we simply flush these |
|
2714 // remembered set entries into the DCQS. That will result in automatic |
|
2715 // re-evaluation of their remembered set entries during the following evacuation |
|
2716 // phase. |
|
2717 if (!r->rem_set()->is_empty()) { |
|
2718 guarantee(r->rem_set()->occupancy_less_or_equal_than(G1RSetSparseRegionEntries), |
|
2719 "Found a not-small remembered set here. This is inconsistent with previous assumptions."); |
|
2720 G1CardTable* ct = g1h->card_table(); |
|
2721 HeapRegionRemSetIterator hrrs(r->rem_set()); |
|
2722 size_t card_index; |
|
2723 while (hrrs.has_next(card_index)) { |
|
2724 CardTable::CardValue* card_ptr = ct->byte_for_index(card_index); |
|
2725 // The remembered set might contain references to already freed |
|
2726 // regions. Filter out such entries to avoid failing card table |
|
2727 // verification. |
|
2728 if (g1h->is_in(ct->addr_for(card_ptr))) { |
|
2729 if (*card_ptr != G1CardTable::dirty_card_val()) { |
|
2730 *card_ptr = G1CardTable::dirty_card_val(); |
|
2731 _dcq.enqueue(card_ptr); |
|
2732 } |
|
2733 } |
|
2734 } |
|
2735 assert(hrrs.n_yielded() == r->rem_set()->occupied(), |
|
2736 "Remembered set hash maps out of sync, cur: " SIZE_FORMAT " entries, next: " SIZE_FORMAT " entries", |
|
2737 hrrs.n_yielded(), r->rem_set()->occupied()); |
|
2738 // We should only clear the card based remembered set here as we will not |
|
2739 // implicitly rebuild anything else during eager reclaim. Note that at the moment |
|
2740 // (and probably never) we do not enter this path if there are other kind of |
|
2741 // remembered sets for this region. |
|
2742 r->rem_set()->clear_locked(true /* only_cardset */); |
|
2743 // Clear_locked() above sets the state to Empty. However we want to continue |
|
2744 // collecting remembered set entries for humongous regions that were not |
|
2745 // reclaimed. |
|
2746 r->rem_set()->set_state_complete(); |
|
2747 #ifdef ASSERT |
|
2748 G1HeapRegionAttr region_attr = g1h->region_attr(oop(r->bottom())); |
|
2749 assert(region_attr.needs_remset_update(), "must be"); |
|
2750 #endif |
|
2751 } |
|
2752 assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty."); |
|
2753 } else { |
2710 } else { |
2754 g1h->register_region_with_region_attr(r); |
2711 g1h->register_region_with_region_attr(r); |
2755 } |
2712 } |
2756 _total_humongous++; |
2713 _total_humongous++; |
2757 |
2714 |
2758 return false; |
2715 return false; |
2759 } |
2716 } |
2760 |
2717 |
2761 size_t total_humongous() const { return _total_humongous; } |
2718 size_t total_humongous() const { return _total_humongous; } |
2762 size_t candidate_humongous() const { return _candidate_humongous; } |
2719 size_t candidate_humongous() const { return _candidate_humongous; } |
2763 |
|
2764 void flush_rem_set_entries() { _dcq.flush(); } |
|
2765 }; |
2720 }; |
2766 |
2721 |
2767 void G1CollectedHeap::register_regions_with_region_attr() { |
2722 void G1CollectedHeap::register_regions_with_region_attr() { |
2768 Ticks start = Ticks::now(); |
2723 Ticks start = Ticks::now(); |
2769 |
2724 |
2772 |
2727 |
2773 phase_times()->record_register_regions((Ticks::now() - start).seconds() * 1000.0, |
2728 phase_times()->record_register_regions((Ticks::now() - start).seconds() * 1000.0, |
2774 cl.total_humongous(), |
2729 cl.total_humongous(), |
2775 cl.candidate_humongous()); |
2730 cl.candidate_humongous()); |
2776 _has_humongous_reclaim_candidates = cl.candidate_humongous() > 0; |
2731 _has_humongous_reclaim_candidates = cl.candidate_humongous() > 0; |
2777 |
|
2778 // Finally flush all remembered set entries to re-check into the global DCQS. |
|
2779 cl.flush_rem_set_entries(); |
|
2780 } |
2732 } |
2781 |
2733 |
2782 #ifndef PRODUCT |
2734 #ifndef PRODUCT |
2783 void G1CollectedHeap::verify_region_attr_remset_update() { |
2735 void G1CollectedHeap::verify_region_attr_remset_update() { |
2784 class VerifyRegionAttrRemSet : public HeapRegionClosure { |
2736 class VerifyRegionAttrRemSet : public HeapRegionClosure { |
3069 |
3021 |
3070 G1ParScanThreadStateSet per_thread_states(this, |
3022 G1ParScanThreadStateSet per_thread_states(this, |
3071 workers()->active_workers(), |
3023 workers()->active_workers(), |
3072 collection_set()->young_region_length(), |
3024 collection_set()->young_region_length(), |
3073 collection_set()->optional_region_length()); |
3025 collection_set()->optional_region_length()); |
3074 pre_evacuate_collection_set(evacuation_info); |
3026 pre_evacuate_collection_set(evacuation_info, &per_thread_states); |
3075 |
3027 |
3076 // Actually do the work... |
3028 // Actually do the work... |
3077 evacuate_initial_collection_set(&per_thread_states); |
3029 evacuate_initial_collection_set(&per_thread_states); |
3078 |
3030 |
3079 if (_collection_set.optional_region_length() != 0) { |
3031 if (_collection_set.optional_region_length() != 0) { |
3102 |
3054 |
3103 expand_heap_after_young_collection(); |
3055 expand_heap_after_young_collection(); |
3104 |
3056 |
3105 double sample_end_time_sec = os::elapsedTime(); |
3057 double sample_end_time_sec = os::elapsedTime(); |
3106 double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS; |
3058 double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS; |
3107 size_t total_cards_scanned = phase_times()->sum_thread_work_items(G1GCPhaseTimes::ScanRS, G1GCPhaseTimes::ScanRSScannedCards) + |
3059 policy()->record_collection_pause_end(pause_time_ms, heap_used_bytes_before_gc); |
3108 phase_times()->sum_thread_work_items(G1GCPhaseTimes::OptScanRS, G1GCPhaseTimes::ScanRSScannedCards); |
|
3109 policy()->record_collection_pause_end(pause_time_ms, total_cards_scanned, heap_used_bytes_before_gc); |
|
3110 } |
3060 } |
3111 |
3061 |
3112 verify_after_young_collection(verify_type); |
3062 verify_after_young_collection(verify_type); |
3113 |
3063 |
3114 #ifdef TRACESPINNING |
3064 #ifdef TRACESPINNING |
3578 double merge_pss_time_start = os::elapsedTime(); |
3528 double merge_pss_time_start = os::elapsedTime(); |
3579 per_thread_states->flush(); |
3529 per_thread_states->flush(); |
3580 phase_times()->record_merge_pss_time_ms((os::elapsedTime() - merge_pss_time_start) * 1000.0); |
3530 phase_times()->record_merge_pss_time_ms((os::elapsedTime() - merge_pss_time_start) * 1000.0); |
3581 } |
3531 } |
3582 |
3532 |
3583 void G1CollectedHeap::pre_evacuate_collection_set(G1EvacuationInfo& evacuation_info) { |
3533 void G1CollectedHeap::pre_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) { |
3584 _expand_heap_after_alloc_failure = true; |
3534 _expand_heap_after_alloc_failure = true; |
3585 _evacuation_failed = false; |
3535 _evacuation_failed = false; |
3586 |
3536 |
3587 // Disable the hot card cache. |
3537 // Disable the hot card cache. |
3588 _hot_card_cache->reset_hot_cache_claimed_index(); |
3538 _hot_card_cache->reset_hot_cache_claimed_index(); |
3589 _hot_card_cache->set_use_cache(false); |
3539 _hot_card_cache->set_use_cache(false); |
3590 |
3540 |
3591 // Initialize the GC alloc regions. |
3541 // Initialize the GC alloc regions. |
3592 _allocator->init_gc_alloc_regions(evacuation_info); |
3542 _allocator->init_gc_alloc_regions(evacuation_info); |
3593 |
3543 |
|
3544 { |
|
3545 Ticks start = Ticks::now(); |
|
3546 rem_set()->prepare_for_scan_heap_roots(); |
|
3547 phase_times()->record_prepare_heap_roots_time_ms((Ticks::now() - start).seconds() * 1000.0); |
|
3548 } |
|
3549 |
3594 register_regions_with_region_attr(); |
3550 register_regions_with_region_attr(); |
3595 assert(_verifier->check_region_attr_table(), "Inconsistency in the region attributes table."); |
3551 assert(_verifier->check_region_attr_table(), "Inconsistency in the region attributes table."); |
3596 |
3552 |
3597 rem_set()->prepare_for_scan_rem_set(); |
|
3598 _preserved_marks_set.assert_empty(); |
3553 _preserved_marks_set.assert_empty(); |
3599 |
3554 |
3600 #if COMPILER2_OR_JVMCI |
3555 #if COMPILER2_OR_JVMCI |
3601 DerivedPointerTable::clear(); |
3556 DerivedPointerTable::clear(); |
3602 #endif |
3557 #endif |
3694 class G1EvacuateRegionsTask : public G1EvacuateRegionsBaseTask { |
3649 class G1EvacuateRegionsTask : public G1EvacuateRegionsBaseTask { |
3695 G1RootProcessor* _root_processor; |
3650 G1RootProcessor* _root_processor; |
3696 |
3651 |
3697 void scan_roots(G1ParScanThreadState* pss, uint worker_id) { |
3652 void scan_roots(G1ParScanThreadState* pss, uint worker_id) { |
3698 _root_processor->evacuate_roots(pss, worker_id); |
3653 _root_processor->evacuate_roots(pss, worker_id); |
3699 _g1h->rem_set()->update_rem_set(pss, worker_id); |
3654 _g1h->rem_set()->scan_heap_roots(pss, worker_id, G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::ObjCopy); |
3700 _g1h->rem_set()->scan_rem_set(pss, worker_id, G1GCPhaseTimes::ScanRS, G1GCPhaseTimes::ObjCopy, G1GCPhaseTimes::CodeRoots); |
3655 _g1h->rem_set()->scan_collection_set_regions(pss, worker_id, G1GCPhaseTimes::ScanHR, G1GCPhaseTimes::CodeRoots, G1GCPhaseTimes::ObjCopy); |
3701 } |
3656 } |
3702 |
3657 |
3703 void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) { |
3658 void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) { |
3704 G1EvacuateRegionsBaseTask::evacuate_live_objects(pss, worker_id, G1GCPhaseTimes::ObjCopy, G1GCPhaseTimes::Termination); |
3659 G1EvacuateRegionsBaseTask::evacuate_live_objects(pss, worker_id, G1GCPhaseTimes::ObjCopy, G1GCPhaseTimes::Termination); |
3705 } |
3660 } |
3722 _root_processor(root_processor) |
3677 _root_processor(root_processor) |
3723 { } |
3678 { } |
3724 }; |
3679 }; |
3725 |
3680 |
3726 void G1CollectedHeap::evacuate_initial_collection_set(G1ParScanThreadStateSet* per_thread_states) { |
3681 void G1CollectedHeap::evacuate_initial_collection_set(G1ParScanThreadStateSet* per_thread_states) { |
|
3682 G1GCPhaseTimes* p = phase_times(); |
|
3683 |
|
3684 { |
|
3685 Ticks start = Ticks::now(); |
|
3686 rem_set()->merge_heap_roots(false /* remset_only */, G1GCPhaseTimes::MergeRS); |
|
3687 p->record_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0); |
|
3688 } |
|
3689 |
3727 Tickspan task_time; |
3690 Tickspan task_time; |
3728 const uint num_workers = workers()->active_workers(); |
3691 const uint num_workers = workers()->active_workers(); |
3729 |
3692 |
3730 Ticks start_processing = Ticks::now(); |
3693 Ticks start_processing = Ticks::now(); |
3731 { |
3694 { |
3736 // To extract its code root fixup time we measure total time of this scope and |
3699 // To extract its code root fixup time we measure total time of this scope and |
3737 // subtract from the time the WorkGang task took. |
3700 // subtract from the time the WorkGang task took. |
3738 } |
3701 } |
3739 Tickspan total_processing = Ticks::now() - start_processing; |
3702 Tickspan total_processing = Ticks::now() - start_processing; |
3740 |
3703 |
3741 G1GCPhaseTimes* p = phase_times(); |
|
3742 p->record_initial_evac_time(task_time.seconds() * 1000.0); |
3704 p->record_initial_evac_time(task_time.seconds() * 1000.0); |
3743 p->record_or_add_code_root_fixup_time((total_processing - task_time).seconds() * 1000.0); |
3705 p->record_or_add_code_root_fixup_time((total_processing - task_time).seconds() * 1000.0); |
3744 } |
3706 } |
3745 |
3707 |
3746 class G1EvacuateOptionalRegionsTask : public G1EvacuateRegionsBaseTask { |
3708 class G1EvacuateOptionalRegionsTask : public G1EvacuateRegionsBaseTask { |
3747 |
3709 |
3748 void scan_roots(G1ParScanThreadState* pss, uint worker_id) { |
3710 void scan_roots(G1ParScanThreadState* pss, uint worker_id) { |
3749 _g1h->rem_set()->scan_rem_set(pss, worker_id, G1GCPhaseTimes::OptScanRS, G1GCPhaseTimes::OptObjCopy, G1GCPhaseTimes::OptCodeRoots); |
3711 _g1h->rem_set()->scan_heap_roots(pss, worker_id, G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::OptObjCopy); |
|
3712 _g1h->rem_set()->scan_collection_set_regions(pss, worker_id, G1GCPhaseTimes::OptScanHR, G1GCPhaseTimes::OptCodeRoots, G1GCPhaseTimes::OptObjCopy); |
3750 } |
3713 } |
3751 |
3714 |
3752 void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) { |
3715 void evacuate_live_objects(G1ParScanThreadState* pss, uint worker_id) { |
3753 G1EvacuateRegionsBaseTask::evacuate_live_objects(pss, worker_id, G1GCPhaseTimes::OptObjCopy, G1GCPhaseTimes::OptTermination); |
3716 G1EvacuateRegionsBaseTask::evacuate_live_objects(pss, worker_id, G1GCPhaseTimes::OptObjCopy, G1GCPhaseTimes::OptTermination); |
3754 } |
3717 } |
3780 } |
3743 } |
3781 |
3744 |
3782 void G1CollectedHeap::evacuate_optional_collection_set(G1ParScanThreadStateSet* per_thread_states) { |
3745 void G1CollectedHeap::evacuate_optional_collection_set(G1ParScanThreadStateSet* per_thread_states) { |
3783 const double gc_start_time_ms = phase_times()->cur_collection_start_sec() * 1000.0; |
3746 const double gc_start_time_ms = phase_times()->cur_collection_start_sec() * 1000.0; |
3784 |
3747 |
3785 Ticks start = Ticks::now(); |
|
3786 |
|
3787 while (!evacuation_failed() && _collection_set.optional_region_length() > 0) { |
3748 while (!evacuation_failed() && _collection_set.optional_region_length() > 0) { |
3788 |
3749 |
3789 double time_used_ms = os::elapsedTime() * 1000.0 - gc_start_time_ms; |
3750 double time_used_ms = os::elapsedTime() * 1000.0 - gc_start_time_ms; |
3790 double time_left_ms = MaxGCPauseMillis - time_used_ms; |
3751 double time_left_ms = MaxGCPauseMillis - time_used_ms; |
3791 |
3752 |
3794 log_trace(gc, ergo, cset)("Skipping evacuation of %u optional regions, no more regions can be evacuated in %.3fms", |
3755 log_trace(gc, ergo, cset)("Skipping evacuation of %u optional regions, no more regions can be evacuated in %.3fms", |
3795 _collection_set.optional_region_length(), time_left_ms); |
3756 _collection_set.optional_region_length(), time_left_ms); |
3796 break; |
3757 break; |
3797 } |
3758 } |
3798 |
3759 |
3799 evacuate_next_optional_regions(per_thread_states); |
3760 { |
|
3761 Ticks start = Ticks::now(); |
|
3762 rem_set()->merge_heap_roots(true /* remset_only */, G1GCPhaseTimes::OptMergeRS); |
|
3763 phase_times()->record_or_add_optional_merge_heap_roots_time((Ticks::now() - start).seconds() * 1000.0); |
|
3764 } |
|
3765 |
|
3766 { |
|
3767 Ticks start = Ticks::now(); |
|
3768 evacuate_next_optional_regions(per_thread_states); |
|
3769 phase_times()->record_or_add_optional_evac_time((Ticks::now() - start).seconds() * 1000.0); |
|
3770 } |
3800 } |
3771 } |
3801 |
3772 |
3802 _collection_set.abandon_optional_collection_set(per_thread_states); |
3773 _collection_set.abandon_optional_collection_set(per_thread_states); |
3803 |
|
3804 phase_times()->record_or_add_optional_evac_time((Ticks::now() - start).seconds() * 1000.0); |
|
3805 } |
3774 } |
3806 |
3775 |
3807 void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) { |
3776 void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) { |
3808 // Also cleans the card table from temporary duplicate detection information used |
3777 rem_set()->cleanup_after_scan_heap_roots(); |
3809 // during UpdateRS/ScanRS. |
|
3810 rem_set()->cleanup_after_scan_rem_set(); |
|
3811 |
3778 |
3812 // Process any discovered reference objects - we have |
3779 // Process any discovered reference objects - we have |
3813 // to do this _before_ we retire the GC alloc regions |
3780 // to do this _before_ we retire the GC alloc regions |
3814 // as we may have to copy some 'reachable' referent |
3781 // as we may have to copy some 'reachable' referent |
3815 // objects (and their reachable sub-graphs) that were |
3782 // objects (and their reachable sub-graphs) that were |