From: Josh Bleecher Snyder Date: Sat, 31 Mar 2018 05:54:00 +0000 (-0700) Subject: runtime: add fast version of getArgInfo X-Git-Tag: go1.11beta1~634 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=13cd0061390af0621516ec22b1a3987712b4da3b;p=gostls13.git 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 TryBot-Result: Gobot Gobot Reviewed-by: Austin Clements --- diff --git a/src/cmd/compile/internal/gc/inl_test.go b/src/cmd/compile/internal/gc/inl_test.go index d1dc6fbbfa..de877f6997 100644 --- a/src/cmd/compile/internal/gc/inl_test.go +++ b/src/cmd/compile/internal/gc/inl_test.go @@ -49,6 +49,7 @@ func TestIntendedInlining(t *testing.T) { "fastrand", "float64bits", "funcPC", + "getArgInfoFast", "getm", "isDirectIface", "itabHashFunc", diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go index 2fb8aea59d..0743449b3c 100644 --- a/src/runtime/traceback.go +++ b/src/runtime/traceback.go @@ -67,7 +67,11 @@ func tracebackdefers(gp *g, callback func(*stkframe, unsafe.Pointer) bool, v uns } frame.fn = f 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 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 // metadata recorded by f's caller. if callback != nil || printing { 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. @@ -546,6 +554,15 @@ type reflectMethodValue struct { 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 // with call frame frame. //