diff options
Diffstat (limited to 'src/runtime/mgcmark.go')
| -rw-r--r-- | src/runtime/mgcmark.go | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/runtime/mgcmark.go b/src/runtime/mgcmark.go index 8340f39a4b..5aabc14b40 100644 --- a/src/runtime/mgcmark.go +++ b/src/runtime/mgcmark.go @@ -18,6 +18,7 @@ import ( const ( fixedRootFinalizers = iota fixedRootFreeGStacks + fixedRootCleanups fixedRootCount // rootBlockBytes is the number of bytes to scan per data or @@ -179,8 +180,6 @@ func markroot(gcw *gcWork, i uint32, flushBgCredit bool) int64 { case i == fixedRootFinalizers: for fb := allfin; fb != nil; fb = fb.alllink { cnt := uintptr(atomic.Load(&fb.cnt)) - // Finalizers that contain cleanups only have fn set. None of the other - // fields are necessary. scanblock(uintptr(unsafe.Pointer(&fb.fin[0])), cnt*unsafe.Sizeof(fb.fin[0]), &finptrmask[0], gcw, nil) } @@ -189,6 +188,14 @@ func markroot(gcw *gcWork, i uint32, flushBgCredit bool) int64 { // stackfree. systemstack(markrootFreeGStacks) + case i == fixedRootCleanups: + for cb := (*cleanupBlock)(gcCleanups.all.Load()); cb != nil; cb = cb.alllink { + // N.B. This only needs to synchronize with cleanup execution, which only resets these blocks. + // All cleanup queueing happens during sweep. + n := uintptr(atomic.Load(&cb.n)) + scanblock(uintptr(unsafe.Pointer(&cb.cleanups[0])), n*goarch.PtrSize, &cleanupBlockPtrMask[0], gcw, nil) + } + case work.baseSpans <= i && i < work.baseStacks: // mark mspan.specials markrootSpans(gcw, int(i-work.baseSpans)) |
