]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: symbol generation optimizations
authorShahar Kohanim <skohanim@gmail.com>
Thu, 7 Apr 2016 15:00:57 +0000 (18:00 +0300)
committerShahar Kohanim <skohanim@gmail.com>
Mon, 11 Apr 2016 15:02:28 +0000 (15:02 +0000)
After making dwarf generation backed by LSyms there was a performance regression
of about 10%. These changes make on the fly symbol generation faster and
are meant to help mitigate that.

name       old secs    new secs    delta
LinkCmdGo   0.55 ± 9%   0.53 ± 8%  -4.42%   (p=0.000 n=100+99)

name       old MaxRSS  new MaxRSS  delta
LinkCmdGo   152k ± 6%   149k ± 3%  -1.99%    (p=0.000 n=99+97)

Change-Id: Iacca3ec924ce401aa83126bc0b10fe89bedf0ba6
Reviewed-on: https://go-review.googlesource.com/21733
Run-TryBot: Shahar Kohanim <skohanim@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
src/cmd/link/internal/ld/data.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/pcln.go
src/cmd/link/internal/ld/symtab.go

index 2c8cc9ca4f1f9b8b6830fcac35bb30aa428aea65..ae7c287f59366c80e4f16e29158a9f7c04d7b784 100644 (file)
@@ -50,8 +50,9 @@ func Symgrow(ctxt *Link, s *LSym, siz int64) {
        if int64(len(s.P)) >= siz {
                return
        }
-       for cap(s.P) < int(siz) {
-               s.P = append(s.P[:len(s.P)], 0)
+       if cap(s.P) < int(siz) {
+               p := make([]byte, 2*(siz+1))
+               s.P = append(p[:0], s.P...)
        }
        s.P = s.P[:siz]
 }
@@ -90,11 +91,8 @@ func Addbytes(ctxt *Link, s *LSym, bytes []byte) int64 {
                s.Type = obj.SDATA
        }
        s.Attr |= AttrReachable
-       s.Size += int64(len(bytes))
-       if int64(int(s.Size)) != s.Size {
-               log.Fatalf("Addbytes size %d too long", s.Size)
-       }
        s.P = append(s.P, bytes...)
+       s.Size = int64(len(s.P))
 
        return s.Size
 }
@@ -106,7 +104,15 @@ func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
 }
 
 func Adduint8(ctxt *Link, s *LSym, v uint8) int64 {
-       return adduintxx(ctxt, s, uint64(v), 1)
+       off := s.Size
+       if s.Type == 0 {
+               s.Type = obj.SDATA
+       }
+       s.Attr |= AttrReachable
+       s.Size++
+       s.P = append(s.P, v)
+
+       return off
 }
 
 func Adduint16(ctxt *Link, s *LSym, v uint16) int64 {
@@ -1006,16 +1012,14 @@ func Addstring(s *LSym, str string) int64 {
                s.Type = obj.SNOPTRDATA
        }
        s.Attr |= AttrReachable
-       r := int32(s.Size)
-       n := len(str) + 1
+       r := s.Size
        if s.Name == ".shstrtab" {
                elfsetstring(str, int(r))
        }
-       Symgrow(Ctxt, s, int64(r)+int64(n))
-       copy(s.P[r:], str)
-       s.P[int(r)+len(str)] = 0
-       s.Size += int64(n)
-       return int64(r)
+       s.P = append(s.P, str...)
+       s.P = append(s.P, 0)
+       s.Size = int64(len(s.P))
+       return r
 }
 
 // addgostring adds str, as a Go string value, to s. symname is the name of the
index de2d50a1a9d66bc0dda0567cf37cd633dffb19c5..a3a931f94c6459c97fe52256c2696e45ecba91ec 100644 (file)
@@ -88,9 +88,7 @@ func uleb128put(s *LSym, v int64) {
 
 func sleb128put(s *LSym, v int64) {
        b := appendSleb128(encbuf[:0], v)
-       for _, x := range b {
-               Adduint8(Ctxt, s, x)
-       }
+       Addbytes(Ctxt, s, b)
 }
 
 /*
@@ -552,8 +550,15 @@ func findchild(die *DWDie, name string) *DWDie {
        return nil
 }
 
+// Used to avoid string allocation when looking up dwarf symbols
+var prefixBuf = []byte(infoprefix)
+
 func find(name string) *LSym {
-       return Linkrlookup(Ctxt, infoprefix+name, 0)
+       n := append(prefixBuf, name...)
+       // The string allocation below is optimized away because it is only used in a map lookup.
+       s := Linkrlookup(Ctxt, string(n), 0)
+       prefixBuf = n[:len(infoprefix)]
+       return s
 }
 
 func mustFind(name string) *LSym {
index a5fea3db763299c84fbb0b567e2b877ba11d740e..9a947c7c07535b52805ecfa2188bad58c18b5dd4 100644 (file)
@@ -127,8 +127,7 @@ func addpctab(ftab *LSym, off int32, d *Pcdata) int32 {
        var start int32
        if len(d.P) > 0 {
                start = int32(len(ftab.P))
-               Symgrow(Ctxt, ftab, int64(start)+int64(len(d.P)))
-               copy(ftab.P[start:], d.P)
+               Addbytes(Ctxt, ftab, d.P)
        }
        return int32(setuint32(Ctxt, ftab, int64(off), uint32(start)))
 }
index ecd5c741bba491cadda18289901b2de97cd11791..c7c273350781fa1785d49fd4e69f2b878bf2276b 100644 (file)
@@ -54,15 +54,9 @@ func putelfstr(s string) int {
                s = strings.Replace(s, "·", ".", -1)
        }
 
-       n := len(s) + 1
-       for len(Elfstrdat)+n > cap(Elfstrdat) {
-               Elfstrdat = append(Elfstrdat[:cap(Elfstrdat)], 0)[:len(Elfstrdat)]
-       }
-
        off := len(Elfstrdat)
-       Elfstrdat = Elfstrdat[:off+n]
-       copy(Elfstrdat[off:], s)
-
+       Elfstrdat = append(Elfstrdat, s...)
+       Elfstrdat = append(Elfstrdat, 0)
        return off
 }