1
0
mirror of https://github.com/golang/go synced 2024-11-18 00:54:45 -07:00

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>
This commit is contained in:
Austin Clements 2015-11-17 17:14:32 -05:00
parent 26119179fa
commit b43b375c6c

View File

@ -106,7 +106,7 @@ func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v uns
} }
frame.fn = f frame.fn = f
frame.argp = uintptr(deferArgs(d)) frame.argp = uintptr(deferArgs(d))
setArgInfo(&frame, f, true) frame.arglen, frame.argmap = getArgInfo(&frame, f, true)
} }
frame.continpc = frame.pc frame.continpc = frame.pc
if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) { 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. // metadata recorded by f's caller.
if callback != nil || printing { if callback != nil || printing {
frame.argp = frame.fp + sys.MinFrameSize 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. // 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 return n
} }
func setArgInfo(frame *stkframe, f *_func, needArgMap bool) { func getArgInfo(frame *stkframe, f *_func, needArgMap bool) (arglen uintptr, argmap *bitvector) {
frame.arglen = uintptr(f.args) arglen = uintptr(f.args)
if needArgMap && f.args == _ArgsSizeUnknown { if needArgMap && f.args == _ArgsSizeUnknown {
// Extract argument bitmaps for reflect stubs from the calls they made to reflect. // Extract argument bitmaps for reflect stubs from the calls they made to reflect.
switch funcname(f) { switch funcname(f) {
@ -532,10 +532,11 @@ func setArgInfo(frame *stkframe, f *_func, needArgMap bool) {
throw("reflect mismatch") throw("reflect mismatch")
} }
bv := (*bitvector)(unsafe.Pointer(fn[1])) bv := (*bitvector)(unsafe.Pointer(fn[1]))
frame.arglen = uintptr(bv.n * sys.PtrSize) arglen = uintptr(bv.n * sys.PtrSize)
frame.argmap = bv argmap = bv
} }
} }
return
} }
func printcreatedby(gp *g) { func printcreatedby(gp *g) {