From: Shahar Kohanim Date: Thu, 7 Apr 2016 15:00:57 +0000 (+0300) Subject: cmd/link: symbol generation optimizations X-Git-Tag: go1.7beta1~777 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4f12cc08132f3e5d2ba4b756c91d88c2e58a73b1;p=gostls13.git cmd/link: symbol generation optimizations 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 TryBot-Result: Gobot Gobot Reviewed-by: David Crawshaw --- diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 2c8cc9ca4f..ae7c287f59 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -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 diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go index de2d50a1a9..a3a931f94c 100644 --- a/src/cmd/link/internal/ld/dwarf.go +++ b/src/cmd/link/internal/ld/dwarf.go @@ -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 { diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go index a5fea3db76..9a947c7c07 100644 --- a/src/cmd/link/internal/ld/pcln.go +++ b/src/cmd/link/internal/ld/pcln.go @@ -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))) } diff --git a/src/cmd/link/internal/ld/symtab.go b/src/cmd/link/internal/ld/symtab.go index ecd5c741bb..c7c2733507 100644 --- a/src/cmd/link/internal/ld/symtab.go +++ b/src/cmd/link/internal/ld/symtab.go @@ -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 }