918 |
918 |
919 uint _merged_sparse; |
919 uint _merged_sparse; |
920 uint _merged_fine; |
920 uint _merged_fine; |
921 uint _merged_coarse; |
921 uint _merged_coarse; |
922 |
922 |
|
923 size_t _cards_dirty; |
|
924 |
923 // Returns if the region contains cards we need to scan. If so, remember that |
925 // Returns if the region contains cards we need to scan. If so, remember that |
924 // region in the current set of dirty regions. |
926 // region in the current set of dirty regions. |
925 bool remember_if_interesting(uint const region_idx) { |
927 bool remember_if_interesting(uint const region_idx) { |
926 if (!_scan_state->contains_cards_to_process(region_idx)) { |
928 if (!_scan_state->contains_cards_to_process(region_idx)) { |
927 return false; |
929 return false; |
933 G1MergeCardSetClosure(G1RemSetScanState* scan_state) : |
935 G1MergeCardSetClosure(G1RemSetScanState* scan_state) : |
934 _scan_state(scan_state), |
936 _scan_state(scan_state), |
935 _ct(G1CollectedHeap::heap()->card_table()), |
937 _ct(G1CollectedHeap::heap()->card_table()), |
936 _merged_sparse(0), |
938 _merged_sparse(0), |
937 _merged_fine(0), |
939 _merged_fine(0), |
938 _merged_coarse(0) { } |
940 _merged_coarse(0), |
|
941 _cards_dirty(0) { } |
939 |
942 |
940 void next_coarse_prt(uint const region_idx) { |
943 void next_coarse_prt(uint const region_idx) { |
941 if (!remember_if_interesting(region_idx)) { |
944 if (!remember_if_interesting(region_idx)) { |
942 return; |
945 return; |
943 } |
946 } |
944 |
947 |
945 _merged_coarse++; |
948 _merged_coarse++; |
946 |
949 |
947 size_t region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion; |
950 size_t region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion; |
948 _ct->mark_region_dirty(region_base_idx, HeapRegion::CardsPerRegion); |
951 _cards_dirty += _ct->mark_region_dirty(region_base_idx, HeapRegion::CardsPerRegion); |
949 _scan_state->set_chunk_region_dirty(region_base_idx); |
952 _scan_state->set_chunk_region_dirty(region_base_idx); |
950 } |
953 } |
951 |
954 |
952 void next_fine_prt(uint const region_idx, BitMap* bm) { |
955 void next_fine_prt(uint const region_idx, BitMap* bm) { |
953 if (!remember_if_interesting(region_idx)) { |
956 if (!remember_if_interesting(region_idx)) { |
957 _merged_fine++; |
960 _merged_fine++; |
958 |
961 |
959 size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion; |
962 size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion; |
960 BitMap::idx_t cur = bm->get_next_one_offset(0); |
963 BitMap::idx_t cur = bm->get_next_one_offset(0); |
961 while (cur != bm->size()) { |
964 while (cur != bm->size()) { |
962 _ct->mark_clean_as_dirty(region_base_idx + cur); |
965 _cards_dirty += _ct->mark_clean_as_dirty(region_base_idx + cur); |
963 _scan_state->set_chunk_dirty(region_base_idx + cur); |
966 _scan_state->set_chunk_dirty(region_base_idx + cur); |
964 cur = bm->get_next_one_offset(cur + 1); |
967 cur = bm->get_next_one_offset(cur + 1); |
965 } |
968 } |
966 } |
969 } |
967 |
970 |
973 _merged_sparse++; |
976 _merged_sparse++; |
974 |
977 |
975 size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion; |
978 size_t const region_base_idx = (size_t)region_idx << HeapRegion::LogCardsPerRegion; |
976 for (uint i = 0; i < num_cards; i++) { |
979 for (uint i = 0; i < num_cards; i++) { |
977 size_t card_idx = region_base_idx + cards[i]; |
980 size_t card_idx = region_base_idx + cards[i]; |
978 _ct->mark_clean_as_dirty(card_idx); |
981 _cards_dirty += _ct->mark_clean_as_dirty(card_idx); |
979 _scan_state->set_chunk_dirty(card_idx); |
982 _scan_state->set_chunk_dirty(card_idx); |
980 } |
983 } |
981 } |
984 } |
982 |
985 |
983 virtual bool do_heap_region(HeapRegion* r) { |
986 virtual bool do_heap_region(HeapRegion* r) { |
992 } |
995 } |
993 |
996 |
994 size_t merged_sparse() const { return _merged_sparse; } |
997 size_t merged_sparse() const { return _merged_sparse; } |
995 size_t merged_fine() const { return _merged_fine; } |
998 size_t merged_fine() const { return _merged_fine; } |
996 size_t merged_coarse() const { return _merged_coarse; } |
999 size_t merged_coarse() const { return _merged_coarse; } |
|
1000 |
|
1001 size_t cards_dirty() const { return _cards_dirty; } |
997 }; |
1002 }; |
998 |
1003 |
999 // Visitor for the remembered sets of humongous candidate regions to merge their |
1004 // Visitor for the remembered sets of humongous candidate regions to merge their |
1000 // remembered set into the card table. |
1005 // remembered set into the card table. |
1001 class G1FlushHumongousCandidateRemSets : public HeapRegionClosure { |
1006 class G1FlushHumongousCandidateRemSets : public HeapRegionClosure { |
1037 } |
1042 } |
1038 |
1043 |
1039 size_t merged_sparse() const { return _cl.merged_sparse(); } |
1044 size_t merged_sparse() const { return _cl.merged_sparse(); } |
1040 size_t merged_fine() const { return _cl.merged_fine(); } |
1045 size_t merged_fine() const { return _cl.merged_fine(); } |
1041 size_t merged_coarse() const { return _cl.merged_coarse(); } |
1046 size_t merged_coarse() const { return _cl.merged_coarse(); } |
|
1047 |
|
1048 size_t cards_dirty() const { return _cl.cards_dirty(); } |
1042 }; |
1049 }; |
1043 |
1050 |
1044 // Visitor for the log buffer entries to merge them into the card table. |
1051 // Visitor for the log buffer entries to merge them into the card table. |
1045 class G1MergeLogBufferCardsClosure : public G1CardTableEntryClosure { |
1052 class G1MergeLogBufferCardsClosure : public G1CardTableEntryClosure { |
1046 G1RemSetScanState* _scan_state; |
1053 G1RemSetScanState* _scan_state; |
1138 g1h->heap_region_iterate(&cl); |
1145 g1h->heap_region_iterate(&cl); |
1139 |
1146 |
1140 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse); |
1147 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse); |
1141 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine); |
1148 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine); |
1142 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse); |
1149 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse); |
|
1150 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.cards_dirty(), G1GCPhaseTimes::MergeRSDirtyCards); |
1143 } |
1151 } |
1144 |
1152 |
1145 // Merge remembered sets of current candidates. |
1153 // Merge remembered sets of current candidates. |
1146 { |
1154 { |
1147 G1GCParPhaseTimesTracker x(p, merge_remset_phase, worker_id, _initial_evacuation /* must_record */); |
1155 G1GCParPhaseTimesTracker x(p, merge_remset_phase, worker_id, _initial_evacuation /* must_record */); |
1149 g1h->collection_set_iterate_increment_from(&cl, &_hr_claimer, worker_id); |
1157 g1h->collection_set_iterate_increment_from(&cl, &_hr_claimer, worker_id); |
1150 |
1158 |
1151 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse); |
1159 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_sparse(), G1GCPhaseTimes::MergeRSMergedSparse); |
1152 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine); |
1160 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_fine(), G1GCPhaseTimes::MergeRSMergedFine); |
1153 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse); |
1161 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.merged_coarse(), G1GCPhaseTimes::MergeRSMergedCoarse); |
|
1162 p->record_or_add_thread_work_item(merge_remset_phase, worker_id, cl.cards_dirty(), G1GCPhaseTimes::MergeRSDirtyCards); |
1154 } |
1163 } |
1155 |
1164 |
1156 // Apply closure to log entries in the HCC. |
1165 // Apply closure to log entries in the HCC. |
1157 if (_initial_evacuation && G1HotCardCache::default_use_cache()) { |
1166 if (_initial_evacuation && G1HotCardCache::default_use_cache()) { |
1158 assert(merge_remset_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase"); |
1167 assert(merge_remset_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase"); |