From c5ebcd2c8ac6c5bdf85ec0a346974efd4b0cbe49 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Thu, 9 Feb 2017 11:50:26 -0500 Subject: runtime: remove rescan list With the hybrid barrier, rescanning stacks is no longer necessary so the rescan list is no longer necessary. Remove it. This leaves the gcrescanstacks GODEBUG variable, since it's useful for debugging, but changes it to simply walk all of the Gs to rescan stacks rather than using the rescan list. We could also remove g.gcscanvalid, which is effectively a distributed rescan list. However, it's still useful for gcrescanstacks mode and it adds little complexity, so we'll leave it in. Fixes #17099. Updates #17503. Change-Id: I776d43f0729567335ef1bfd145b75c74de2cc7a9 Reviewed-on: https://go-review.googlesource.com/36619 Run-TryBot: Austin Clements TryBot-Result: Gobot Gobot Reviewed-by: Rick Hudson --- src/runtime/proc.go | 34 +++++----------------------------- 1 file changed, 5 insertions(+), 29 deletions(-) (limited to 'src/runtime/proc.go') diff --git a/src/runtime/proc.go b/src/runtime/proc.go index e71ebcd7a7..11e1e21291 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -432,16 +432,6 @@ func allgadd(gp *g) { lock(&allglock) allgs = append(allgs, gp) allglen = uintptr(len(allgs)) - - // Grow GC rescan list if necessary. - if len(allgs) > cap(work.rescan.list) { - lock(&work.rescan.lock) - l := work.rescan.list - // Let append do the heavy lifting, but keep the - // length the same. - work.rescan.list = append(l[:cap(l)], 0)[:len(l)] - unlock(&work.rescan.lock) - } unlock(&allglock) } @@ -795,9 +785,8 @@ func casgstatus(gp *g, oldval, newval uint32) { nextYield = nanotime() + yieldDelay/2 } } - if newval == _Grunning && gp.gcscanvalid { - // Run queueRescan on the system stack so it has more space. - systemstack(func() { queueRescan(gp) }) + if newval == _Grunning { + gp.gcscanvalid = false } } @@ -1481,9 +1470,8 @@ func oneNewExtraM() { gp.syscallpc = gp.sched.pc gp.syscallsp = gp.sched.sp gp.stktopsp = gp.sched.sp - gp.gcscanvalid = true // fresh G, so no dequeueRescan necessary + gp.gcscanvalid = true gp.gcscandone = true - gp.gcRescan = -1 // malg returns status as Gidle, change to Gsyscall before adding to allg // where GC will see it. casgstatus(gp, _Gidle, _Gsyscall) @@ -2346,8 +2334,7 @@ func goexit0(gp *g) { gp.labels = nil // Note that gp's stack scan is now "valid" because it has no - // stack. We could dequeueRescan, but that takes a lock and - // isn't really necessary. + // stack. gp.gcscanvalid = true dropg() @@ -2875,7 +2862,6 @@ func newproc1(fn *funcval, argp *uint8, narg int32, nret int32, callerpc uintptr if newg == nil { newg = malg(_StackMin) casgstatus(newg, _Gidle, _Gdead) - newg.gcRescan = -1 allgadd(newg) // publishes with a g->status of Gdead so GC scanner doesn't look at uninitialized stack. } if newg.stack.hi == 0 { @@ -2927,17 +2913,7 @@ func newproc1(fn *funcval, argp *uint8, narg int32, nret int32, callerpc uintptr if isSystemGoroutine(newg) { atomic.Xadd(&sched.ngsys, +1) } - // The stack is dirty from the argument frame, so queue it for - // scanning. Do this before setting it to runnable so we still - // own the G. If we're recycling a G, it may already be on the - // rescan list. - if newg.gcRescan == -1 { - queueRescan(newg) - } else { - // The recycled G is already on the rescan list. Just - // mark the stack dirty. - newg.gcscanvalid = false - } + newg.gcscanvalid = false casgstatus(newg, _Gdead, _Grunnable) if _p_.goidcache == _p_.goidcacheend { -- cgit v1.3-5-g9baa