Commit 7b229001 authored by Austin Clements's avatar Austin Clements

runtime: pass gcWork to markroot

Currently markroot uses a gcWork on the stack and disposes of it
immediately after marking one root. This used to be necessary because
markroot was called from the depths of parfor, but now that we call it
directly and have ready access to a gcWork at the call site, pass the
gcWork in, use it directly in markroot, and share it across calls to
markroot from the same P.

Change-Id: Id7c3b811bfb944153760e01873c07c8d18909be1
Reviewed-on: https://go-review.googlesource.com/19635Reviewed-by: 's avatarRick Hudson <rlh@golang.org>
Run-TryBot: Austin Clements <austin@google.com>
parent 98130b39
...@@ -98,10 +98,7 @@ var oneptrmask = [...]uint8{1} ...@@ -98,10 +98,7 @@ var oneptrmask = [...]uint8{1}
// Preemption must be disabled (because this uses a gcWork). // Preemption must be disabled (because this uses a gcWork).
// //
//go:nowritebarrier //go:nowritebarrier
func markroot(i uint32) { func markroot(gcw *gcWork, i uint32) {
// TODO: Consider using getg().m.p.ptr().gcw.
var gcw gcWork
baseData := uint32(fixedRootCount) baseData := uint32(fixedRootCount)
baseBSS := baseData + uint32(work.nDataRoots) baseBSS := baseData + uint32(work.nDataRoots)
baseSpans := baseBSS + uint32(work.nBSSRoots) baseSpans := baseBSS + uint32(work.nBSSRoots)
...@@ -111,17 +108,17 @@ func markroot(i uint32) { ...@@ -111,17 +108,17 @@ func markroot(i uint32) {
switch { switch {
case baseData <= i && i < baseBSS: case baseData <= i && i < baseBSS:
for datap := &firstmoduledata; datap != nil; datap = datap.next { for datap := &firstmoduledata; datap != nil; datap = datap.next {
markrootBlock(datap.data, datap.edata-datap.data, datap.gcdatamask.bytedata, &gcw, int(i-baseData)) markrootBlock(datap.data, datap.edata-datap.data, datap.gcdatamask.bytedata, gcw, int(i-baseData))
} }
case baseBSS <= i && i < baseSpans: case baseBSS <= i && i < baseSpans:
for datap := &firstmoduledata; datap != nil; datap = datap.next { for datap := &firstmoduledata; datap != nil; datap = datap.next {
markrootBlock(datap.bss, datap.ebss-datap.bss, datap.gcbssmask.bytedata, &gcw, int(i-baseBSS)) markrootBlock(datap.bss, datap.ebss-datap.bss, datap.gcbssmask.bytedata, gcw, int(i-baseBSS))
} }
case i == fixedRootFinalizers: case i == fixedRootFinalizers:
for fb := allfin; fb != nil; fb = fb.alllink { for fb := allfin; fb != nil; fb = fb.alllink {
scanblock(uintptr(unsafe.Pointer(&fb.fin[0])), uintptr(fb.cnt)*unsafe.Sizeof(fb.fin[0]), &finptrmask[0], &gcw) scanblock(uintptr(unsafe.Pointer(&fb.fin[0])), uintptr(fb.cnt)*unsafe.Sizeof(fb.fin[0]), &finptrmask[0], gcw)
} }
case i == fixedRootFlushCaches: case i == fixedRootFlushCaches:
...@@ -131,7 +128,7 @@ func markroot(i uint32) { ...@@ -131,7 +128,7 @@ func markroot(i uint32) {
case baseSpans <= i && i < baseStacks: case baseSpans <= i && i < baseStacks:
// mark MSpan.specials // mark MSpan.specials
markrootSpans(&gcw, int(i-baseSpans)) markrootSpans(gcw, int(i-baseSpans))
default: default:
// the rest is scanning goroutine stacks // the rest is scanning goroutine stacks
...@@ -193,8 +190,6 @@ func markroot(i uint32) { ...@@ -193,8 +190,6 @@ func markroot(i uint32) {
} }
}) })
} }
gcw.dispose()
} }
// markrootBlock scans the shard'th shard of the block of memory [b0, // markrootBlock scans the shard'th shard of the block of memory [b0,
...@@ -808,8 +803,7 @@ func gcDrain(gcw *gcWork, flags gcDrainFlags) { ...@@ -808,8 +803,7 @@ func gcDrain(gcw *gcWork, flags gcDrainFlags) {
if job >= work.markrootJobs { if job >= work.markrootJobs {
break break
} }
// TODO: Pass in gcw. markroot(gcw, job)
markroot(job)
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment