From b43b375c6c3d540b8ed4ab69bfc634991cd5dcd3 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Tue, 17 Nov 2015 17:14:32 -0500 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Dmitry Vyukov --- src/runtime/traceback.go | 13 +++++++------ 1 file 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) {