7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output

Tue, 17 Jan 2012 10:21:43 -0800

author
johnc
date
Tue, 17 Jan 2012 10:21:43 -0800
changeset 3458
7ca7be5a6a0b
parent 3457
0b3d1ec6eaee
child 3459
a8a126788ea0

7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
Summary: During an initial mark pause, signal the Concurrent Mark thread after the pause output from PrintGC/PrintGCDetails is complete.
Reviewed-by: tonyp, brutisso

src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Jan 18 10:30:12 2012 -0500
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Jan 17 10:21:43 2012 -0800
     1.3 @@ -3557,19 +3557,25 @@
     1.4    verify_region_sets_optional();
     1.5    verify_dirty_young_regions();
     1.6  
     1.7 +  // This call will decide whether this pause is an initial-mark
     1.8 +  // pause. If it is, during_initial_mark_pause() will return true
     1.9 +  // for the duration of this pause.
    1.10 +  g1_policy()->decide_on_conc_mark_initiation();
    1.11 +
    1.12 +  // We do not allow initial-mark to be piggy-backed on a mixed GC.
    1.13 +  assert(!g1_policy()->during_initial_mark_pause() ||
    1.14 +          g1_policy()->gcs_are_young(), "sanity");
    1.15 +
    1.16 +  // We also do not allow mixed GCs during marking.
    1.17 +  assert(!mark_in_progress() || g1_policy()->gcs_are_young(), "sanity");
    1.18 +
    1.19 +  // Record whether this pause is an initial mark. When the current
    1.20 +  // thread has completed its logging output and it's safe to signal
    1.21 +  // the CM thread, the flag's value in the policy has been reset.
    1.22 +  bool should_start_conc_mark = g1_policy()->during_initial_mark_pause();
    1.23 +
    1.24 +  // Inner scope for scope based logging, timers, and stats collection
    1.25    {
    1.26 -    // This call will decide whether this pause is an initial-mark
    1.27 -    // pause. If it is, during_initial_mark_pause() will return true
    1.28 -    // for the duration of this pause.
    1.29 -    g1_policy()->decide_on_conc_mark_initiation();
    1.30 -
    1.31 -    // We do not allow initial-mark to be piggy-backed on a mixed GC.
    1.32 -    assert(!g1_policy()->during_initial_mark_pause() ||
    1.33 -            g1_policy()->gcs_are_young(), "sanity");
    1.34 -
    1.35 -    // We also do not allow mixed GCs during marking.
    1.36 -    assert(!mark_in_progress() || g1_policy()->gcs_are_young(), "sanity");
    1.37 -
    1.38      char verbose_str[128];
    1.39      sprintf(verbose_str, "GC pause ");
    1.40      if (g1_policy()->gcs_are_young()) {
    1.41 @@ -3625,7 +3631,6 @@
    1.42          Universe::verify(/* allow dirty */ false,
    1.43                           /* silent      */ false,
    1.44                           /* option      */ VerifyOption_G1UsePrevMarking);
    1.45 -
    1.46        }
    1.47  
    1.48        COMPILER2_PRESENT(DerivedPointerTable::clear());
    1.49 @@ -3779,14 +3784,9 @@
    1.50          if (g1_policy()->during_initial_mark_pause()) {
    1.51            concurrent_mark()->checkpointRootsInitialPost();
    1.52            set_marking_started();
    1.53 -          // CAUTION: after the doConcurrentMark() call below,
    1.54 -          // the concurrent marking thread(s) could be running
    1.55 -          // concurrently with us. Make sure that anything after
    1.56 -          // this point does not assume that we are the only GC thread
    1.57 -          // running. Note: of course, the actual marking work will
    1.58 -          // not start until the safepoint itself is released in
    1.59 -          // ConcurrentGCThread::safepoint_desynchronize().
    1.60 -          doConcurrentMark();
    1.61 +          // Note that we don't actually trigger the CM thread at
    1.62 +          // this point. We do that later when we're sure that
    1.63 +          // the current thread has completed its logging output.
    1.64          }
    1.65  
    1.66          allocate_dummy_regions();
    1.67 @@ -3896,6 +3896,15 @@
    1.68      }
    1.69    }
    1.70  
    1.71 +  // The closing of the inner scope, immediately above, will complete
    1.72 +  // the PrintGC logging output. The record_collection_pause_end() call
    1.73 +  // above will complete the logging output of PrintGCDetails.
    1.74 +  //
    1.75 +  // It is not yet to safe, however, to tell the concurrent mark to
    1.76 +  // start as we have some optional output below. We don't want the
    1.77 +  // output from the concurrent mark thread interfering with this
    1.78 +  // logging output either.
    1.79 +
    1.80    _hrs.verify_optional();
    1.81    verify_region_sets_optional();
    1.82  
    1.83 @@ -3913,6 +3922,21 @@
    1.84      g1_rem_set()->print_summary_info();
    1.85    }
    1.86  
    1.87 +  // It should now be safe to tell the concurrent mark thread to start
    1.88 +  // without its logging output interfering with the logging output
    1.89 +  // that came from the pause.
    1.90 +
    1.91 +  if (should_start_conc_mark) {
    1.92 +    // CAUTION: after the doConcurrentMark() call below,
    1.93 +    // the concurrent marking thread(s) could be running
    1.94 +    // concurrently with us. Make sure that anything after
    1.95 +    // this point does not assume that we are the only GC thread
    1.96 +    // running. Note: of course, the actual marking work will
    1.97 +    // not start until the safepoint itself is released in
    1.98 +    // ConcurrentGCThread::safepoint_desynchronize().
    1.99 +    doConcurrentMark();
   1.100 +  }
   1.101 +
   1.102    return true;
   1.103  }
   1.104  

mercurial