1
0
mirror of https://github.com/golang/go synced 2024-11-18 14:04:45 -07:00

[dev.link] cmd/link: minor performance tweaks in dodata

Tweak doDataSect to reduce symbol sorting overhead, and calculate size
ahead of allocating the ctxt.datap slice. Yields a small speedup
(2-3%) linking kubelet.

Change-Id: I82869f5276caa4bee9f6e6f41da2b240e601ce50
Reviewed-on: https://go-review.googlesource.com/c/go/+/231047
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Than McIntosh 2020-04-29 18:46:44 -04:00
parent 2a00c137b1
commit 404f626ee5

View File

@ -1879,6 +1879,11 @@ func (state *dodataState) allocateDataSections2(ctxt *Link) {
Errorf(nil, "read-only data segment too large: %d", state.datsize) Errorf(nil, "read-only data segment too large: %d", state.datsize)
} }
siz := 0
for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
siz += len(state.data2[symn])
}
ctxt.datap2 = make([]loader.Sym, 0, siz)
for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ { for symn := sym.SELFRXSECT; symn < sym.SXREF; symn++ {
ctxt.datap2 = append(ctxt.datap2, state.data2[symn]...) ctxt.datap2 = append(ctxt.datap2, state.data2[symn]...)
} }
@ -1919,11 +1924,19 @@ func (state *dodataState) allocateDwarfSections2(ctxt *Link) {
} }
} }
type symNameSize struct {
name string
sz int64
sym loader.Sym
}
func (state *dodataState) dodataSect2(ctxt *Link, symn sym.SymKind, syms []loader.Sym) (result []loader.Sym, maxAlign int32) { func (state *dodataState) dodataSect2(ctxt *Link, symn sym.SymKind, syms []loader.Sym) (result []loader.Sym, maxAlign int32) {
var head, tail loader.Sym var head, tail loader.Sym
ldr := ctxt.loader ldr := ctxt.loader
for _, s := range syms { sl := make([]symNameSize, len(syms))
for k, s := range syms {
ss := ldr.SymSize(s) ss := ldr.SymSize(s)
sl[k] = symNameSize{name: ldr.SymName(s), sz: ss, sym: s}
ds := int64(len(ldr.Data(s))) ds := int64(len(ldr.Data(s)))
switch { switch {
case ss < ds: case ss < ds:
@ -1956,8 +1969,8 @@ func (state *dodataState) dodataSect2(ctxt *Link, symn sym.SymKind, syms []loade
checkSize := symn != sym.SELFGOT checkSize := symn != sym.SELFGOT
// Perform the sort. // Perform the sort.
sort.Slice(syms, func(i, j int) bool { sort.Slice(sl, func(i, j int) bool {
si, sj := syms[i], syms[j] si, sj := sl[i].sym, sl[j].sym
switch { switch {
case si == head, sj == tail: case si == head, sj == tail:
return true return true
@ -1965,29 +1978,31 @@ func (state *dodataState) dodataSect2(ctxt *Link, symn sym.SymKind, syms []loade
return false return false
} }
if checkSize { if checkSize {
isz := ldr.SymSize(si) isz := sl[i].sz
jsz := ldr.SymSize(sj) jsz := sl[j].sz
if isz != jsz { if isz != jsz {
return isz < jsz return isz < jsz
} }
} }
iname := ldr.SymName(si) iname := sl[i].name
jname := ldr.SymName(sj) jname := sl[j].name
if iname != jname { if iname != jname {
return iname < jname return iname < jname
} }
return si < sj return si < sj
}) })
// Reap alignment. // Reap alignment, construct result
for k := range syms { syms = syms[:0]
s := syms[k] for k := range sl {
s := sl[k].sym
if s != head && s != tail { if s != head && s != tail {
align := state.symalign2(s) align := state.symalign2(s)
if maxAlign < align { if maxAlign < align {
maxAlign = align maxAlign = align
} }
} }
syms = append(syms, s)
} }
return syms, maxAlign return syms, maxAlign