mirror of
https://github.com/golang/go
synced 2024-11-23 07:20:06 -07:00
runtime: add fast version of getArgInfo
getArgInfo is called a lot during stack copying. In the common case it doesn't do much work, but it cannot be inlined. This change works around that. name old time/op new time/op delta StackCopyPtr-8 108ms ± 5% 96ms ± 4% -10.40% (p=0.000 n=20+20) StackCopy-8 82.6ms ± 3% 78.4ms ± 6% -5.15% (p=0.000 n=19+20) StackCopyNoCache-8 130ms ± 3% 122ms ± 3% -6.44% (p=0.000 n=20+20) Change-Id: If7d8a08c50a4e2e76e4331b399396c5dbe88c2ce Reviewed-on: https://go-review.googlesource.com/108945 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
0fd427fda7
commit
13cd006139
@ -49,6 +49,7 @@ func TestIntendedInlining(t *testing.T) {
|
|||||||
"fastrand",
|
"fastrand",
|
||||||
"float64bits",
|
"float64bits",
|
||||||
"funcPC",
|
"funcPC",
|
||||||
|
"getArgInfoFast",
|
||||||
"getm",
|
"getm",
|
||||||
"isDirectIface",
|
"isDirectIface",
|
||||||
"itabHashFunc",
|
"itabHashFunc",
|
||||||
|
@ -67,8 +67,12 @@ 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))
|
||||||
|
var ok bool
|
||||||
|
frame.arglen, frame.argmap, ok = getArgInfoFast(f, true)
|
||||||
|
if !ok {
|
||||||
frame.arglen, frame.argmap = getArgInfo(&frame, f, true, fn)
|
frame.arglen, frame.argmap = getArgInfo(&frame, f, true, fn)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
frame.continpc = frame.pc
|
frame.continpc = frame.pc
|
||||||
if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) {
|
if !callback((*stkframe)(noescape(unsafe.Pointer(&frame))), v) {
|
||||||
return
|
return
|
||||||
@ -279,8 +283,12 @@ 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
|
||||||
|
var ok bool
|
||||||
|
frame.arglen, frame.argmap, ok = getArgInfoFast(f, callback != nil)
|
||||||
|
if !ok {
|
||||||
frame.arglen, frame.argmap = getArgInfo(&frame, f, callback != nil, nil)
|
frame.arglen, frame.argmap = getArgInfo(&frame, f, callback != nil, nil)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Determine frame's 'continuation PC', where it can continue.
|
// Determine frame's 'continuation PC', where it can continue.
|
||||||
// Normally this is the return address on the stack, but if sigpanic
|
// Normally this is the return address on the stack, but if sigpanic
|
||||||
@ -546,6 +554,15 @@ type reflectMethodValue struct {
|
|||||||
stack *bitvector // args bitmap
|
stack *bitvector // args bitmap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getArgInfoFast returns the argument frame information for a call to f.
|
||||||
|
// It is short and inlineable. However, it does not handle all functions.
|
||||||
|
// If ok reports false, you must call getArgInfo instead.
|
||||||
|
// TODO(josharian): once we do mid-stack inlining,
|
||||||
|
// call getArgInfo directly from getArgInfoFast and stop returning an ok bool.
|
||||||
|
func getArgInfoFast(f funcInfo, needArgMap bool) (arglen uintptr, argmap *bitvector, ok bool) {
|
||||||
|
return uintptr(f.args), nil, !(needArgMap && f.args == _ArgsSizeUnknown)
|
||||||
|
}
|
||||||
|
|
||||||
// getArgInfo returns the argument frame information for a call to f
|
// getArgInfo returns the argument frame information for a call to f
|
||||||
// with call frame frame.
|
// with call frame frame.
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user