From 5758c40ac850f249eccd1676974aac11cb0e8b66 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Tue, 5 Oct 2021 12:11:46 -0700 Subject: [PATCH] runtime: add a single-text-section fast path to findfunc MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Run-TryBot: Josh Bleecher Snyder TryBot-Result: Go Bot Reviewed-by: Cherry Mui --- src/runtime/symtab.go | 44 +++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/src/runtime/symtab.go b/src/runtime/symtab.go index fc02cb4ae5..7724f0d2f0 100644 --- a/src/runtime/symtab.go +++ b/src/runtime/symtab.go @@ -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 -- 2.48.1