]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: don't sort data symbols by name
authorCherry Mui <cherryyz@google.com>
Fri, 21 Apr 2023 20:28:57 +0000 (16:28 -0400)
committerCherry Mui <cherryyz@google.com>
Mon, 24 Apr 2023 16:50:28 +0000 (16:50 +0000)
For data symbols, we currently sort them by size, then by name if
the size is the same. Sorting by name is not really necessary.
Instead, we sort by symbol index. Like name, the symbol index is
deterministic, and pretty stable if only a small portion of the
input is changed, and also naturally partitioned by packages. This
reduces the CPU time for reading the symbol names and comparing
strings.

Linking cmd/compile (on macOS/amd64),

Dodata    57.2ms ± 6%    54.5ms ± 4%   -4.74%  (p=0.000 n=19+17)

Change-Id: I1c4f2b83dbbb4b984b2c8ab4a7e8543b9f7f22b4
Reviewed-on: https://go-review.googlesource.com/c/go/+/487515
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/link/internal/ld/data.go

index a4c52e942b04d83032491e6e29ea45bce18a0ba6..c3550e59a597b8575661d882c40ab219c94bcb09 100644 (file)
@@ -2159,9 +2159,19 @@ func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader
        var head, tail loader.Sym
        ldr := ctxt.loader
        sl := make([]symNameSize, len(syms))
+
+       // For ppc64, we want to interleave the .got and .toc sections
+       // from input files. Both are type sym.SELFGOT, so in that case
+       // we skip size comparison and do the name comparison instead
+       // (conveniently, .got sorts before .toc).
+       checkSize := symn != sym.SELFGOT
+
        for k, s := range syms {
                ss := ldr.SymSize(s)
-               sl[k] = symNameSize{name: ldr.SymName(s), sz: ss, sym: s}
+               sl[k] = symNameSize{sz: ss, sym: s}
+               if !checkSize {
+                       sl[k].name = ldr.SymName(s)
+               }
                ds := int64(len(ldr.Data(s)))
                switch {
                case ss < ds:
@@ -2187,12 +2197,6 @@ func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader
                }
        }
 
-       // For ppc64, we want to interleave the .got and .toc sections
-       // from input files. Both are type sym.SELFGOT, so in that case
-       // we skip size comparison and fall through to the name
-       // comparison (conveniently, .got sorts before .toc).
-       checkSize := symn != sym.SELFGOT
-
        // Perform the sort.
        if symn != sym.SPCLNTAB {
                sort.Slice(sl, func(i, j int) bool {
@@ -2209,11 +2213,12 @@ func (state *dodataState) dodataSect(ctxt *Link, symn sym.SymKind, syms []loader
                                if isz != jsz {
                                        return isz < jsz
                                }
-                       }
-                       iname := sl[i].name
-                       jname := sl[j].name
-                       if iname != jname {
-                               return iname < jname
+                       } else {
+                               iname := sl[i].name
+                               jname := sl[j].name
+                               if iname != jname {
+                                       return iname < jname
+                               }
                        }
                        return si < sj
                })