1
0
mirror of https://github.com/golang/go synced 2024-11-23 09:50:03 -07:00

debug/gosym: use sort.Search in findFunc

Use sort.Search instead of open-coding the binary search.
This makes the code a lot easier to work on.

As a bonus, it speeds it up.

name            old time/op    new time/op    delta
115/LineToPC-8    57.4µs ± 5%    59.2µs ± 8%   +3.19%  (p=0.003 n=15+13)
115/PCToLine-8     255ns ± 1%     192ns ± 3%  -24.63%  (p=0.000 n=15+15)

Change-Id: I41da18bfb0e745c40d24e5b96e50dfdd0c3b79f5
Reviewed-on: https://go-review.googlesource.com/c/go/+/353879
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2021-10-04 14:08:05 -07:00
parent 7c79e8ef09
commit 199ec42350

View File

@ -11,6 +11,7 @@ package gosym
import (
"bytes"
"encoding/binary"
"sort"
"sync"
)
@ -319,25 +320,13 @@ func (t *LineTable) findFunc(pc uint64) funcData {
if pc < t.uintptr(t.functab) || pc >= t.uintptr(t.functab[len(t.functab)-int(t.ptrsize):]) {
return funcData{}
}
// The function table is a list of 2*nfunctab+1 uintptrs,
// alternating program counters and offsets to func structures.
f := t.functab
nf := t.nfunctab
for nf > 0 {
m := nf / 2
fm := f[2*t.ptrsize*m:]
if t.uintptr(fm) <= pc && pc < t.uintptr(fm[2*t.ptrsize:]) {
data := t.funcdata[t.uintptr(fm[t.ptrsize:]):]
return funcData{t: t, data: data}
} else if pc < t.uintptr(fm) {
nf = m
} else {
f = f[(m+1)*2*t.ptrsize:]
nf -= m + 1
}
}
return funcData{}
idx := sort.Search(int(t.nfunctab), func(i int) bool {
return t.uintptr(t.functab[2*i*int(t.ptrsize):]) > pc
})
idx--
return t.funcData(uint32(idx))
}
// readvarint reads, removes, and returns a varint from *pp.