]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: refactor symbol lookup
authorShahar Kohanim <skohanim@gmail.com>
Sun, 27 Mar 2016 07:06:12 +0000 (10:06 +0300)
committerDavid Crawshaw <crawshaw@golang.org>
Mon, 28 Mar 2016 16:09:54 +0000 (16:09 +0000)
Calling the read only Linkrlookup will now not cause the name
string to escape. So a lookup can be performed on a []byte
casted to a string without allocating. This will help a followup
cl and it is also much simpler and cleaner.
Performance not impacted by this.

name       old s/op   new s/op   delta
LinkCmdGo  0.51 ± 6%  0.51 ± 5%   ~     (p=0.192 n=98+98)

Change-Id: I7846ba3160eb845a3a29cbf0be703c47369ece16
Reviewed-on: https://go-review.googlesource.com/21187
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
Run-TryBot: David Crawshaw <crawshaw@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/link/internal/ld/ldelf.go
src/cmd/link/internal/ld/ldmacho.go
src/cmd/link/internal/ld/ldpe.go
src/cmd/link/internal/ld/link.go
src/cmd/link/internal/ld/objfile.go
src/cmd/link/internal/ld/sym.go

index b04b32bf272dcdc37f22a7ee0c8b81d7b65579e6..a68c473a388740f3076c2c0cdf5d29595a7d472f 100644 (file)
@@ -450,7 +450,7 @@ func ldelf(f *obj.Biobuf, pkg string, length int64, pn string) {
                fmt.Fprintf(&Bso, "%5.2f ldelf %s\n", obj.Cputime(), pn)
        }
 
-       Ctxt.Version++
+       Ctxt.IncVersion()
        base := int32(obj.Boffset(f))
 
        var add uint64
index 9c9eb2ca29499ba9f38862aca43487beeea66d4b..c4c13f13b9ea36451c22c3fdd506c20073831479 100644 (file)
@@ -429,7 +429,7 @@ func ldmacho(f *obj.Biobuf, pkg string, length int64, pn string) {
        var rp *Reloc
        var name string
 
-       Ctxt.Version++
+       Ctxt.IncVersion()
        base := obj.Boffset(f)
        if obj.Bread(f, hdr[:]) != len(hdr) {
                goto bad
index 0ead95e4521c5dc520517c4b5cb92916e31b2e41..5c3e99c44f894ecd8f5e9db34bc13b0ab302d8f3 100644 (file)
@@ -133,7 +133,7 @@ func ldpe(f *obj.Biobuf, pkg string, length int64, pn string) {
        }
 
        var sect *PeSect
-       Ctxt.Version++
+       Ctxt.IncVersion()
        base := int32(obj.Boffset(f))
 
        peobj := new(PeObj)
index 54ebab9ebbf949c4ccd80a9b565a1b44736654b4..16605352ec042037a78ce219d94dee8a8bf840c7 100644 (file)
@@ -171,11 +171,8 @@ type Link struct {
        Windows   int32
        Goroot    string
 
-       // 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
+       // Symbol lookup based on name and indexed by version.
+       Hash []map[string]*LSym
 
        Allsym     []*LSym
        Tlsg       *LSym
@@ -212,6 +209,11 @@ func (ctxt *Link) FixedFrameSize() int64 {
        }
 }
 
+func (l *Link) IncVersion() {
+       l.Version++
+       l.Hash = append(l.Hash, make(map[string]*LSym))
+}
+
 type LinkArch struct {
        ByteOrder binary.ByteOrder
        Name      string
index 34ef61be828e6599abd307008ce90641e254b695..2e8f01099c293f0057b307f58a1218e4c33eda2b 100644 (file)
@@ -116,7 +116,7 @@ const (
 
 func ldobjfile(ctxt *Link, f *obj.Biobuf, pkg string, length int64, pn string) {
        start := obj.Boffset(f)
-       ctxt.Version++
+       ctxt.IncVersion()
        var buf [8]uint8
        obj.Bread(f, buf[:])
        if string(buf[:]) != startmagic {
index 3c4dc5587f91ddd7dea7aa3f07885a6bfe46a996..486b88152001a25eb4cea77a93af058785a874a8 100644 (file)
@@ -58,12 +58,14 @@ var headers = []struct {
 
 func linknew(arch *LinkArch) *Link {
        ctxt := &Link{
-               HashName:    make(map[string]*LSym, 100000), // preallocate about 2mb for hash
-               HashVersion: make(map[symVer]*LSym),
-               Allsym:      make([]*LSym, 0, 100000),
-               Arch:        arch,
-               Version:     obj.HistVersion,
-               Goroot:      obj.Getgoroot(),
+               Hash: []map[string]*LSym{
+                       // preallocate about 2mb for hash of
+                       // non static symbols
+                       make(map[string]*LSym, 100000),
+               },
+               Allsym: make([]*LSym, 0, 100000),
+               Arch:   arch,
+               Goroot: obj.Getgoroot(),
        }
 
        p := obj.Getgoarch()
@@ -158,7 +160,7 @@ func linknew(arch *LinkArch) *Link {
        return ctxt
 }
 
-func linknewsym(ctxt *Link, symb string, v int) *LSym {
+func linknewsym(ctxt *Link, name string, v int) *LSym {
        batch := ctxt.LSymBatch
        if len(batch) == 0 {
                batch = make([]LSym, 1000)
@@ -169,55 +171,28 @@ func linknewsym(ctxt *Link, symb string, v int) *LSym {
        s.Dynid = -1
        s.Plt = -1
        s.Got = -1
-       s.Name = symb
+       s.Name = name
        s.Version = int16(v)
        ctxt.Allsym = append(ctxt.Allsym, s)
 
        return s
 }
 
-type symVer struct {
-       sym string
-       ver int
-}
-
-func _lookup(ctxt *Link, symb string, v int, creat int) *LSym {
-       // 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]
+func Linklookup(ctxt *Link, name string, v int) *LSym {
+       m := ctxt.Hash[v]
+       s := m[name]
        if s != nil {
-               if int(s.Version) == v {
-                       return s
-               }
-               s = ctxt.HashVersion[symVer{symb, v}]
-               if s != nil {
-                       return s
-               }
-       }
-       if creat == 0 {
-               return nil
+               return s
        }
-
-       s = linknewsym(ctxt, symb, v)
+       s = linknewsym(ctxt, name, v)
        s.Extname = s.Name
-       if exist {
-               ctxt.HashVersion[symVer{symb, v}] = s
-       } else {
-               ctxt.HashName[symb] = s
-       }
+       m[name] = s
        return s
 }
 
-func Linklookup(ctxt *Link, name string, v int) *LSym {
-       return _lookup(ctxt, name, v, 1)
-}
-
 // read-only lookup
 func Linkrlookup(ctxt *Link, name string, v int) *LSym {
-       return _lookup(ctxt, name, v, 0)
+       return ctxt.Hash[v][name]
 }
 
 func Headstr(v int) string {