diff options
| author | Than McIntosh <thanm@google.com> | 2019-10-24 11:59:49 -0400 |
|---|---|---|
| committer | Than McIntosh <thanm@google.com> | 2019-10-25 17:15:50 +0000 |
| commit | 2e2ef666b4d0bf0e86aaa3afbef7fc17f34232e6 (patch) | |
| tree | 6e82fdbe434d5061038087c4b84ab0d2d41810f5 /src | |
| parent | 376ef734a7d2cec8764ec34ab51902028101b630 (diff) | |
| download | go-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')
| -rw-r--r-- | src/cmd/link/internal/loader/loader.go | 32 |
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()...) |
