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:
parent
26119179fa
commit
b43b375c6c
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user