src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp

changeset 3208
ec4b032a4977
parent 3065
ff53346271fe
child 3218
db89aa49298f
equal deleted inserted replaced
3188:d1bdeef3e3e2 3208:ec4b032a4977
213 gclog_or_tty->date_stamp(PrintGCDateStamps); 213 gclog_or_tty->date_stamp(PrintGCDateStamps);
214 gclog_or_tty->stamp(PrintGCTimeStamps); 214 gclog_or_tty->stamp(PrintGCTimeStamps);
215 gclog_or_tty->print_cr("[GC concurrent-cleanup-start]"); 215 gclog_or_tty->print_cr("[GC concurrent-cleanup-start]");
216 } 216 }
217 217
218 // Now do the remainder of the cleanup operation. 218 // Now do the concurrent cleanup operation.
219 _cm->completeCleanup(); 219 _cm->completeCleanup();
220
220 // Notify anyone who's waiting that there are no more free 221 // Notify anyone who's waiting that there are no more free
221 // regions coming. We have to do this before we join the STS, 222 // regions coming. We have to do this before we join the STS
222 // otherwise we might deadlock: a GC worker could be blocked 223 // (in fact, we should not attempt to join the STS in the
223 // waiting for the notification whereas this thread will be 224 // interval between finishing the cleanup pause and clearing
224 // blocked for the pause to finish while it's trying to join 225 // the free_regions_coming flag) otherwise we might deadlock:
225 // the STS, which is conditional on the GC workers finishing. 226 // a GC worker could be blocked waiting for the notification
227 // whereas this thread will be blocked for the pause to finish
228 // while it's trying to join the STS, which is conditional on
229 // the GC workers finishing.
226 g1h->reset_free_regions_coming(); 230 g1h->reset_free_regions_coming();
227
228 _sts.join();
229 g1_policy->record_concurrent_mark_cleanup_completed();
230 _sts.leave();
231 231
232 double cleanup_end_sec = os::elapsedTime(); 232 double cleanup_end_sec = os::elapsedTime();
233 if (PrintGC) { 233 if (PrintGC) {
234 gclog_or_tty->date_stamp(PrintGCDateStamps); 234 gclog_or_tty->date_stamp(PrintGCDateStamps);
235 gclog_or_tty->stamp(PrintGCTimeStamps); 235 gclog_or_tty->stamp(PrintGCTimeStamps);
238 } 238 }
239 } 239 }
240 guarantee(cm()->cleanup_list_is_empty(), 240 guarantee(cm()->cleanup_list_is_empty(),
241 "at this point there should be no regions on the cleanup list"); 241 "at this point there should be no regions on the cleanup list");
242 242
243 // There is a tricky race before recording that the concurrent
244 // cleanup has completed and a potential Full GC starting around
245 // the same time. We want to make sure that the Full GC calls
246 // abort() on concurrent mark after
247 // record_concurrent_mark_cleanup_completed(), since abort() is
248 // the method that will reset the concurrent mark state. If we
249 // end up calling record_concurrent_mark_cleanup_completed()
250 // after abort() then we might incorrectly undo some of the work
251 // abort() did. Checking the has_aborted() flag after joining
252 // the STS allows the correct ordering of the two methods. There
253 // are two scenarios:
254 //
255 // a) If we reach here before the Full GC, the fact that we have
256 // joined the STS means that the Full GC cannot start until we
257 // leave the STS, so record_concurrent_mark_cleanup_completed()
258 // will complete before abort() is called.
259 //
260 // b) If we reach here during the Full GC, we'll be held up from
261 // joining the STS until the Full GC is done, which means that
262 // abort() will have completed and has_aborted() will return
263 // true to prevent us from calling
264 // record_concurrent_mark_cleanup_completed() (and, in fact, it's
265 // not needed any more as the concurrent mark state has been
266 // already reset).
267 _sts.join();
268 if (!cm()->has_aborted()) {
269 g1_policy->record_concurrent_mark_cleanup_completed();
270 }
271 _sts.leave();
272
243 if (cm()->has_aborted()) { 273 if (cm()->has_aborted()) {
244 if (PrintGC) { 274 if (PrintGC) {
245 gclog_or_tty->date_stamp(PrintGCDateStamps); 275 gclog_or_tty->date_stamp(PrintGCDateStamps);
246 gclog_or_tty->stamp(PrintGCTimeStamps); 276 gclog_or_tty->stamp(PrintGCTimeStamps);
247 gclog_or_tty->print_cr("[GC concurrent-mark-abort]"); 277 gclog_or_tty->print_cr("[GC concurrent-mark-abort]");
248 } 278 }
249 } 279 }
250 280
251 // we now want to allow clearing of the marking bitmap to be 281 // We now want to allow clearing of the marking bitmap to be
252 // suspended by a collection pause. 282 // suspended by a collection pause.
253 _sts.join(); 283 _sts.join();
254 _cm->clearNextBitmap(); 284 _cm->clearNextBitmap();
255 _sts.leave(); 285 _sts.leave();
256 } 286 }

mercurial