Tue, 17 Jan 2012 10:21:43 -0800
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