]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.link] cmd/link: minor performance tweaks in dodata
authorThan McIntosh <thanm@google.com>
Wed, 29 Apr 2020 22:46:44 +0000 (18:46 -0400)
committerThan McIntosh <thanm@google.com>
Thu, 30 Apr 2020 16:16:30 +0000 (16:16 +0000)
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>
src/cmd/link/internal/ld/data.go

index 84b5b494b2659e4fc6bd41ea99e447a0487a864d..5520d22cf207bfed69461d2d8aa852fd093e301f 100644 (file)
@@ -1879,6 +1879,11 @@ func (state *dodataState) allocateDataSections2(ctxt *Link) {
                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++ {
                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) {
        var head, tail loader.Sym
        ldr := ctxt.loader
-       for _, s := range syms {
+       sl := make([]symNameSize, len(syms))
+       for k, s := range syms {
                ss := ldr.SymSize(s)
+               sl[k] = symNameSize{name: ldr.SymName(s), sz: ss, sym: s}
                ds := int64(len(ldr.Data(s)))
                switch {
                case ss < ds:
@@ -1956,8 +1969,8 @@ func (state *dodataState) dodataSect2(ctxt *Link, symn sym.SymKind, syms []loade
        checkSize := symn != sym.SELFGOT
 
        // Perform the sort.
-       sort.Slice(syms, func(i, j int) bool {
-               si, sj := syms[i], syms[j]
+       sort.Slice(sl, func(i, j int) bool {
+               si, sj := sl[i].sym, sl[j].sym
                switch {
                case si == head, sj == tail:
                        return true
@@ -1965,29 +1978,31 @@ func (state *dodataState) dodataSect2(ctxt *Link, symn sym.SymKind, syms []loade
                        return false
                }
                if checkSize {
-                       isz := ldr.SymSize(si)
-                       jsz := ldr.SymSize(sj)
+                       isz := sl[i].sz
+                       jsz := sl[j].sz
                        if isz != jsz {
                                return isz < jsz
                        }
                }
-               iname := ldr.SymName(si)
-               jname := ldr.SymName(sj)
+               iname := sl[i].name
+               jname := sl[j].name
                if iname != jname {
                        return iname < jname
                }
                return si < sj
        })
 
-       // Reap alignment.
-       for k := range syms {
-               s := syms[k]
+       // Reap alignment, construct result
+       syms = syms[:0]
+       for k := range sl {
+               s := sl[k].sym
                if s != head && s != tail {
                        align := state.symalign2(s)
                        if maxAlign < align {
                                maxAlign = align
                        }
                }
+               syms = append(syms, s)
        }
 
        return syms, maxAlign