Commit 4f12cc08 authored by Shahar Kohanim's avatar Shahar Kohanim

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 <skohanim@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarDavid Crawshaw <crawshaw@golang.org>
parent b0eeb8b0
...@@ -50,8 +50,9 @@ func Symgrow(ctxt *Link, s *LSym, siz int64) { ...@@ -50,8 +50,9 @@ func Symgrow(ctxt *Link, s *LSym, siz int64) {
if int64(len(s.P)) >= siz { if int64(len(s.P)) >= siz {
return return
} }
for cap(s.P) < int(siz) { if cap(s.P) < int(siz) {
s.P = append(s.P[:len(s.P)], 0) p := make([]byte, 2*(siz+1))
s.P = append(p[:0], s.P...)
} }
s.P = s.P[:siz] s.P = s.P[:siz]
} }
...@@ -90,11 +91,8 @@ func Addbytes(ctxt *Link, s *LSym, bytes []byte) int64 { ...@@ -90,11 +91,8 @@ func Addbytes(ctxt *Link, s *LSym, bytes []byte) int64 {
s.Type = obj.SDATA s.Type = obj.SDATA
} }
s.Attr |= AttrReachable 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.P = append(s.P, bytes...)
s.Size = int64(len(s.P))
return s.Size return s.Size
} }
...@@ -106,7 +104,15 @@ func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 { ...@@ -106,7 +104,15 @@ func adduintxx(ctxt *Link, s *LSym, v uint64, wid int) int64 {
} }
func Adduint8(ctxt *Link, s *LSym, v uint8) 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 { func Adduint16(ctxt *Link, s *LSym, v uint16) int64 {
...@@ -1006,16 +1012,14 @@ func Addstring(s *LSym, str string) int64 { ...@@ -1006,16 +1012,14 @@ func Addstring(s *LSym, str string) int64 {
s.Type = obj.SNOPTRDATA s.Type = obj.SNOPTRDATA
} }
s.Attr |= AttrReachable s.Attr |= AttrReachable
r := int32(s.Size) r := s.Size
n := len(str) + 1
if s.Name == ".shstrtab" { if s.Name == ".shstrtab" {
elfsetstring(str, int(r)) elfsetstring(str, int(r))
} }
Symgrow(Ctxt, s, int64(r)+int64(n)) s.P = append(s.P, str...)
copy(s.P[r:], str) s.P = append(s.P, 0)
s.P[int(r)+len(str)] = 0 s.Size = int64(len(s.P))
s.Size += int64(n) return r
return int64(r)
} }
// addgostring adds str, as a Go string value, to s. symname is the name of the // addgostring adds str, as a Go string value, to s. symname is the name of the
......
...@@ -88,9 +88,7 @@ func uleb128put(s *LSym, v int64) { ...@@ -88,9 +88,7 @@ func uleb128put(s *LSym, v int64) {
func sleb128put(s *LSym, v int64) { func sleb128put(s *LSym, v int64) {
b := appendSleb128(encbuf[:0], v) b := appendSleb128(encbuf[:0], v)
for _, x := range b { Addbytes(Ctxt, s, b)
Adduint8(Ctxt, s, x)
}
} }
/* /*
...@@ -552,8 +550,15 @@ func findchild(die *DWDie, name string) *DWDie { ...@@ -552,8 +550,15 @@ func findchild(die *DWDie, name string) *DWDie {
return nil return nil
} }
// Used to avoid string allocation when looking up dwarf symbols
var prefixBuf = []byte(infoprefix)
func find(name string) *LSym { 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 { func mustFind(name string) *LSym {
......
...@@ -127,8 +127,7 @@ func addpctab(ftab *LSym, off int32, d *Pcdata) int32 { ...@@ -127,8 +127,7 @@ func addpctab(ftab *LSym, off int32, d *Pcdata) int32 {
var start int32 var start int32
if len(d.P) > 0 { if len(d.P) > 0 {
start = int32(len(ftab.P)) start = int32(len(ftab.P))
Symgrow(Ctxt, ftab, int64(start)+int64(len(d.P))) Addbytes(Ctxt, ftab, d.P)
copy(ftab.P[start:], d.P)
} }
return int32(setuint32(Ctxt, ftab, int64(off), uint32(start))) return int32(setuint32(Ctxt, ftab, int64(off), uint32(start)))
} }
......
...@@ -54,15 +54,9 @@ func putelfstr(s string) int { ...@@ -54,15 +54,9 @@ func putelfstr(s string) int {
s = strings.Replace(s, "·", ".", -1) 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) off := len(Elfstrdat)
Elfstrdat = Elfstrdat[:off+n] Elfstrdat = append(Elfstrdat, s...)
copy(Elfstrdat[off:], s) Elfstrdat = append(Elfstrdat, 0)
return off return off
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment