< prev index next >

src/hotspot/share/gc/g1/g1ConcurrentMark.cpp

Print this page
rev 49511 : imported patch 8200234-g1concurrentmark-refactorings
rev 49512 : imported patch 8200234-stefanj-review
rev 49515 : 8200255: Remove G1CMTask::_concurrent
Reviewed-by: sangheki, sjohanss
rev 49516 : 8200074: Remove G1ConcurrentMark::_concurrent_marking_in_progress
Reviewed-by: sjohanss, sangheki
rev 49517 : imported patch 8200305-gc,liveness-output
rev 49518 : imported patch 8200385-prev-bitmap-marks-left
rev 49519 : imported patch 8200385-stefanj-review
rev 49520 : imported patch 8178105-switch-at-remark
rev 49521 : [mq]: 8178105-stefanj-review


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(), "Should not have marked bytes " SIZE_FORMAT " in non-starts humongous region %u (%s)", marked_words, region_idx, hr->get_type_str());


1029     uint num_regions_in_humongous = (uint)G1CollectedHeap::humongous_obj_size_in_regions(marked_words);
1030 
1031     for (uint i = region_idx; i < (region_idx + num_regions_in_humongous); i++) {
1032       HeapRegion* const r = _g1h->region_at(i);
1033       size_t const words_to_add = MIN2(HeapRegion::GrainWords, marked_words);


1034       r->add_to_marked_bytes(words_to_add * HeapWordSize);
1035       marked_words -= words_to_add;
1036     }



1037   }
1038 
1039   void update_marked_bytes(HeapRegion* hr) {
1040     uint const region_idx = hr->hrm_index();
1041     size_t marked_words = _cm->liveness(region_idx);
1042     // The marking attributes the object's size completely to the humongous starts
1043     // region. We need to distribute this value across the entire set of regions a
1044     // humongous object spans.
1045     if (!hr->is_humongous()) {
1046       hr->add_to_marked_bytes(marked_words * HeapWordSize);
1047       log_trace(gc)("Added " SIZE_FORMAT " words to region %u (%s)", marked_words, region_idx, hr->get_type_str());
1048     } else {
1049       if (marked_words > 0) {
1050         log_trace(gc)("Distributing " SIZE_FORMAT " words to humongous start region %u (%s), word size %d (%f)", 
1051                       marked_words, region_idx, hr->get_type_str(),
1052                       oop(hr->bottom())->size(), (double)oop(hr->bottom())->size() / HeapRegion::GrainWords);
1053         distribute_marked_bytes(hr, marked_words);
1054       } else {
1055         log_trace(gc)("NOT Added " SIZE_FORMAT " words to region %u (%s)", marked_words, region_idx, hr->get_type_str());


1056       }



1057     }
1058   }

1059 public:
1060   G1UpdateRemSetTrackingBeforeRebuild(G1CollectedHeap* g1h, G1ConcurrentMark* cm) :
1061     _g1h(g1h), _cm(cm), _cl("Post-Marking"), _num_regions_selected_for_rebuild(0) { }
1062 
1063   virtual bool do_heap_region(HeapRegion* r) {
1064     update_remset_before_rebuild(r);
1065     update_marked_bytes(r);
1066     if (log_is_enabled(Trace, gc, liveness)) {
1067       _cl.do_heap_region(r);
1068     }
1069     r->note_end_of_marking();
1070     return false;
1071   }
1072 
1073   uint num_selected_for_rebuild() const { return _num_regions_selected_for_rebuild; }
1074 };
1075 
1076 class G1UpdateRemSetTrackingAfterRebuild : public HeapRegionClosure {
1077   G1CollectedHeap* _g1h;
1078 public:


1663   }
1664 }
1665 
1666 // When sampling object counts, we already swapped the mark bitmaps, so we need to use
1667 // the prev bitmap determining liveness.
1668 class G1ObjectCountIsAliveClosure: public BoolObjectClosure {
1669   G1CollectedHeap* _g1;
1670  public:
1671   G1ObjectCountIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) { }
1672 
1673   bool do_object_b(oop obj) {
1674     HeapWord* addr = (HeapWord*)obj;
1675     return addr != NULL &&
1676            (!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_dead(obj));
1677   }
1678 };
1679 
1680 void G1ConcurrentMark::report_object_count(bool mark_completed) {
1681   // Depending on the completion of the marking liveness needs to be determined
1682   // using either the next or prev bitmap.
1683   G1ObjectCountIsAliveClosure is_alive_prev(_g1h);
1684   G1CMIsAliveClosure is_alive_next(_g1h);
1685   BoolObjectClosure* is_alive;
1686   if (mark_completed) {
1687     is_alive = &is_alive_prev;

1688   } else {
1689     is_alive = &is_alive_next;

1690   }
1691   _gc_tracer_cm->report_object_count_after_gc(is_alive);
1692 }
1693 
1694 
1695 void G1ConcurrentMark::swap_mark_bitmaps() {
1696   G1CMBitMap* temp = _prev_mark_bitmap;
1697   _prev_mark_bitmap = _next_mark_bitmap;
1698   _next_mark_bitmap = temp;
1699   _g1h->collector_state()->set_clearing_next_bitmap(true);
1700 }
1701 
1702 // Closure for marking entries in SATB buffers.
1703 class G1CMSATBBufferClosure : public SATBBufferClosure {
1704 private:
1705   G1CMTask* _task;
1706   G1CollectedHeap* _g1h;
1707 
1708   // This is very similar to G1CMTask::deal_with_reference, but with
1709   // more relaxed requirements for the argument, so this must be more
1710   // circumspect about treating the argument as an object.
1711   void do_entry(void* entry) const {




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   }
1082 
1083   uint num_selected_for_rebuild() const { return _num_regions_selected_for_rebuild; }
1084 };
1085 
1086 class G1UpdateRemSetTrackingAfterRebuild : public HeapRegionClosure {
1087   G1CollectedHeap* _g1h;
1088 public:


1673   }
1674 }
1675 
1676 // When sampling object counts, we already swapped the mark bitmaps, so we need to use
1677 // the prev bitmap determining liveness.
1678 class G1ObjectCountIsAliveClosure: public BoolObjectClosure {
1679   G1CollectedHeap* _g1;
1680  public:
1681   G1ObjectCountIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) { }
1682 
1683   bool do_object_b(oop obj) {
1684     HeapWord* addr = (HeapWord*)obj;
1685     return addr != NULL &&
1686            (!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_dead(obj));
1687   }
1688 };
1689 
1690 void G1ConcurrentMark::report_object_count(bool mark_completed) {
1691   // Depending on the completion of the marking liveness needs to be determined
1692   // using either the next or prev bitmap.



1693   if (mark_completed) {
1694     G1ObjectCountIsAliveClosure is_alive(_g1h);
1695     _gc_tracer_cm->report_object_count_after_gc(&is_alive);
1696   } else {
1697     G1CMIsAliveClosure is_alive(_g1h);
1698     _gc_tracer_cm->report_object_count_after_gc(&is_alive);
1699   }

1700 }
1701 
1702 
1703 void G1ConcurrentMark::swap_mark_bitmaps() {
1704   G1CMBitMap* temp = _prev_mark_bitmap;
1705   _prev_mark_bitmap = _next_mark_bitmap;
1706   _next_mark_bitmap = temp;
1707   _g1h->collector_state()->set_clearing_next_bitmap(true);
1708 }
1709 
1710 // Closure for marking entries in SATB buffers.
1711 class G1CMSATBBufferClosure : public SATBBufferClosure {
1712 private:
1713   G1CMTask* _task;
1714   G1CollectedHeap* _g1h;
1715 
1716   // This is very similar to G1CMTask::deal_with_reference, but with
1717   // more relaxed requirements for the argument, so this must be more
1718   // circumspect about treating the argument as an object.
1719   void do_entry(void* entry) const {


< prev index next >