pauseStart = now
systemstack(stopTheWorldWithSema)
- systemstack(finishsweep_m) // finish sweep before we start concurrent scan.
+ // Finish sweep before we start concurrent scan.
+ systemstack(func() {
+ finishsweep_m(true)
+ })
// clearpools before we start the GC. If we wait they memory will not be
// reclaimed until the next GC cycle.
clearpools()
// Reset these so that all stacks will be rescanned.
gcResetGState()
gcResetMarkState()
- finishsweep_m()
+ finishsweep_m(true)
// Still in STW but gcphase is _GCoff, reset to _GCmarktermination
// At this point all objects will be found during the gcMark which
}
//go:nowritebarrier
-func finishsweep_m() {
- // The world is stopped so we should be able to complete the sweeps
- // quickly.
+func finishsweep_m(stw bool) {
+ // Sweeping must be complete before marking commences, so
+ // sweep any unswept spans. If this is a concurrent GC, there
+ // shouldn't be any spans left to sweep, so this should finish
+ // instantly. If GC was forced before the concurrent sweep
+ // finished, there may be spans to sweep.
for sweepone() != ^uintptr(0) {
sweep.npausesweep++
}
// There may be some other spans being swept concurrently that
// we need to wait for. If finishsweep_m is done with the world stopped
- // this code is not required.
- sg := mheap_.sweepgen
- for _, s := range work.spans {
- if s.sweepgen != sg && s.state == _MSpanInUse {
- mSpan_EnsureSwept(s)
+ // this is not required because the STW must have waited for sweeps.
+ //
+ // TODO(austin): As of this writing, we always pass true for stw.
+ // Consider removing this code.
+ if !stw {
+ sg := mheap_.sweepgen
+ for _, s := range work.spans {
+ if s.sweepgen != sg && s.state == _MSpanInUse {
+ mSpan_EnsureSwept(s)
+ }
}
}
}