1
0
mirror of https://github.com/golang/go synced 2024-11-06 10:26:10 -07:00

[dev.link] cmd/link: don't read symbol name if not needed

Most of the time of goobj2.Sym.Read is spent in reading the
symbol name. Sometimes the name is not needed, so don't read
it.

This brings the linking time pretty much back to the old linker.
On my Mac,

$ time go build cmd/compile     # (new)

real	0m1.016s
user	0m1.164s
sys	0m0.297s

$ time go-tip build cmd/compile # (old)

real	0m0.980s
user	0m1.229s
sys	0m0.309s

Again, this is a bit ugly. Maybe we want to consider moving
symbol names out of Sym, to a separate section of the object
file?

Change-Id: Ia9085c15aa4d614b7eae126e71a79d6806c75055
Reviewed-on: https://go-review.googlesource.com/c/go/+/218480
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>
This commit is contained in:
Cherry Zhang 2020-02-07 11:02:42 -05:00
parent 38437ce118
commit ab1253b59a
2 changed files with 14 additions and 16 deletions

View File

@ -225,6 +225,16 @@ func (s *Sym) Read(r *Reader, off uint32) {
s.Siz = r.uint32At(off + 8) s.Siz = r.uint32At(off + 8)
} }
// Read fields other than the symbol name. The name is not necessary
// in some cases, and most of the time spent in Read is reading the
// name.
func (s *Sym) ReadWithoutName(r *Reader, off uint32) {
s.ABI = r.uint16At(off + 4)
s.Type = r.uint8At(off + 6)
s.Flag = r.uint8At(off + 7)
s.Siz = r.uint32At(off + 8)
}
func (s *Sym) ReadFlag(r *Reader, off uint32) { func (s *Sym) ReadFlag(r *Reader, off uint32) {
s.Flag = r.uint8At(off + 7) s.Flag = r.uint8At(off + 7)
} }

View File

@ -343,7 +343,7 @@ func (l *Loader) AddSym(name string, ver int, r *oReader, li int, dupok bool, ty
} }
oldr, oldli := l.toLocal(oldi) oldr, oldli := l.toLocal(oldi)
oldsym := goobj2.Sym{} oldsym := goobj2.Sym{}
oldsym.Read(oldr.Reader, oldr.SymOff(oldli)) oldsym.ReadWithoutName(oldr.Reader, oldr.SymOff(oldli))
if oldsym.Dupok() { if oldsym.Dupok() {
return oldi, false return oldi, false
} }
@ -615,7 +615,7 @@ func (l *Loader) SymVersion(i Sym) int {
} }
r, li := l.toLocal(i) r, li := l.toLocal(i)
osym := goobj2.Sym{} osym := goobj2.Sym{}
osym.Read(r.Reader, r.SymOff(li)) osym.ReadWithoutName(r.Reader, r.SymOff(li))
return int(abiToVer(osym.ABI, r.version)) return int(abiToVer(osym.ABI, r.version))
} }
@ -630,7 +630,7 @@ func (l *Loader) SymType(i Sym) sym.SymKind {
} }
r, li := l.toLocal(i) r, li := l.toLocal(i)
osym := goobj2.Sym{} osym := goobj2.Sym{}
osym.Read(r.Reader, r.SymOff(li)) osym.ReadWithoutName(r.Reader, r.SymOff(li))
return sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type)] return sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type)]
} }
@ -1766,10 +1766,6 @@ func loadObjSyms(l *Loader, syms *sym.Symbols, r *oReader) int {
continue continue
} }
ver := abiToVer(osym.ABI, r.version) ver := abiToVer(osym.ABI, r.version)
if osym.ABI != goobj2.SymABIstatic && l.symsByName[ver][name] != gi {
continue
}
t := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type)] t := sym.AbiSymKindToSymKind[objabi.SymKind(osym.Type)]
if t == sym.SXREF { if t == sym.SXREF {
log.Fatalf("bad sxref") log.Fatalf("bad sxref")
@ -1987,11 +1983,7 @@ func loadObjFull(l *Loader, r *oReader) {
} }
osym := goobj2.Sym{} osym := goobj2.Sym{}
osym.Read(r.Reader, r.SymOff(i)) osym.ReadWithoutName(r.Reader, r.SymOff(i))
name := strings.Replace(osym.Name, "\"\".", r.pkgprefix, -1)
if name == "" {
continue
}
dupok := osym.Dupok() dupok := osym.Dupok()
if dupok && isdup { if dupok && isdup {
if l.attrReachable.has(gi) { if l.attrReachable.has(gi) {
@ -2014,10 +2006,6 @@ func loadObjFull(l *Loader, r *oReader) {
if s == nil { if s == nil {
continue continue
} }
if s.Name != name { // Sanity check. We can remove it in the final version.
fmt.Println("name mismatch:", lib, i, s.Name, name)
panic("name mismatch")
}
local := osym.Local() local := osym.Local()
makeTypelink := osym.Typelink() makeTypelink := osym.Typelink()