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>
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]
}
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
}
}
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 {
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
func sleb128put(s *LSym, v int64) {
b := appendSleb128(encbuf[:0], v)
- for _, x := range b {
- Adduint8(Ctxt, s, x)
- }
+ Addbytes(Ctxt, s, b)
}
/*
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 {
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)))
}
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
}