mirror of
https://github.com/golang/go
synced 2024-11-19 13:54:56 -07:00
cmd/link: use string map for symbols with single version
Reduces link time by ~3% Results with gc on: name old s/op new s/op delta LinkCmdGo 0.82 ± 2% 0.78 ± 2% -3.90% (p=0.000 n=17+17) LinkJuju 7.11 ± 7% 6.87 ± 6% -3.41% (p=0.012 n=20+19) Less noisy results with gc turned off: name old s/op new s/op delta LinkCmdGo 0.66 ± 2% 0.64 ± 2% -3.14% (p=0.000 n=18+20) LinkJuju 5.91 ± 1% 5.72 ± 2% -3.17% (p=0.000 n=20+20) Change-Id: I4cac7933b0b22d0aee18255e1ab54550ad364593 Reviewed-on: https://go-review.googlesource.com/20478 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: David Crawshaw <crawshaw@golang.org> Run-TryBot: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
bb48b864b1
commit
eb57a1dd75
@ -171,7 +171,13 @@ type Link struct {
|
|||||||
Bso *obj.Biobuf
|
Bso *obj.Biobuf
|
||||||
Windows int32
|
Windows int32
|
||||||
Goroot string
|
Goroot string
|
||||||
Hash map[symVer]*LSym
|
|
||||||
|
// Map for fast access of symbols based on name.
|
||||||
|
HashName map[string]*LSym
|
||||||
|
// Fallback map based also on version, for symbols
|
||||||
|
// with more than one version (see func _lookup).
|
||||||
|
HashVersion map[symVer]*LSym
|
||||||
|
|
||||||
Allsym []*LSym
|
Allsym []*LSym
|
||||||
Nsymbol int32
|
Nsymbol int32
|
||||||
Tlsg *LSym
|
Tlsg *LSym
|
||||||
|
@ -58,7 +58,8 @@ var headers = []struct {
|
|||||||
|
|
||||||
func linknew(arch *LinkArch) *Link {
|
func linknew(arch *LinkArch) *Link {
|
||||||
ctxt := &Link{
|
ctxt := &Link{
|
||||||
Hash: make(map[symVer]*LSym, 100000), // preallocate about 2mb for hash
|
HashName: make(map[string]*LSym, 100000), // preallocate about 2mb for hash
|
||||||
|
HashVersion: make(map[symVer]*LSym),
|
||||||
Allsym: make([]*LSym, 0, 100000),
|
Allsym: make([]*LSym, 0, 100000),
|
||||||
Arch: arch,
|
Arch: arch,
|
||||||
Version: obj.HistVersion,
|
Version: obj.HistVersion,
|
||||||
@ -182,17 +183,32 @@ type symVer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func _lookup(ctxt *Link, symb string, v int, creat int) *LSym {
|
func _lookup(ctxt *Link, symb string, v int, creat int) *LSym {
|
||||||
s := ctxt.Hash[symVer{symb, v}]
|
// Most symbols have only a single version, and a string key
|
||||||
|
// is faster to search for. So we store the first symbol in HashName,
|
||||||
|
// keyed only by symbol name. If there are name collisions, the
|
||||||
|
// alternate versions are stored in the spill over map
|
||||||
|
// HashVersion.
|
||||||
|
s, exist := ctxt.HashName[symb]
|
||||||
|
if s != nil {
|
||||||
|
if int(s.Version) == v {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
s = ctxt.HashVersion[symVer{symb, v}]
|
||||||
if s != nil {
|
if s != nil {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if creat == 0 {
|
if creat == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
s = linknewsym(ctxt, symb, v)
|
s = linknewsym(ctxt, symb, v)
|
||||||
s.Extname = s.Name
|
s.Extname = s.Name
|
||||||
ctxt.Hash[symVer{symb, v}] = s
|
if exist {
|
||||||
|
ctxt.HashVersion[symVer{symb, v}] = s
|
||||||
|
} else {
|
||||||
|
ctxt.HashName[symb] = s
|
||||||
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user