]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link/internal/loader: add PkgNone resolver cache
authorThan McIntosh <thanm@google.com>
Thu, 24 Oct 2019 15:59:49 +0000 (11:59 -0400)
committerThan McIntosh <thanm@google.com>
Fri, 25 Oct 2019 17:15:50 +0000 (17:15 +0000)
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>
src/cmd/link/internal/loader/loader.go

index 846e954aa1856b89e1eb8c5780a06bd0d23276f8..52809c63da992f31d18eeda3caf92a8689f49d79 100644 (file)
@@ -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()...)