]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: avoid calling adjustpointers unnecessarily
authorJosh Bleecher Snyder <josharian@gmail.com>
Wed, 4 Apr 2018 16:24:13 +0000 (09:24 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Thu, 5 Apr 2018 21:43:23 +0000 (21:43 +0000)
adjustpointers loops over a bitmap.
If the length of that bitmap is zero,
we can skip making the call entirely.
This speeds up stack copying when there are
no pointers present in either args or locals.

name                old time/op  new time/op  delta
StackCopyPtr-8       101ms ± 4%    90ms ± 4%  -10.95%  (p=0.000 n=87+93)
StackCopy-8         80.1ms ± 4%  72.6ms ± 4%   -9.41%  (p=0.000 n=98+100)
StackCopyNoCache-8   121ms ± 3%   113ms ± 3%   -6.57%  (p=0.000 n=98+97)

Change-Id: I7a272e19bc9a14fa3e3318771ebd082dc6247d25
Reviewed-on: https://go-review.googlesource.com/104737
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
src/runtime/stack.go

index 2dc7001e381c9f87bfcf512aff339b82078a84bf..63a286bf592ec2f5d8450730a3384c0eb3f02a83 100644 (file)
@@ -643,24 +643,28 @@ func adjustframe(frame *stkframe, arg unsafe.Pointer) bool {
                minsize = sys.MinFrameSize
        }
        if size > minsize {
-               var bv bitvector
                stackmap := (*stackmap)(funcdata(f, _FUNCDATA_LocalsPointerMaps))
                if stackmap == nil || stackmap.n <= 0 {
                        print("runtime: frame ", funcname(f), " untyped locals ", hex(frame.varp-size), "+", hex(size), "\n")
                        throw("missing stackmap")
                }
-               // Locals bitmap information, scan just the pointers in locals.
-               if pcdata < 0 || pcdata >= stackmap.n {
-                       // don't know where we are
-                       print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " locals stack map entries for ", funcname(f), " (targetpc=", targetpc, ")\n")
-                       throw("bad symbol table")
-               }
-               bv = stackmapdata(stackmap, pcdata)
-               size = uintptr(bv.n) * sys.PtrSize
-               if stackDebug >= 3 {
-                       print("      locals ", pcdata, "/", stackmap.n, " ", size/sys.PtrSize, " words ", bv.bytedata, "\n")
+               // If nbit == 0, there's no work to do.
+               if stackmap.nbit > 0 {
+                       // Locals bitmap information, scan just the pointers in locals.
+                       if pcdata < 0 || pcdata >= stackmap.n {
+                               // don't know where we are
+                               print("runtime: pcdata is ", pcdata, " and ", stackmap.n, " locals stack map entries for ", funcname(f), " (targetpc=", targetpc, ")\n")
+                               throw("bad symbol table")
+                       }
+                       bv := stackmapdata(stackmap, pcdata)
+                       size = uintptr(bv.n) * sys.PtrSize
+                       if stackDebug >= 3 {
+                               print("      locals ", pcdata, "/", stackmap.n, " ", size/sys.PtrSize, " words ", bv.bytedata, "\n")
+                       }
+                       adjustpointers(unsafe.Pointer(frame.varp-size), &bv, adjinfo, f)
+               } else if stackDebug >= 3 {
+                       print("      no locals to adjust\n")
                }
-               adjustpointers(unsafe.Pointer(frame.varp-size), &bv, adjinfo, f)
        }
 
        // Adjust saved base pointer if there is one.
@@ -707,7 +711,9 @@ func adjustframe(frame *stkframe, arg unsafe.Pointer) bool {
                if stackDebug >= 3 {
                        print("      args\n")
                }
-               adjustpointers(unsafe.Pointer(frame.argp), &bv, adjinfo, funcInfo{})
+               if bv.n > 0 {
+                       adjustpointers(unsafe.Pointer(frame.argp), &bv, adjinfo, funcInfo{})
+               }
        }
        return true
 }