]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: add a single-text-section fast path to findfunc
authorJosh Bleecher Snyder <josharian@gmail.com>
Tue, 5 Oct 2021 19:11:46 +0000 (12:11 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Tue, 5 Oct 2021 23:34:32 +0000 (23:34 +0000)
name                   old time/op  new time/op  delta
StackCopyWithStkobj-8  11.5ms ± 4%  10.7ms ± 7%  -7.10%  (p=0.000 n=10+10)

Change-Id: Ib806d732ec11f2a6cfde229fd88aff0fe68d9e7d
Reviewed-on: https://go-review.googlesource.com/c/go/+/354129
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/runtime/symtab.go

index fc02cb4ae52fff83ae1eb020b3f0de0c8886a71e..7724f0d2f0b3d5db8bf5948355f1de02fe9eed63 100644 (file)
@@ -808,28 +808,36 @@ func findfunc(pc uintptr) funcInfo {
        ffb := (*findfuncbucket)(add(unsafe.Pointer(datap.findfunctab), b*unsafe.Sizeof(findfuncbucket{})))
        idx := ffb.idx + uint32(ffb.subbuckets[i])
 
-       // If the idx is beyond the end of the ftab, set it to the end of the table and search backward.
-       // This situation can occur if multiple text sections are generated to handle large text sections
-       // and the linker has inserted jump tables between them.
-
-       if idx >= uint32(len(datap.ftab)) {
-               idx = uint32(len(datap.ftab) - 1)
-       }
-       if pc < datap.textAddr(uintptr(datap.ftab[idx].entryoff)) {
-               // With multiple text sections, the idx might reference a function address that
-               // is higher than the pcOff being searched, so search backward until the matching address is found.
-               for datap.textAddr(uintptr(datap.ftab[idx].entryoff)) > pc && idx > 0 {
-                       idx--
-               }
-               if idx == 0 {
-                       throw("findfunc: bad findfunctab entry idx")
+       // Find the ftab entry.
+       if len(datap.textsectmap) == 1 {
+               // fast path for the common case
+               pcOff := uint32(pc - datap.text)
+               for datap.ftab[idx+1].entryoff <= pcOff {
+                       idx++
                }
        } else {
-               // linear search to find func with pcOff >= entry.
-               for datap.textAddr(uintptr(datap.ftab[idx+1].entryoff)) <= pc {
-                       idx++
+               // Multiple text sections.
+               // If the idx is beyond the end of the ftab, set it to the end of the table and search backward.
+               if idx >= uint32(len(datap.ftab)) {
+                       idx = uint32(len(datap.ftab) - 1)
+               }
+               if pc < datap.textAddr(uintptr(datap.ftab[idx].entryoff)) {
+                       // The idx might reference a function address that
+                       // is higher than the pcOff being searched, so search backward until the matching address is found.
+                       for datap.textAddr(uintptr(datap.ftab[idx].entryoff)) > pc && idx > 0 {
+                               idx--
+                       }
+                       if idx == 0 {
+                               throw("findfunc: bad findfunctab entry idx")
+                       }
+               } else {
+                       // linear search to find func with pc >= entry.
+                       for datap.textAddr(uintptr(datap.ftab[idx+1].entryoff)) <= pc {
+                               idx++
+                       }
                }
        }
+
        funcoff := datap.ftab[idx].funcoff
        if funcoff == ^uint32(0) {
                // With multiple text sections, there may be functions inserted by the external