src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
changeset 49811 bfba4712d4ff
parent 49809 ef5220d644e3
child 49819 3cdebcdc8ec0
equal deleted inserted replaced
49810:b5d5e53232ce 49811:bfba4712d4ff
  1006   }
  1006   }
  1007 
  1007 
  1008   verifier->check_bitmaps(caller);
  1008   verifier->check_bitmaps(caller);
  1009 }
  1009 }
  1010 
  1010 
  1011 class G1UpdateRemSetTrackingBeforeRebuild : public HeapRegionClosure {
  1011 class G1UpdateRemSetTrackingBeforeRebuildTask : public AbstractGangTask {
  1012   G1CollectedHeap* _g1h;
  1012   G1CollectedHeap* _g1h;
  1013   G1ConcurrentMark* _cm;
  1013   G1ConcurrentMark* _cm;
       
  1014   HeapRegionClaimer _hrclaimer;
       
  1015   uint volatile _total_selected_for_rebuild;
  1014 
  1016 
  1015   G1PrintRegionLivenessInfoClosure _cl;
  1017   G1PrintRegionLivenessInfoClosure _cl;
  1016 
  1018 
  1017   uint _num_regions_selected_for_rebuild;  // The number of regions actually selected for rebuild.
  1019   class G1UpdateRemSetTrackingBeforeRebuild : public HeapRegionClosure {
  1018 
  1020     G1CollectedHeap* _g1h;
  1019   void update_remset_before_rebuild(HeapRegion * hr) {
  1021     G1ConcurrentMark* _cm;
  1020     G1RemSetTrackingPolicy* tracking_policy = _g1h->g1_policy()->remset_tracker();
  1022 
  1021 
  1023     G1PrintRegionLivenessInfoClosure* _cl;
  1022     size_t live_bytes = _cm->liveness(hr->hrm_index()) * HeapWordSize;
  1024 
  1023     bool selected_for_rebuild = tracking_policy->update_before_rebuild(hr, live_bytes);
  1025     uint _num_regions_selected_for_rebuild;  // The number of regions actually selected for rebuild.
  1024     if (selected_for_rebuild) {
  1026 
  1025       _num_regions_selected_for_rebuild++;
  1027     void update_remset_before_rebuild(HeapRegion * hr) {
  1026     }
  1028       G1RemSetTrackingPolicy* tracking_policy = _g1h->g1_policy()->remset_tracker();
  1027     _cm->update_top_at_rebuild_start(hr);
  1029 
  1028   }
  1030       size_t const live_bytes = _cm->liveness(hr->hrm_index()) * HeapWordSize;
  1029 
  1031       bool selected_for_rebuild = tracking_policy->update_before_rebuild(hr, live_bytes);
  1030   void distribute_marked_bytes(HeapRegion* hr, size_t marked_words) {
  1032       if (selected_for_rebuild) {
  1031     uint const region_idx = hr->hrm_index();
  1033         _num_regions_selected_for_rebuild++;
  1032     uint num_regions_in_humongous = (uint)G1CollectedHeap::humongous_obj_size_in_regions(marked_words);
       
  1033 
       
  1034     for (uint i = region_idx; i < (region_idx + num_regions_in_humongous); i++) {
       
  1035       HeapRegion* const r = _g1h->region_at(i);
       
  1036       size_t const words_to_add = MIN2(HeapRegion::GrainWords, marked_words);
       
  1037       assert(words_to_add > 0, "Out of space to distribute before end of humongous object in region %u (starts %u)", i, region_idx);
       
  1038 
       
  1039       log_trace(gc, marking)("Adding " SIZE_FORMAT " words to humongous region %u (%s)",
       
  1040                              words_to_add, i, r->get_type_str());
       
  1041       r->add_to_marked_bytes(words_to_add * HeapWordSize);
       
  1042       marked_words -= words_to_add;
       
  1043     }
       
  1044     assert(marked_words == 0,
       
  1045            SIZE_FORMAT " words left after distributing space across %u regions",
       
  1046            marked_words, num_regions_in_humongous);
       
  1047   }
       
  1048 
       
  1049   void update_marked_bytes(HeapRegion* hr) {
       
  1050     uint const region_idx = hr->hrm_index();
       
  1051     size_t marked_words = _cm->liveness(region_idx);
       
  1052     // The marking attributes the object's size completely to the humongous starts
       
  1053     // region. We need to distribute this value across the entire set of regions a
       
  1054     // humongous object spans.
       
  1055     if (hr->is_humongous()) {
       
  1056       assert(hr->is_starts_humongous() || marked_words == 0,
       
  1057              "Should not have marked words " SIZE_FORMAT " in non-starts humongous region %u (%s)",
       
  1058              marked_words, region_idx, hr->get_type_str());
       
  1059 
       
  1060       if (marked_words > 0) {
       
  1061         distribute_marked_bytes(hr, marked_words);
       
  1062       }
  1034       }
  1063     } else {
  1035       _cm->update_top_at_rebuild_start(hr);
  1064       log_trace(gc, marking)("Adding " SIZE_FORMAT " words to region %u (%s)", marked_words, region_idx, hr->get_type_str());
  1036     }
  1065       hr->add_to_marked_bytes(marked_words * HeapWordSize);
  1037 
  1066     }
  1038     // Distribute the given words across the humongous object starting with hr and
  1067   }
  1039     // note end of marking.
       
  1040     void distribute_marked_bytes(HeapRegion* hr, size_t marked_words) {
       
  1041       uint const region_idx = hr->hrm_index();
       
  1042       size_t const obj_size_in_words = (size_t)oop(hr->bottom())->size();
       
  1043       uint const num_regions_in_humongous = (uint)G1CollectedHeap::humongous_obj_size_in_regions(obj_size_in_words);
       
  1044 
       
  1045       // "Distributing" zero words means that we only note end of marking for these
       
  1046       // regions.
       
  1047       assert(marked_words == 0 || obj_size_in_words == marked_words,
       
  1048              "Marked words should either be 0 or the same as humongous object (" SIZE_FORMAT ") but is " SIZE_FORMAT,
       
  1049              obj_size_in_words, marked_words);
       
  1050 
       
  1051       for (uint i = region_idx; i < (region_idx + num_regions_in_humongous); i++) {
       
  1052         HeapRegion* const r = _g1h->region_at(i);
       
  1053         size_t const words_to_add = MIN2(HeapRegion::GrainWords, marked_words);
       
  1054 
       
  1055         log_trace(gc, marking)("Adding " SIZE_FORMAT " words to humongous region %u (%s)",
       
  1056                                words_to_add, i, r->get_type_str());
       
  1057         add_marked_bytes_and_note_end(r, words_to_add * HeapWordSize);
       
  1058         marked_words -= words_to_add;
       
  1059       }
       
  1060       assert(marked_words == 0,
       
  1061              SIZE_FORMAT " words left after distributing space across %u regions",
       
  1062              marked_words, num_regions_in_humongous);
       
  1063     }
       
  1064 
       
  1065     void update_marked_bytes(HeapRegion* hr) {
       
  1066       uint const region_idx = hr->hrm_index();
       
  1067       size_t const marked_words = _cm->liveness(region_idx);
       
  1068       // The marking attributes the object's size completely to the humongous starts
       
  1069       // region. We need to distribute this value across the entire set of regions a
       
  1070       // humongous object spans.
       
  1071       if (hr->is_humongous()) {
       
  1072         assert(hr->is_starts_humongous() || marked_words == 0,
       
  1073                "Should not have marked words " SIZE_FORMAT " in non-starts humongous region %u (%s)",
       
  1074                marked_words, region_idx, hr->get_type_str());
       
  1075         if (hr->is_starts_humongous()) {
       
  1076           distribute_marked_bytes(hr, marked_words);
       
  1077         }
       
  1078       } else {
       
  1079         log_trace(gc, marking)("Adding " SIZE_FORMAT " words to region %u (%s)", marked_words, region_idx, hr->get_type_str());
       
  1080         add_marked_bytes_and_note_end(hr, marked_words * HeapWordSize);
       
  1081       }
       
  1082     }
       
  1083 
       
  1084     void add_marked_bytes_and_note_end(HeapRegion* hr, size_t marked_bytes) {
       
  1085       hr->add_to_marked_bytes(marked_bytes);
       
  1086       _cl->do_heap_region(hr);
       
  1087       hr->note_end_of_marking();
       
  1088     }
       
  1089 
       
  1090   public:
       
  1091     G1UpdateRemSetTrackingBeforeRebuild(G1CollectedHeap* g1h, G1ConcurrentMark* cm, G1PrintRegionLivenessInfoClosure* cl) :
       
  1092       _g1h(g1h), _cm(cm), _num_regions_selected_for_rebuild(0), _cl(cl) { }
       
  1093 
       
  1094     virtual bool do_heap_region(HeapRegion* r) {
       
  1095       update_remset_before_rebuild(r);
       
  1096       update_marked_bytes(r);
       
  1097 
       
  1098       return false;
       
  1099     }
       
  1100 
       
  1101     uint num_selected_for_rebuild() const { return _num_regions_selected_for_rebuild; }
       
  1102   };
  1068 
  1103 
  1069 public:
  1104 public:
  1070   G1UpdateRemSetTrackingBeforeRebuild(G1CollectedHeap* g1h, G1ConcurrentMark* cm) :
  1105   G1UpdateRemSetTrackingBeforeRebuildTask(G1CollectedHeap* g1h, G1ConcurrentMark* cm, uint num_workers) :
  1071     _g1h(g1h), _cm(cm), _cl("Post-Marking"), _num_regions_selected_for_rebuild(0) { }
  1106     AbstractGangTask("G1 Update RemSet Tracking Before Rebuild"),
  1072 
  1107     _g1h(g1h), _cm(cm), _hrclaimer(num_workers), _total_selected_for_rebuild(0), _cl("Post-Marking") { }
  1073   virtual bool do_heap_region(HeapRegion* r) {
  1108 
  1074     update_remset_before_rebuild(r);
  1109   virtual void work(uint worker_id) {
  1075     update_marked_bytes(r);
  1110     G1UpdateRemSetTrackingBeforeRebuild update_cl(_g1h, _cm, &_cl);
  1076     if (log_is_enabled(Trace, gc, liveness)) {
  1111     _g1h->heap_region_par_iterate_from_worker_offset(&update_cl, &_hrclaimer, worker_id);
  1077       _cl.do_heap_region(r);
  1112     Atomic::add(update_cl.num_selected_for_rebuild(), &_total_selected_for_rebuild);
  1078     }
  1113   }
  1079     r->note_end_of_marking();
  1114 
  1080     return false;
  1115   uint total_selected_for_rebuild() const { return _total_selected_for_rebuild; }
  1081   }
  1116 
  1082 
  1117   // Number of regions for which roughly one thread should be spawned for this work.
  1083   uint num_selected_for_rebuild() const { return _num_regions_selected_for_rebuild; }
  1118   static const uint RegionsPerThread = 384;
  1084 };
  1119 };
  1085 
  1120 
  1086 class G1UpdateRemSetTrackingAfterRebuild : public HeapRegionClosure {
  1121 class G1UpdateRemSetTrackingAfterRebuild : public HeapRegionClosure {
  1087   G1CollectedHeap* _g1h;
  1122   G1CollectedHeap* _g1h;
  1088 public:
  1123 public:
  1135 
  1170 
  1136     // Install newly created mark bitmap as "prev".
  1171     // Install newly created mark bitmap as "prev".
  1137     swap_mark_bitmaps();
  1172     swap_mark_bitmaps();
  1138     {
  1173     {
  1139       GCTraceTime(Debug, gc, phases) debug("Update Remembered Set Tracking Before Rebuild", _gc_timer_cm);
  1174       GCTraceTime(Debug, gc, phases) debug("Update Remembered Set Tracking Before Rebuild", _gc_timer_cm);
  1140       G1UpdateRemSetTrackingBeforeRebuild cl(_g1h, this);
  1175 
  1141       _g1h->heap_region_iterate(&cl);
  1176       uint const workers_by_capacity = (_g1h->num_regions() + G1UpdateRemSetTrackingBeforeRebuildTask::RegionsPerThread - 1) /
       
  1177                                        G1UpdateRemSetTrackingBeforeRebuildTask::RegionsPerThread;
       
  1178       uint const num_workers = MIN2(_g1h->workers()->active_workers(), workers_by_capacity);
       
  1179 
       
  1180       G1UpdateRemSetTrackingBeforeRebuildTask cl(_g1h, this, num_workers);
       
  1181       log_debug(gc,ergo)("Running %s using %u workers for %u regions in heap", cl.name(), num_workers, _g1h->num_regions());
       
  1182       _g1h->workers()->run_task(&cl, num_workers);
       
  1183 
  1142       log_debug(gc, remset, tracking)("Remembered Set Tracking update regions total %u, selected %u",
  1184       log_debug(gc, remset, tracking)("Remembered Set Tracking update regions total %u, selected %u",
  1143                                       _g1h->num_regions(), cl.num_selected_for_rebuild());
  1185                                       _g1h->num_regions(), cl.total_selected_for_rebuild());
  1144     }
  1186     }
  1145     {
  1187     {
  1146       GCTraceTime(Debug, gc, phases) debug("Reclaim Empty Regions", _gc_timer_cm);
  1188       GCTraceTime(Debug, gc, phases) debug("Reclaim Empty Regions", _gc_timer_cm);
  1147       reclaim_empty_regions();
  1189       reclaim_empty_regions();
  1148     }
  1190     }
  2924 G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure(const char* phase_name) :
  2966 G1PrintRegionLivenessInfoClosure::G1PrintRegionLivenessInfoClosure(const char* phase_name) :
  2925   _total_used_bytes(0), _total_capacity_bytes(0),
  2967   _total_used_bytes(0), _total_capacity_bytes(0),
  2926   _total_prev_live_bytes(0), _total_next_live_bytes(0),
  2968   _total_prev_live_bytes(0), _total_next_live_bytes(0),
  2927   _total_remset_bytes(0), _total_strong_code_roots_bytes(0)
  2969   _total_remset_bytes(0), _total_strong_code_roots_bytes(0)
  2928 {
  2970 {
       
  2971   if (!log_is_enabled(Trace, gc, liveness)) {
       
  2972     return;
       
  2973   }
       
  2974 
  2929   G1CollectedHeap* g1h = G1CollectedHeap::heap();
  2975   G1CollectedHeap* g1h = G1CollectedHeap::heap();
  2930   MemRegion g1_reserved = g1h->g1_reserved();
  2976   MemRegion g1_reserved = g1h->g1_reserved();
  2931   double now = os::elapsedTime();
  2977   double now = os::elapsedTime();
  2932 
  2978 
  2933   // Print the header of the output.
  2979   // Print the header of the output.
  2965                           "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)",
  3011                           "(bytes)", "(bytes)", "(bytes)", "(bytes/ms)",
  2966                           "(bytes)", "", "(bytes)");
  3012                           "(bytes)", "", "(bytes)");
  2967 }
  3013 }
  2968 
  3014 
  2969 bool G1PrintRegionLivenessInfoClosure::do_heap_region(HeapRegion* r) {
  3015 bool G1PrintRegionLivenessInfoClosure::do_heap_region(HeapRegion* r) {
       
  3016   if (!log_is_enabled(Trace, gc, liveness)) {
       
  3017     return false;
       
  3018   }
       
  3019 
  2970   const char* type       = r->get_type_str();
  3020   const char* type       = r->get_type_str();
  2971   HeapWord* bottom       = r->bottom();
  3021   HeapWord* bottom       = r->bottom();
  2972   HeapWord* end          = r->end();
  3022   HeapWord* end          = r->end();
  2973   size_t capacity_bytes  = r->capacity();
  3023   size_t capacity_bytes  = r->capacity();
  2974   size_t used_bytes      = r->used();
  3024   size_t used_bytes      = r->used();
  3003 
  3053 
  3004   return false;
  3054   return false;
  3005 }
  3055 }
  3006 
  3056 
  3007 G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
  3057 G1PrintRegionLivenessInfoClosure::~G1PrintRegionLivenessInfoClosure() {
       
  3058   if (!log_is_enabled(Trace, gc, liveness)) {
       
  3059     return;
       
  3060   }
       
  3061 
  3008   // add static memory usages to remembered set sizes
  3062   // add static memory usages to remembered set sizes
  3009   _total_remset_bytes += HeapRegionRemSet::fl_mem_size() + HeapRegionRemSet::static_mem_size();
  3063   _total_remset_bytes += HeapRegionRemSet::fl_mem_size() + HeapRegionRemSet::static_mem_size();
  3010   // Print the footer of the output.
  3064   // Print the footer of the output.
  3011   log_trace(gc, liveness)(G1PPRL_LINE_PREFIX);
  3065   log_trace(gc, liveness)(G1PPRL_LINE_PREFIX);
  3012   log_trace(gc, liveness)(G1PPRL_LINE_PREFIX
  3066   log_trace(gc, liveness)(G1PPRL_LINE_PREFIX