aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/export_test.go
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2017-10-27 15:20:21 -0400
committerAustin Clements <austin@google.com>2017-10-30 16:33:55 +0000
commit15d6ab69fbd8c84cde109def59c7e002296c19e8 (patch)
tree4e41f0e94965a21024d4c3bd13011edfea04922c /src/runtime/export_test.go
parent67a7d5d88503646a7e411cf5ae9c38e485b9be1b (diff)
downloadgo-15d6ab69fbd8c84cde109def59c7e002296c19e8.tar.xz
runtime: make systemstack tail call if already switched
Currently systemstack always calls its argument, even if we're already on the system stack. Unfortunately, traceback with _TraceJump stops at the first systemstack it sees, which often cuts off runtime stacks early in profiles. Fix this by performing a tail call if we're already on the system stack. This eliminates it from the traceback entirely, so it won't stop prematurely (or all get mushed into a single node in the profile graph). Change-Id: Ibc69e8765e899f8d3806078517b8c7314da196f4 Reviewed-on: https://go-review.googlesource.com/74050 Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/runtime/export_test.go')
-rw-r--r--src/runtime/export_test.go13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/runtime/export_test.go b/src/runtime/export_test.go
index 9b269d9659..599ac2d84a 100644
--- a/src/runtime/export_test.go
+++ b/src/runtime/export_test.go
@@ -395,3 +395,16 @@ func LockOSCounts() (external, internal uint32) {
}
return g.m.lockedExt, g.m.lockedInt
}
+
+//go:noinline
+func TracebackSystemstack(stk []uintptr, i int) int {
+ if i == 0 {
+ pc, sp := getcallerpc(), getcallersp(unsafe.Pointer(&stk))
+ return gentraceback(pc, sp, 0, getg(), 0, &stk[0], len(stk), nil, nil, _TraceJumpStack)
+ }
+ n := 0
+ systemstack(func() {
+ n = TracebackSystemstack(stk, i-1)
+ })
+ return n
+}