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: default avatarDavid Crawshaw <crawshaw@golang.org>
parent b0eeb8b0
......@@ -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
......
......@@ -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 {
......
......@@ -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)))
}
......
......@@ -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
}
......
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