aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/loader
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2019-10-24 11:59:49 -0400
committerThan McIntosh <thanm@google.com>2019-10-25 17:15:50 +0000
commit2e2ef666b4d0bf0e86aaa3afbef7fc17f34232e6 (patch)
tree6e82fdbe434d5061038087c4b84ab0d2d41810f5 /src/cmd/link/internal/loader
parent376ef734a7d2cec8764ec34ab51902028101b630 (diff)
downloadgo-2e2ef666b4d0bf0e86aaa3afbef7fc17f34232e6.tar.xz
[dev.link] cmd/link/internal/loader: add PkgNone resolver cache
Add a cache for the loader.Loader.resolve() method to use when looking mapping local PkgNone symbols to global symbol indices. This helps avoid repeated map lookups during deadcode and other early phases of the linker when we haven't fully read in all of object file symbols. Benchstat numbers: name old time/op new time/op delta LinkCompiler 1.97s ±13% 1.67s ± 8% -15.34% (p=0.000 n=20+20) LinkWithoutDebugCompiler 1.48s ±12% 1.21s ±11% -18.14% (p=0.000 n=20+20) name old user-time/op new user-time/op delta LinkCompiler 2.19s ± 9% 2.04s ±17% -6.98% (p=0.002 n=19+20) LinkWithoutDebugCompiler 1.29s ±13% 1.20s ±13% -7.70% (p=0.000 n=20+20) Change-Id: I4b0b05c8208ee44ee9405b24774b84443e486831 Reviewed-on: https://go-review.googlesource.com/c/go/+/203197 Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/link/internal/loader')
-rw-r--r--src/cmd/link/internal/loader/loader.go32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/cmd/link/internal/loader/loader.go b/src/cmd/link/internal/loader/loader.go
index 846e954aa1..52809c63da 100644
--- a/src/cmd/link/internal/loader/loader.go
+++ b/src/cmd/link/internal/loader/loader.go
@@ -59,6 +59,7 @@ type oReader struct {
version int // version of static symbol
flags uint32 // read from object file
pkgprefix string
+ rcache []Sym // cache mapping local PkgNone symbol to resolved Sym
}
type objIdx struct {
@@ -257,6 +258,26 @@ func (l *Loader) toLocal(i Sym) (*oReader, int) {
return l.objs[k-1].r, int(i - l.objs[k-1].i)
}
+// rcacheGet checks for a valid entry for 's' in the readers cache,
+// where 's' is a local PkgIdxNone ref or def, or zero if
+// the cache is empty or doesn't contain a value for 's'.
+func (or *oReader) rcacheGet(symIdx uint32) Sym {
+ if len(or.rcache) > 0 {
+ return or.rcache[symIdx]
+ }
+ return 0
+}
+
+// rcacheSet installs a new entry in the oReader's PkgNone
+// resolver cache for the specified PkgIdxNone ref or def,
+// allocating a new cache if needed.
+func (or *oReader) rcacheSet(symIdx uint32, gsym Sym) {
+ if len(or.rcache) == 0 {
+ or.rcache = make([]Sym, or.NNonpkgdef()+or.NNonpkgref())
+ }
+ or.rcache[symIdx] = gsym
+}
+
// Resolve a local symbol reference. Return global index.
func (l *Loader) resolve(r *oReader, s goobj2.SymRef) Sym {
var rr *oReader
@@ -267,13 +288,20 @@ func (l *Loader) resolve(r *oReader, s goobj2.SymRef) Sym {
}
return 0
case goobj2.PkgIdxNone:
+ // Check for cached version first
+ if cached := r.rcacheGet(s.SymIdx); cached != 0 {
+ return cached
+ }
// Resolve by name
i := int(s.SymIdx) + r.NSym()
osym := goobj2.Sym{}
osym.Read(r.Reader, r.SymOff(i))
name := strings.Replace(osym.Name, "\"\".", r.pkgprefix, -1)
v := abiToVer(osym.ABI, r.version)
- return l.Lookup(name, v)
+ gsym := l.Lookup(name, v)
+ // Add to cache, then return.
+ r.rcacheSet(s.SymIdx, gsym)
+ return gsym
case goobj2.PkgIdxBuiltin:
return l.builtinSyms[s.SymIdx]
case goobj2.PkgIdxSelf:
@@ -549,7 +577,7 @@ func (l *Loader) Preload(arch *sys.Arch, syms *sym.Symbols, f *bio.Reader, lib *
}
localSymVersion := syms.IncVersion()
pkgprefix := objabi.PathToPrefix(lib.Pkg) + "."
- or := &oReader{r, unit, localSymVersion, r.Flags(), pkgprefix}
+ or := &oReader{r, unit, localSymVersion, r.Flags(), pkgprefix, nil}
// Autolib
lib.ImportStrings = append(lib.ImportStrings, r.Autolib()...)