]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: use string map for name lookup
authorCherry Zhang <cherryyz@google.com>
Fri, 18 Oct 2019 16:11:56 +0000 (12:11 -0400)
committerCherry Zhang <cherryyz@google.com>
Thu, 24 Oct 2019 15:22:31 +0000 (15:22 +0000)
As we no longer include static symbols into the name lookup table,
it is basically just two maps, one for ABI0, one for ABIInternal.
Just use two maps instead. It may be slightly faster to use
string-keyed maps than struct-keyed maps (still need performance
data to confirm).

For now, allow external symbols being referenced by name, as
external objects don't use index.

Change-Id: I60cedaa7346fce7535970780bc67f93c82160646
Reviewed-on: https://go-review.googlesource.com/c/go/+/201999
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/link/internal/loader/loader.go

index 3f61726b2450b7c85289449a41923aebe572fccd..e3f7480ac71cd9035d8455c80dd8dcbd404a6807 100644 (file)
@@ -97,8 +97,9 @@ type Loader struct {
        extStart Sym              // from this index on, the symbols are externally defined
        extSyms  []nameVer        // externally defined symbols
 
-       symsByName map[nameVer]Sym // map symbol name to index
-       overwrite  map[Sym]Sym     // overwrite[i]=j if symbol j overwrites symbol i
+       symsByName    [2]map[string]Sym // map symbol name to index, two maps are for ABI0 and ABIInternal
+       extStaticSyms map[nameVer]Sym   // externally defined static symbols, keyed by name
+       overwrite     map[Sym]Sym       // overwrite[i]=j if symbol j overwrites symbol i
 
        itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
 
@@ -111,12 +112,13 @@ type Loader struct {
 
 func NewLoader() *Loader {
        return &Loader{
-               start:      make(map[*oReader]Sym),
-               objs:       []objIdx{{nil, 0}},
-               symsByName: make(map[nameVer]Sym),
-               objByPkg:   make(map[string]*oReader),
-               overwrite:  make(map[Sym]Sym),
-               itablink:   make(map[Sym]struct{}),
+               start:         make(map[*oReader]Sym),
+               objs:          []objIdx{{nil, 0}},
+               symsByName:    [2]map[string]Sym{make(map[string]Sym), make(map[string]Sym)},
+               objByPkg:      make(map[string]*oReader),
+               overwrite:     make(map[Sym]Sym),
+               itablink:      make(map[Sym]struct{}),
+               extStaticSyms: make(map[nameVer]Sym),
        }
 }
 
@@ -153,8 +155,7 @@ func (l *Loader) AddSym(name string, ver int, i Sym, r *oReader, dupok bool, typ
                // referenced by name.
                return true
        }
-       nv := nameVer{name, ver}
-       if oldi, ok := l.symsByName[nv]; ok {
+       if oldi, ok := l.symsByName[ver][name]; ok {
                if dupok {
                        return false
                }
@@ -181,24 +182,34 @@ func (l *Loader) AddSym(name string, ver int, i Sym, r *oReader, dupok bool, typ
                        return false
                }
        }
-       l.symsByName[nv] = i
+       l.symsByName[ver][name] = i
        return true
 }
 
 // Add an external symbol (without index). Return the index of newly added
 // symbol, or 0 if not added.
 func (l *Loader) AddExtSym(name string, ver int) Sym {
-       nv := nameVer{name, ver}
-       if _, ok := l.symsByName[nv]; ok {
-               return 0
+       static := ver >= sym.SymVerStatic
+       if static {
+               if _, ok := l.extStaticSyms[nameVer{name, ver}]; ok {
+                       return 0
+               }
+       } else {
+               if _, ok := l.symsByName[ver][name]; ok {
+                       return 0
+               }
        }
        i := l.max + 1
-       l.symsByName[nv] = i
+       if static {
+               l.extStaticSyms[nameVer{name, ver}] = i
+       } else {
+               l.symsByName[ver][name] = i
+       }
        l.max++
        if l.extStart == 0 {
                l.extStart = i
        }
-       l.extSyms = append(l.extSyms, nv)
+       l.extSyms = append(l.extSyms, nameVer{name, ver})
        l.growSyms(int(i))
        return i
 }
@@ -259,8 +270,7 @@ func (l *Loader) resolve(r *oReader, s goobj2.SymRef) Sym {
                osym.Read(r.Reader, r.SymOff(i))
                name := strings.Replace(osym.Name, "\"\".", r.pkgprefix, -1)
                v := abiToVer(osym.ABI, r.version)
-               nv := nameVer{name, v}
-               return l.symsByName[nv]
+               return l.Lookup(name, v)
        case goobj2.PkgIdxBuiltin:
                panic("PkgIdxBuiltin not used")
        case goobj2.PkgIdxSelf:
@@ -280,8 +290,10 @@ func (l *Loader) resolve(r *oReader, s goobj2.SymRef) Sym {
 // This is more like Syms.ROLookup than Lookup -- it doesn't create
 // new symbol.
 func (l *Loader) Lookup(name string, ver int) Sym {
-       nv := nameVer{name, ver}
-       return l.symsByName[nv]
+       if ver >= sym.SymVerStatic {
+               return l.extStaticSyms[nameVer{name, ver}]
+       }
+       return l.symsByName[ver][name]
 }
 
 // Returns whether i is a dup of another symbol, and i is not
@@ -307,7 +319,7 @@ func (l *Loader) IsDup(i Sym) bool {
        }
        name := strings.Replace(osym.Name, "\"\".", r.pkgprefix, -1)
        ver := abiToVer(osym.ABI, r.version)
-       return l.symsByName[nameVer{name, ver}] != i
+       return l.symsByName[ver][name] != i
 }
 
 // Number of total symbols.
@@ -665,7 +677,7 @@ func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) {
                        continue
                }
                ver := abiToVer(osym.ABI, r.version)
-               if osym.ABI != goobj2.SymABIstatic && l.symsByName[nameVer{name, ver}] != istart+Sym(i) {
+               if osym.ABI != goobj2.SymABIstatic && l.symsByName[ver][name] != istart+Sym(i) {
                        continue
                }
 
@@ -719,7 +731,7 @@ func loadObjFull(l *Loader, r *oReader) {
                ver := abiToVer(osym.ABI, r.version)
                dupok := osym.Dupok()
                if dupok {
-                       if dupsym := l.symsByName[nameVer{name, ver}]; dupsym != istart+Sym(i) {
+                       if dupsym := l.symsByName[ver][name]; dupsym != istart+Sym(i) {
                                if l.Reachable.Has(dupsym) {
                                        // A dupok symbol is resolved to another package. We still need
                                        // to record its presence in the current package, as the trampoline
@@ -960,7 +972,10 @@ func (l *Loader) Dump() {
        }
        fmt.Println("overwrite:", l.overwrite)
        fmt.Println("symsByName")
-       for nv, i := range l.symsByName {
-               fmt.Println(i, nv.name, nv.v)
+       for name, i := range l.symsByName[0] {
+               fmt.Println(i, name, 0)
+       }
+       for name, i := range l.symsByName[1] {
+               fmt.Println(i, name, 1)
        }
 }