1
0
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:
Austin Clements 2016-03-02 17:55:45 -05:00
parent 269c969c81
commit 9f263c14ed
2 changed files with 32 additions and 0 deletions

View File

@ -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.

View File

@ -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.