aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/link/internal/loader
diff options
context:
space:
mode:
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()...)