From ecc365960ba7ff72f650b32190f40a1f1b6ff992 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Tue, 14 Aug 2018 17:04:04 -0400 Subject: [PATCH] runtime: avoid using STW GC mechanism for checkmarks mode Currently, checkmarks mode uses the full STW GC infrastructure to perform mark checking. We're about to remove that infrastructure and, furthermore, since checkmarks is about doing the simplest thing possible to check concurrent GC, it's valuable for it to be simpler. Hence, this CL makes checkmarks even simpler by making it non-parallel and divorcing it from the STW GC infrastructure (including the gchelper mechanism). Updates #26903. This is preparation for unifying STW GC and concurrent GC. Change-Id: Iad21158123e025e3f97d7986d577315e994bd43e Reviewed-on: https://go-review.googlesource.com/c/134776 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Rick Hudson --- src/runtime/mgc.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/runtime/mgc.go b/src/runtime/mgc.go index 25bb210475..9ae5eb7a62 100644 --- a/src/runtime/mgc.go +++ b/src/runtime/mgc.go @@ -1513,12 +1513,16 @@ func gcMarkTermination(nextTriggerRatio float64) { systemstack(func() { work.heap2 = work.bytesMarked if debug.gccheckmark > 0 { - // Run a full stop-the-world mark using checkmark bits, - // to check that we didn't forget to mark anything during - // the concurrent mark process. + // Run a full non-parallel, stop-the-world + // mark using checkmark bits, to check that we + // didn't forget to mark anything during the + // concurrent mark process. gcResetMarkState() initCheckmarks() - gcMark(startTime) + gcw := &getg().m.p.ptr().gcw + gcDrain(gcw, gcDrainNoBlock) + wbBufFlush1(getg().m.p.ptr()) + gcw.dispose() clearCheckmarks() } @@ -1905,12 +1909,12 @@ func gcMark(start_time int64) { work.helperDrainBlock = false } else { // There's marking work to do. This is the case during - // STW GC and in checkmark mode. Instruct GC workers + // STW GC. Instruct GC workers // to block in getfull until all GC workers are in getfull. // - // TODO(austin): Move STW and checkmark marking out of + // TODO(austin): Move STW marking out of // mark termination and eliminate this code path. - if !useCheckmark && debug.gcstoptheworld == 0 && debug.gcrescanstacks == 0 { + if debug.gcstoptheworld == 0 && debug.gcrescanstacks == 0 { print("runtime: full=", hex(work.full), " nDataRoots=", work.nDataRoots, " nBSSRoots=", work.nBSSRoots, " nSpanRoots=", work.nSpanRoots, " nStackRoots=", work.nStackRoots, "\n") panic("non-empty mark queue after concurrent mark") }