diff options
| author | Austin Clements <austin@google.com> | 2015-11-17 17:14:32 -0500 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2015-11-19 21:17:04 +0000 |
| commit | b43b375c6c3d540b8ed4ab69bfc634991cd5dcd3 (patch) | |
| tree | e0efbe078612d3f75e125f240de6e0439c09b557 /src/runtime/traceback.go | |
| parent | 26119179fa217da7f89d4c5930889bbbedbab8b9 (diff) | |
| download | go-b43b375c6c3d540b8ed4ab69bfc634991cd5dcd3.tar.xz | |
runtime: eliminate write barriers from gentraceback
gentraceback is used in many contexts where write barriers are
disallowed. This currently works because the only write barrier is in
assigning frame.argmap in setArgInfo and in practice frame is always
on the stack, so this write barrier is a no-op.
However, we can easily eliminate this write barrier, which will let us
statically disallow write barriers (using go:nowritebarrierrec
annotations) in many more situations. As a bonus, this makes the code
a little more idiomatic.
Updates #10600.
Change-Id: I45ba5cece83697ff79f8537ee6e43eadf1c18c6d
Reviewed-on: https://go-review.googlesource.com/17003
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Diffstat (limited to 'src/runtime/traceback.go')
| -rw-r--r-- | src/runtime/traceback.go | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index b636f58eed..8d1b758271 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -106,7 +106,7 @@ func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v uns } frame.fn = f frame.argp = uintptr(deferArgs(d)) - setArgInfo(&frame, f, true) + frame.arglen, frame.argmap = getArgInfo(&frame, f, true) } frame.continpc = frame.pc if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) { @@ -328,7 +328,7 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in // metadata recorded by f's caller. if callback != nil || printing { frame.argp = frame.fp + sys.MinFrameSize - setArgInfo(&frame, f, callback != nil) + frame.arglen, frame.argmap = getArgInfo(&frame, f, callback != nil) } // Determine frame's 'continuation PC', where it can continue. @@ -519,8 +519,8 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in return n } -func setArgInfo(frame *stkframe, f *_func, needArgMap bool) { - frame.arglen = uintptr(f.args) +func getArgInfo(frame *stkframe, f *_func, needArgMap bool) (arglen uintptr, argmap *bitvector) { + arglen = uintptr(f.args) if needArgMap && f.args == _ArgsSizeUnknown { // Extract argument bitmaps for reflect stubs from the calls they made to reflect. switch funcname(f) { @@ -532,10 +532,11 @@ func setArgInfo(frame *stkframe, f *_func, needArgMap bool) { throw("reflect mismatch") } bv := (*bitvector)(unsafe.Pointer(fn[1])) - frame.arglen = uintptr(bv.n * sys.PtrSize) - frame.argmap = bv + arglen = uintptr(bv.n * sys.PtrSize) + argmap = bv } } + return } func printcreatedby(gp *g) { |
