From 2e7e57770c71109cc036478c656309c41ddee143 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Wed, 4 Apr 2018 09:24:13 -0700 Subject: [PATCH] runtime: avoid calling adjustpointers unnecessarily MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 TryBot-Result: Gobot Gobot Reviewed-by: Austin Clements --- src/runtime/stack.go | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/runtime/stack.go b/src/runtime/stack.go index 2dc7001e38..63a286bf59 100644 --- a/src/runtime/stack.go +++ b/src/runtime/stack.go @@ -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") + // 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") } - 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) } // 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 }