Commit 13cd0061 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

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: default avatarAustin Clements <austin@google.com>
parent 0fd427fd
...@@ -49,6 +49,7 @@ func TestIntendedInlining(t *testing.T) { ...@@ -49,6 +49,7 @@ func TestIntendedInlining(t *testing.T) {
"fastrand", "fastrand",
"float64bits", "float64bits",
"funcPC", "funcPC",
"getArgInfoFast",
"getm", "getm",
"isDirectIface", "isDirectIface",
"itabHashFunc", "itabHashFunc",
......
...@@ -67,7 +67,11 @@ func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v uns ...@@ -67,7 +67,11 @@ 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))
frame.arglen, frame.argmap = getArgInfo(&frame, f, true, fn) var ok bool
frame.arglen, frame.argmap, ok = getArgInfoFast(f, true)
if !ok {
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) {
...@@ -279,7 +283,11 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in ...@@ -279,7 +283,11 @@ 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
frame.arglen, frame.argmap = getArgInfo(&frame, f, callback != nil, nil) var ok bool
frame.arglen, frame.argmap, ok = getArgInfoFast(f, callback != nil)
if !ok {
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.
...@@ -546,6 +554,15 @@ type reflectMethodValue struct { ...@@ -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.
// //
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment