< 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
rev 49522 : [mq]: 8178105-stefanj-review2
*** 1006,1015 ****
--- 1006,1017 ----
class G1UpdateRemSetTrackingBeforeRebuild : public HeapRegionClosure {
G1CollectedHeap* _g1h;
G1ConcurrentMark* _cm;
+ G1PrintRegionLivenessInfoClosure _cl;
+
uint _num_regions_selected_for_rebuild; // The number of regions actually selected for rebuild.
void update_remset_before_rebuild(HeapRegion * hr) {
G1RemSetTrackingPolicy* tracking_policy = _g1h->g1_policy()->remset_tracker();
*** 1019,1034 ****
_num_regions_selected_for_rebuild++;
}
_cm->update_top_at_rebuild_start(hr);
}
public:
G1UpdateRemSetTrackingBeforeRebuild(G1CollectedHeap* g1h, G1ConcurrentMark* cm) :
! _g1h(g1h), _cm(cm), _num_regions_selected_for_rebuild(0) { }
virtual bool do_heap_region(HeapRegion* r) {
update_remset_before_rebuild(r);
return false;
}
uint num_selected_for_rebuild() const { return _num_regions_selected_for_rebuild; }
};
--- 1021,1080 ----
_num_regions_selected_for_rebuild++;
}
_cm->update_top_at_rebuild_start(hr);
}
+ void distribute_marked_bytes(HeapRegion* hr, size_t marked_words) {
+ uint const region_idx = hr->hrm_index();
+ uint num_regions_in_humongous = (uint)G1CollectedHeap::humongous_obj_size_in_regions(marked_words);
+
+ for (uint i = region_idx; i < (region_idx + num_regions_in_humongous); i++) {
+ HeapRegion* const r = _g1h->region_at(i);
+ size_t const words_to_add = MIN2(HeapRegion::GrainWords, marked_words);
+ assert(words_to_add > 0, "Out of space to distribute before end of humongous object in region %u (starts %u)", i, region_idx);
+
+ log_trace(gc, marking)("Adding " SIZE_FORMAT " words to humongous region %u (%s)",
+ words_to_add, i, r->get_type_str());
+ r->add_to_marked_bytes(words_to_add * HeapWordSize);
+ marked_words -= words_to_add;
+ }
+ assert(marked_words == 0,
+ SIZE_FORMAT " words left after distributing space across %u regions",
+ marked_words, num_regions_in_humongous);
+ }
+
+ void update_marked_bytes(HeapRegion* hr) {
+ uint const region_idx = hr->hrm_index();
+ size_t marked_words = _cm->liveness(region_idx);
+ // The marking attributes the object's size completely to the humongous starts
+ // region. We need to distribute this value across the entire set of regions a
+ // humongous object spans.
+ if (hr->is_humongous()) {
+ assert(hr->is_starts_humongous() || marked_words == 0,
+ "Should not have marked words " SIZE_FORMAT " in non-starts humongous region %u (%s)",
+ marked_words, region_idx, hr->get_type_str());
+
+ if (marked_words > 0) {
+ distribute_marked_bytes(hr, marked_words);
+ }
+ } else {
+ log_trace(gc, marking)("Adding " SIZE_FORMAT " words to region %u (%s)", marked_words, region_idx, hr->get_type_str());
+ hr->add_to_marked_bytes(marked_words * HeapWordSize);
+ }
+ }
+
public:
G1UpdateRemSetTrackingBeforeRebuild(G1CollectedHeap* g1h, G1ConcurrentMark* cm) :
! _g1h(g1h), _cm(cm), _cl("Post-Marking"), _num_regions_selected_for_rebuild(0) { }
virtual bool do_heap_region(HeapRegion* r) {
update_remset_before_rebuild(r);
+ update_marked_bytes(r);
+ if (log_is_enabled(Trace, gc, liveness)) {
+ _cl.do_heap_region(r);
+ }
+ r->note_end_of_marking();
return false;
}
uint num_selected_for_rebuild() const { return _num_regions_selected_for_rebuild; }
};
*** 1081,1099 ****
{
GCTraceTime(Debug, gc, phases)("Flush Task Caches");
flush_all_task_caches();
}
{
GCTraceTime(Debug, gc, phases)("Update Remembered Set Tracking Before Rebuild");
G1UpdateRemSetTrackingBeforeRebuild cl(_g1h, this);
_g1h->heap_region_iterate(&cl);
log_debug(gc, remset, tracking)("Remembered Set Tracking update regions total %u, selected %u",
_g1h->num_regions(), cl.num_selected_for_rebuild());
}
! verify_during_pause(G1HeapVerifier::G1VerifyRemark, VerifyOption_G1UseNextMarking, "Remark after");
assert(!restart_for_overflow(), "sanity");
// Completely reset the marking state since marking completed
reset_at_marking_complete();
} else {
--- 1127,1147 ----
{
GCTraceTime(Debug, gc, phases)("Flush Task Caches");
flush_all_task_caches();
}
+ // Install newly created mark bitmap as "prev".
+ swap_mark_bitmaps();
{
GCTraceTime(Debug, gc, phases)("Update Remembered Set Tracking Before Rebuild");
G1UpdateRemSetTrackingBeforeRebuild cl(_g1h, this);
_g1h->heap_region_iterate(&cl);
log_debug(gc, remset, tracking)("Remembered Set Tracking update regions total %u, selected %u",
_g1h->num_regions(), cl.num_selected_for_rebuild());
}
! verify_during_pause(G1HeapVerifier::G1VerifyRemark, VerifyOption_G1UsePrevMarking, "Remark after");
assert(!restart_for_overflow(), "sanity");
// Completely reset the marking state since marking completed
reset_at_marking_complete();
} else {
*** 1107,1117 ****
reset_marking_for_restart();
}
{
GCTraceTime(Debug, gc, phases)("Report Object Count");
! report_object_count();
}
// Statistics
double now = os::elapsedTime();
_remark_mark_times.add((mark_work_end - start) * 1000.0);
--- 1155,1165 ----
reset_marking_for_restart();
}
{
GCTraceTime(Debug, gc, phases)("Report Object Count");
! report_object_count(mark_finished);
}
// Statistics
double now = os::elapsedTime();
_remark_mark_times.add((mark_work_end - start) * 1000.0);
*** 1145,1156 ****
size_t freed_bytes() { return _freed_bytes; }
const uint old_regions_removed() { return _old_regions_removed; }
const uint humongous_regions_removed() { return _humongous_regions_removed; }
bool do_heap_region(HeapRegion *hr) {
- hr->note_end_of_marking();
-
if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young() && !hr->is_archive()) {
_freed_bytes += hr->used();
hr->set_containing_set(NULL);
if (hr->is_humongous()) {
_humongous_regions_removed++;
--- 1193,1202 ----
*** 1241,1251 ****
G1Policy* g1p = _g1h->g1_policy();
g1p->record_concurrent_mark_cleanup_start();
double start = os::elapsedTime();
! verify_during_pause(G1HeapVerifier::G1VerifyCleanup, VerifyOption_G1UseNextMarking, "Cleanup before");
{
GCTraceTime(Debug, gc, phases)("Update Remembered Set Tracking After Rebuild");
G1UpdateRemSetTrackingAfterRebuild cl(_g1h);
_g1h->heap_region_iterate(&cl);
--- 1287,1297 ----
G1Policy* g1p = _g1h->g1_policy();
g1p->record_concurrent_mark_cleanup_start();
double start = os::elapsedTime();
! verify_during_pause(G1HeapVerifier::G1VerifyCleanup, VerifyOption_G1UsePrevMarking, "Cleanup before");
{
GCTraceTime(Debug, gc, phases)("Update Remembered Set Tracking After Rebuild");
G1UpdateRemSetTrackingAfterRebuild cl(_g1h);
_g1h->heap_region_iterate(&cl);
*** 1254,1265 ****
if (log_is_enabled(Trace, gc, liveness)) {
G1PrintRegionLivenessInfoClosure cl("Post-Cleanup");
_g1h->heap_region_iterate(&cl);
}
- // Install newly created mark bitmap as "prev".
- swap_mark_bitmaps();
{
GCTraceTime(Debug, gc, phases)("Reclaim Empty Regions");
reclaim_empty_regions();
}
--- 1300,1309 ----
*** 1623,1637 ****
// class unloading is disabled.
_g1h->partial_cleaning(&g1_is_alive, false, false, G1StringDedup::is_enabled());
}
}
! void G1ConcurrentMark::report_object_count() {
G1CMIsAliveClosure is_alive(_g1h);
_gc_tracer_cm->report_object_count_after_gc(&is_alive);
}
void G1ConcurrentMark::swap_mark_bitmaps() {
G1CMBitMap* temp = _prev_mark_bitmap;
_prev_mark_bitmap = _next_mark_bitmap;
_next_mark_bitmap = temp;
_g1h->collector_state()->set_clearing_next_bitmap(true);
--- 1667,1703 ----
// class unloading is disabled.
_g1h->partial_cleaning(&g1_is_alive, false, false, G1StringDedup::is_enabled());
}
}
! // When sampling object counts, we already swapped the mark bitmaps, so we need to use
! // the prev bitmap determining liveness.
! class G1ObjectCountIsAliveClosure: public BoolObjectClosure {
! G1CollectedHeap* _g1;
! public:
! G1ObjectCountIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) { }
!
! bool do_object_b(oop obj) {
! HeapWord* addr = (HeapWord*)obj;
! return addr != NULL &&
! (!_g1->is_in_g1_reserved(addr) || !_g1->is_obj_dead(obj));
! }
! };
!
! void G1ConcurrentMark::report_object_count(bool mark_completed) {
! // Depending on the completion of the marking liveness needs to be determined
! // using either the next or prev bitmap.
! if (mark_completed) {
! G1ObjectCountIsAliveClosure is_alive(_g1h);
! _gc_tracer_cm->report_object_count_after_gc(&is_alive);
! } else {
G1CMIsAliveClosure is_alive(_g1h);
_gc_tracer_cm->report_object_count_after_gc(&is_alive);
+ }
}
+
void G1ConcurrentMark::swap_mark_bitmaps() {
G1CMBitMap* temp = _prev_mark_bitmap;
_prev_mark_bitmap = _next_mark_bitmap;
_next_mark_bitmap = temp;
_g1h->collector_state()->set_clearing_next_bitmap(true);
< prev index next >