1008 G1CollectedHeap* _g1h;
1009 G1ConcurrentMark* _cm;
1010
1011 G1PrintRegionLivenessInfoClosure _cl;
1012
1013 uint _num_regions_selected_for_rebuild; // The number of regions actually selected for rebuild.
1014
1015 void update_remset_before_rebuild(HeapRegion * hr) {
1016 G1RemSetTrackingPolicy* tracking_policy = _g1h->g1_policy()->remset_tracker();
1017
1018 size_t live_bytes = _cm->liveness(hr->hrm_index()) * HeapWordSize;
1019 bool selected_for_rebuild = tracking_policy->update_before_rebuild(hr, live_bytes);
1020 if (selected_for_rebuild) {
1021 _num_regions_selected_for_rebuild++;
1022 }
1023 _cm->update_top_at_rebuild_start(hr);
1024 }
1025
1026 void distribute_marked_bytes(HeapRegion* hr, size_t marked_words) {
1027 uint const region_idx = hr->hrm_index();
1028 assert(hr->is_starts_humongous(),
1029 "Should not have marked bytes " SIZE_FORMAT " in non-starts humongous region %u (%s)",
1030 marked_words, region_idx, hr->get_type_str());
1031 uint num_regions_in_humongous = (uint)G1CollectedHeap::humongous_obj_size_in_regions(marked_words);
1032
1033 for (uint i = region_idx; i < (region_idx + num_regions_in_humongous); i++) {
1034 HeapRegion* const r = _g1h->region_at(i);
1035 size_t const words_to_add = MIN2(HeapRegion::GrainWords, marked_words);
1036 assert(words_to_add > 0, "Out of space to distribute before end of humongous object in region %u (starts %u)", i, region_idx);
1037
1038 r->add_to_marked_bytes(words_to_add * HeapWordSize);
1039 marked_words -= words_to_add;
1040 }
1041 assert(marked_words == 0,
1042 SIZE_FORMAT " words left after distributing space across %u regions",
1043 marked_words, num_regions_in_humongous);
1044 }
1045
1046 void update_marked_bytes(HeapRegion* hr) {
1047 uint const region_idx = hr->hrm_index();
1048 size_t marked_words = _cm->liveness(region_idx);
1049 // The marking attributes the object's size completely to the humongous starts
1050 // region. We need to distribute this value across the entire set of regions a
1051 // humongous object spans.
1052 if (hr->is_humongous()) {
1053 if (marked_words > 0) {
1054 log_trace(gc, marking)("Adding " SIZE_FORMAT " words to humongous start region %u (%s), word size %d (%f)",
1055 marked_words, region_idx, hr->get_type_str(),
1056 oop(hr->bottom())->size(), (double)oop(hr->bottom())->size() / HeapRegion::GrainWords);
1057 distribute_marked_bytes(hr, marked_words);
1058 } else {
1059 assert(marked_words == 0,
1060 "Asked to add " SIZE_FORMAT " words to add to continues humongous region %u (%s)",
1061 marked_words, region_idx, hr->get_type_str());
1062 }
1063 } else {
1064 log_trace(gc, marking)("Adding " SIZE_FORMAT " words to region %u (%s)", marked_words, region_idx, hr->get_type_str());
1065 hr->add_to_marked_bytes(marked_words * HeapWordSize);
1066 }
1067 }
1068
1069 public:
1070 G1UpdateRemSetTrackingBeforeRebuild(G1CollectedHeap* g1h, G1ConcurrentMark* cm) :
1071 _g1h(g1h), _cm(cm), _cl("Post-Marking"), _num_regions_selected_for_rebuild(0) { }
1072
1073 virtual bool do_heap_region(HeapRegion* r) {
1074 update_remset_before_rebuild(r);
1075 update_marked_bytes(r);
1076 if (log_is_enabled(Trace, gc, liveness)) {
1077 _cl.do_heap_region(r);
1078 }
1079 r->note_end_of_marking();
1080 return false;
1081 }
|
1008 G1CollectedHeap* _g1h;
1009 G1ConcurrentMark* _cm;
1010
1011 G1PrintRegionLivenessInfoClosure _cl;
1012
1013 uint _num_regions_selected_for_rebuild; // The number of regions actually selected for rebuild.
1014
1015 void update_remset_before_rebuild(HeapRegion * hr) {
1016 G1RemSetTrackingPolicy* tracking_policy = _g1h->g1_policy()->remset_tracker();
1017
1018 size_t live_bytes = _cm->liveness(hr->hrm_index()) * HeapWordSize;
1019 bool selected_for_rebuild = tracking_policy->update_before_rebuild(hr, live_bytes);
1020 if (selected_for_rebuild) {
1021 _num_regions_selected_for_rebuild++;
1022 }
1023 _cm->update_top_at_rebuild_start(hr);
1024 }
1025
1026 void distribute_marked_bytes(HeapRegion* hr, size_t marked_words) {
1027 uint const region_idx = hr->hrm_index();
1028 uint num_regions_in_humongous = (uint)G1CollectedHeap::humongous_obj_size_in_regions(marked_words);
1029
1030 for (uint i = region_idx; i < (region_idx + num_regions_in_humongous); i++) {
1031 HeapRegion* const r = _g1h->region_at(i);
1032 size_t const words_to_add = MIN2(HeapRegion::GrainWords, marked_words);
1033 assert(words_to_add > 0, "Out of space to distribute before end of humongous object in region %u (starts %u)", i, region_idx);
1034
1035 log_trace(gc, marking)("Adding " SIZE_FORMAT " words to humongous region %u (%s)",
1036 words_to_add, i, r->get_type_str());
1037 r->add_to_marked_bytes(words_to_add * HeapWordSize);
1038 marked_words -= words_to_add;
1039 }
1040 assert(marked_words == 0,
1041 SIZE_FORMAT " words left after distributing space across %u regions",
1042 marked_words, num_regions_in_humongous);
1043 }
1044
1045 void update_marked_bytes(HeapRegion* hr) {
1046 uint const region_idx = hr->hrm_index();
1047 size_t marked_words = _cm->liveness(region_idx);
1048 // The marking attributes the object's size completely to the humongous starts
1049 // region. We need to distribute this value across the entire set of regions a
1050 // humongous object spans.
1051 if (hr->is_humongous()) {
1052 assert(hr->is_starts_humongous() || marked_words == 0,
1053 "Should not have marked words " SIZE_FORMAT " in non-starts humongous region %u (%s)",
1054 marked_words, region_idx, hr->get_type_str());
1055
1056 if (marked_words > 0) {
1057 distribute_marked_bytes(hr, marked_words);
1058 }
1059 } else {
1060 log_trace(gc, marking)("Adding " SIZE_FORMAT " words to region %u (%s)", marked_words, region_idx, hr->get_type_str());
1061 hr->add_to_marked_bytes(marked_words * HeapWordSize);
1062 }
1063 }
1064
1065 public:
1066 G1UpdateRemSetTrackingBeforeRebuild(G1CollectedHeap* g1h, G1ConcurrentMark* cm) :
1067 _g1h(g1h), _cm(cm), _cl("Post-Marking"), _num_regions_selected_for_rebuild(0) { }
1068
1069 virtual bool do_heap_region(HeapRegion* r) {
1070 update_remset_before_rebuild(r);
1071 update_marked_bytes(r);
1072 if (log_is_enabled(Trace, gc, liveness)) {
1073 _cl.do_heap_region(r);
1074 }
1075 r->note_end_of_marking();
1076 return false;
1077 }
|