< prev index next >

src/share/vm/gc/g1/g1CollectorPolicy.cpp

Print this page
rev 9277 : imported patch 8140597-forcing-initial-mark-causes-abort-mixed-collections

@@ -928,12 +928,16 @@
 
 double G1CollectorPolicy::constant_other_time_ms(double pause_time_ms) const {
   return other_time_ms(pause_time_ms) - young_other_time_ms() - non_young_other_time_ms();
 }
 
+bool G1CollectorPolicy::about_to_start_mixed_phase() const {
+  return _g1->concurrent_mark()->cmThread()->during_cycle() || collector_state()->last_young_gc();
+}
+
 bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) {
-  if (_g1->concurrent_mark()->cmThread()->during_cycle()) {
+  if (about_to_start_mixed_phase()) {
     return false;
   }
 
   size_t marking_initiating_used_threshold =
     (_g1->capacity() / 100) * InitiatingHeapOccupancyPercent;

@@ -1069,21 +1073,17 @@
   }
 
   if (collector_state()->last_young_gc()) {
     // This is supposed to to be the "last young GC" before we start
     // doing mixed GCs. Here we decide whether to start mixed GCs or not.
+    assert(!last_pause_included_initial_mark, "The last young GC is not allowed to be an initial mark GC");
 
-    if (!last_pause_included_initial_mark) {
       if (next_gc_should_be_mixed("start mixed GCs",
                                   "do not start mixed GCs")) {
         collector_state()->set_gcs_are_young(false);
       }
-    } else {
-      ergo_verbose0(ErgoMixedGCs,
-                    "do not start mixed GCs",
-                    ergo_format_reason("concurrent cycle is about to start"));
-    }
+
     collector_state()->set_last_young_gc(false);
   }
 
   if (!collector_state()->last_gc_was_young()) {
     // This is a mixed GC. Here we decide whether to continue doing

@@ -1597,12 +1597,14 @@
 
   _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
         HeapRegion::GrainWords * _max_survivor_regions, counters());
 }
 
-bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(
-                                                     GCCause::Cause gc_cause) {
+bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(GCCause::Cause gc_cause) {
+  // We actually check whether we are marking here and not if we are in a
+  // reclamation phase. This means that we will schedule a concurrent mark
+  // even while we are still in the process of reclaiming memory.
   bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
   if (!during_cycle) {
     ergo_verbose1(ErgoConcCycles,
                   "request concurrent cycle initiation",
                   ergo_format_reason("requested by GC cause")

@@ -1618,12 +1620,11 @@
                   GCCause::to_string(gc_cause));
     return false;
   }
 }
 
-void
-G1CollectorPolicy::decide_on_conc_mark_initiation() {
+void G1CollectorPolicy::decide_on_conc_mark_initiation() {
   // We are about to decide on whether this pause will be an
   // initial-mark pause.
 
   // First, collector_state()->during_initial_mark_pause() should not be already set. We
   // will set it here if we have to. However, it should be cleared by

@@ -1634,25 +1635,15 @@
   if (collector_state()->initiate_conc_mark_if_possible()) {
     // We had noticed on a previous pause that the heap occupancy has
     // gone over the initiating threshold and we should start a
     // concurrent marking cycle. So we might initiate one.
 
-    bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
-    if (!during_cycle) {
-      // The concurrent marking thread is not "during a cycle", i.e.,
-      // it has completed the last one. So we can go ahead and
-      // initiate a new cycle.
+    if (!about_to_start_mixed_phase() && collector_state()->gcs_are_young()) {
+      // Initiate a new initial mark only if there is no marking or reclamation going
+      // on.
 
       collector_state()->set_during_initial_mark_pause(true);
-      // We do not allow mixed GCs during marking.
-      if (!collector_state()->gcs_are_young()) {
-        collector_state()->set_gcs_are_young(true);
-        ergo_verbose0(ErgoMixedGCs,
-                      "end mixed GCs",
-                      ergo_format_reason("concurrent cycle is about to start"));
-      }
-
       // And we can now clear initiate_conc_mark_if_possible() as
       // we've already acted on it.
       collector_state()->set_initiate_conc_mark_if_possible(false);
 
       ergo_verbose0(ErgoConcCycles,
< prev index next >