]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add fast version of getArgInfo
authorJosh Bleecher Snyder <josharian@gmail.com>
Sat, 31 Mar 2018 05:54:00 +0000 (22:54 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Sun, 29 Apr 2018 03:33:09 +0000 (03:33 +0000)
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>
src/cmd/compile/internal/gc/inl_test.go
src/runtime/traceback.go

index d1dc6fbbfa1bb6177c5c7d8ab587683d8aac0f23..de877f6997b14422b2912db7e255bf10c4e58647 100644 (file)
@@ -49,6 +49,7 @@ func TestIntendedInlining(t *testing.T) {
                        "fastrand",
                        "float64bits",
                        "funcPC",
+                       "getArgInfoFast",
                        "getm",
                        "isDirectIface",
                        "itabHashFunc",
index 2fb8aea59d5d2d65d97f87a2001d17fb0d70c7f6..0743449b3c68dc0c159407c4ec3ab7ebfcfca4ab 100644 (file)
@@ -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.
 //