mirror of
https://github.com/golang/go
synced 2024-11-12 04:30:22 -07:00
runtime: remove stack barriers during sweep
This adds a best-effort pass to remove stack barriers immediately after the end of mark termination. This isn't necessary for the Go runtime, but should help external tools that perform stack walks but aren't aware of Go's stack barriers such as GDB, perf, and VTune. (Though clearly they'll still have trouble unwinding stacks during mark.) Change-Id: I66600fae1f03ee36b5459d2b00dcc376269af18e Reviewed-on: https://go-review.googlesource.com/20668 Reviewed-by: Rick Hudson <rlh@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
269c969c81
commit
9f263c14ed
@ -1266,6 +1266,13 @@ func gcMarkTermination() {
|
||||
// Free stack spans. This must be done between GC cycles.
|
||||
systemstack(freeStackSpans)
|
||||
|
||||
// Best-effort remove stack barriers so they don't get in the
|
||||
// way of things like GDB and perf.
|
||||
lock(&allglock)
|
||||
myallgs := allgs
|
||||
unlock(&allglock)
|
||||
gcTryRemoveAllStackBarriers(myallgs)
|
||||
|
||||
// Print gctrace before dropping worldsema. As soon as we drop
|
||||
// worldsema another cycle could start and smash the stats
|
||||
// we're trying to print.
|
||||
|
@ -257,6 +257,31 @@ func gcRemoveStackBarrier(gp *g, stkbar stkbar) {
|
||||
*lrPtr = sys.Uintreg(stkbar.savedLRVal)
|
||||
}
|
||||
|
||||
// gcTryRemoveAllStackBarriers tries to remove stack barriers from all
|
||||
// Gs in gps. It is best-effort and efficient. If it can't remove
|
||||
// barriers from a G immediately, it will simply skip it.
|
||||
func gcTryRemoveAllStackBarriers(gps []*g) {
|
||||
for _, gp := range gps {
|
||||
retry:
|
||||
for {
|
||||
switch s := readgstatus(gp); s {
|
||||
default:
|
||||
break retry
|
||||
|
||||
case _Grunnable, _Gsyscall, _Gwaiting:
|
||||
if !castogscanstatus(gp, s, s|_Gscan) {
|
||||
continue
|
||||
}
|
||||
gcLockStackBarriers(gp)
|
||||
gcRemoveStackBarriers(gp)
|
||||
gcUnlockStackBarriers(gp)
|
||||
restartg(gp)
|
||||
break retry
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// gcPrintStkbars prints the stack barriers of gp for debugging. It
|
||||
// places a "@@@" marker at gp.stkbarPos. If marker >= 0, it will also
|
||||
// place a "==>" marker before the marker'th entry.
|
||||
|
Loading…
Reference in New Issue
Block a user