]> Cypherpunks repositories - gostls13.git/commitdiff
cmd: replace many sort.Interface with slices.Sort and SortFunc
authorZxilly <zxilly@outlook.com>
Tue, 3 Sep 2024 17:46:10 +0000 (17:46 +0000)
committerKeith Randall <khr@golang.org>
Tue, 3 Sep 2024 20:55:18 +0000 (20:55 +0000)
with slices there's no need to implement sort.Interface

Change-Id: I59167e78881cb1df89a71e33d738d6aeca7adb71
GitHub-Last-Rev: 507ba84453f7305b6b2bf6317292111c00c93ffe
GitHub-Pull-Request: golang/go#68724
Reviewed-on: https://go-review.googlesource.com/c/go/+/602895
Reviewed-by: Ian Lance Taylor <iant@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
38 files changed:
src/cmd/compile/internal/dwarfgen/dwarf.go
src/cmd/compile/internal/importer/gcimporter.go
src/cmd/compile/internal/importer/iimport.go
src/cmd/compile/internal/reflectdata/reflect.go
src/cmd/compile/internal/ssa/_gen/main.go
src/cmd/compile/internal/ssa/cse.go
src/cmd/compile/internal/ssa/debug.go
src/cmd/compile/internal/ssa/html.go
src/cmd/compile/internal/ssa/schedule.go
src/cmd/compile/internal/ssagen/ssa.go
src/cmd/compile/internal/typecheck/subr.go
src/cmd/compile/internal/types/size.go
src/cmd/compile/internal/types/sort.go
src/cmd/compile/internal/types2/resolver.go
src/cmd/compile/internal/types2/typeset.go
src/cmd/cover/cover.go
src/cmd/fix/fix.go
src/cmd/fix/main.go
src/cmd/internal/dwarf/dwarf.go
src/cmd/internal/obj/arm/asm5.go
src/cmd/internal/obj/arm64/asm7.go
src/cmd/internal/obj/dwarf.go
src/cmd/internal/obj/loong64/asm.go
src/cmd/internal/obj/mips/asm0.go
src/cmd/internal/obj/objfile.go
src/cmd/internal/obj/s390x/asmz.go
src/cmd/internal/objfile/macho.go
src/cmd/internal/objfile/objfile.go
src/cmd/internal/objfile/pe.go
src/cmd/internal/objfile/plan9obj.go
src/cmd/link/internal/ld/dwarf.go
src/cmd/link/internal/ld/elf.go
src/cmd/link/internal/ld/pe.go
src/cmd/link/internal/ld/symtab.go
src/cmd/link/internal/ld/typelink.go
src/cmd/link/internal/loader/symbolbuilder.go
src/go/types/resolver.go
src/go/types/typeset.go

index 36cc253e827de5856f72dce4fcacd6b0061e0ca1..0451534a4c39d013eb442e6825deddb9b0d36ce6 100644 (file)
@@ -9,7 +9,9 @@ import (
        "flag"
        "fmt"
        "internal/buildcfg"
+       "slices"
        "sort"
+       "strings"
 
        "cmd/compile/internal/base"
        "cmd/compile/internal/ir"
@@ -130,7 +132,9 @@ func Info(fnsym *obj.LSym, infosym *obj.LSym, curfn obj.Func) (scopes []dwarf.Sc
        for t := range fnsym.Func().Autot {
                typesyms = append(typesyms, t)
        }
-       sort.Sort(obj.BySymName(typesyms))
+       slices.SortFunc(typesyms, func(a, b *obj.LSym) int {
+               return strings.Compare(a.Name, b.Name)
+       })
        for _, sym := range typesyms {
                r := obj.Addrel(infosym)
                r.Sym = sym
index 1f7b49c8c3d53547b300083a9403a6137b9a5cd8..c35d7604f2a4c9bace9b98ca85a81b652ab05868 100644 (file)
@@ -245,9 +245,3 @@ func Import(packages map[string]*types2.Package, path, srcDir string, lookup fun
 
        return
 }
-
-type byPath []*types2.Package
-
-func (a byPath) Len() int           { return len(a) }
-func (a byPath) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
-func (a byPath) Less(i, j int) bool { return a[i].Path() < a[j].Path() }
index 97feb7f3fdd5baa3f60454fdf4ffa2a0c29d3c20..652f62766e280d26589864c0f6b91e6f0c435096 100644 (file)
@@ -17,6 +17,7 @@ import (
        "go/token"
        "io"
        "math/big"
+       "slices"
        "sort"
        "strings"
 )
@@ -188,7 +189,9 @@ func ImportData(imports map[string]*types2.Package, data, path string) (pkg *typ
        }
        // record all referenced packages as imports
        list := append(([]*types2.Package)(nil), pkgList[1:]...)
-       sort.Sort(byPath(list))
+       slices.SortFunc(list, func(a, b *types2.Package) int {
+               return strings.Compare(a.Path(), b.Path())
+       })
        localpkg.SetImports(list)
 
        // package was imported completely and without errors
index 06a3314c479b6fa45300f67e7514c0e46e3a1f4f..c2dc0174d52c99bb38efba51e6d35fd6e63d0537 100644 (file)
@@ -10,6 +10,7 @@ import (
        "internal/abi"
        "internal/buildcfg"
        "os"
+       "slices"
        "sort"
        "strings"
        "sync"
@@ -991,7 +992,7 @@ func WriteRuntimeTypes() {
        for len(signatslice) > 0 {
                signats := signatslice
                // Sort for reproducible builds.
-               sort.Sort(typesByString(signats))
+               slices.SortFunc(signats, typesStrCmp)
                for _, ts := range signats {
                        t := ts.t
                        writeType(t)
@@ -1009,7 +1010,7 @@ func WriteGCSymbols() {
        for t := range gcsymset {
                gcsyms = append(gcsyms, typeAndStr{t: t, short: types.TypeSymName(t), regular: t.String()})
        }
-       sort.Sort(typesByString(gcsyms))
+       slices.SortFunc(gcsyms, typesStrCmp)
        for _, ts := range gcsyms {
                dgcsym(ts.t, true)
        }
@@ -1187,20 +1188,17 @@ type typeAndStr struct {
        regular string
 }
 
-type typesByString []typeAndStr
-
-func (a typesByString) Len() int { return len(a) }
-func (a typesByString) Less(i, j int) bool {
+func typesStrCmp(a, b typeAndStr) int {
        // put named types before unnamed types
-       if a[i].t.Sym() != nil && a[j].t.Sym() == nil {
-               return true
+       if a.t.Sym() != nil && b.t.Sym() == nil {
+               return -1
        }
-       if a[i].t.Sym() == nil && a[j].t.Sym() != nil {
-               return false
+       if a.t.Sym() == nil && b.t.Sym() != nil {
+               return +1
        }
 
-       if a[i].short != a[j].short {
-               return a[i].short < a[j].short
+       if r := strings.Compare(a.short, b.short); r != 0 {
+               return r
        }
        // When the only difference between the types is whether
        // they refer to byte or uint8, such as **byte vs **uint8,
@@ -1211,19 +1209,21 @@ func (a typesByString) Less(i, j int) bool {
        // avoid naming collisions, and there shouldn't be a reason to care
        // about "byte" vs "uint8": they share the same runtime type
        // descriptor anyway.
-       if a[i].regular != a[j].regular {
-               return a[i].regular < a[j].regular
+       if r := strings.Compare(a.regular, b.regular); r != 0 {
+               return r
        }
        // Identical anonymous interfaces defined in different locations
        // will be equal for the above checks, but different in DWARF output.
        // Sort by source position to ensure deterministic order.
        // See issues 27013 and 30202.
-       if a[i].t.Kind() == types.TINTER && len(a[i].t.AllMethods()) > 0 {
-               return a[i].t.AllMethods()[0].Pos.Before(a[j].t.AllMethods()[0].Pos)
+       if a.t.Kind() == types.TINTER && len(a.t.AllMethods()) > 0 {
+               if a.t.AllMethods()[0].Pos.Before(b.t.AllMethods()[0].Pos) {
+                       return -1
+               }
+               return +1
        }
-       return false
+       return 0
 }
-func (a typesByString) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
 
 // GCSym returns a data symbol containing GC information for type t, along
 // with a boolean reporting whether the UseGCProg bit should be set in the
index 086418c7cb2e52f346cbe9a4eedb4715276d9f8e..c2d4ca26655381ba2ec3a6ef99b64accd8db21e9 100644 (file)
@@ -19,6 +19,7 @@ import (
        "runtime"
        "runtime/pprof"
        "runtime/trace"
+       "slices"
        "sort"
        "strings"
        "sync"
@@ -142,7 +143,9 @@ func main() {
                defer trace.Stop()
        }
 
-       sort.Sort(ArchsByName(archs))
+       slices.SortFunc(archs, func(a, b arch) int {
+               return strings.Compare(a.name, b.name)
+       })
 
        // The generate tasks are run concurrently, since they are CPU-intensive
        // that can easily make use of many cores on a machine.
@@ -563,9 +566,3 @@ type byKey []intPair
 func (a byKey) Len() int           { return len(a) }
 func (a byKey) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
 func (a byKey) Less(i, j int) bool { return a[i].key < a[j].key }
-
-type ArchsByName []arch
-
-func (x ArchsByName) Len() int           { return len(x) }
-func (x ArchsByName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x ArchsByName) Less(i, j int) bool { return x[i].name < x[j].name }
index d6497977c74cfc40e9cbe783704587d5cfd76799..5285ef52036906e84f4fa594559573f2c4208282 100644 (file)
@@ -7,8 +7,9 @@ package ssa
 import (
        "cmd/compile/internal/types"
        "cmd/internal/src"
+       "cmp"
        "fmt"
-       "sort"
+       "slices"
 )
 
 // cse does common-subexpression elimination on the Function.
@@ -86,7 +87,6 @@ func cse(f *Func) {
        // non-equivalent arguments.  Repeat until we can't find any
        // more splits.
        var splitPoints []int
-       byArgClass := new(partitionByArgClass) // reusable partitionByArgClass to reduce allocations
        for {
                changed := false
 
@@ -105,9 +105,18 @@ func cse(f *Func) {
                        }
 
                        // Sort by eq class of arguments.
-                       byArgClass.a = e
-                       byArgClass.eqClass = valueEqClass
-                       sort.Sort(byArgClass)
+                       slices.SortFunc(e, func(v, w *Value) int {
+                               for i, a := range v.Args {
+                                       b := w.Args[i]
+                                       if valueEqClass[a.ID] < valueEqClass[b.ID] {
+                                               return -1
+                                       }
+                                       if valueEqClass[a.ID] > valueEqClass[b.ID] {
+                                               return +1
+                                       }
+                               }
+                               return 0
+                       })
 
                        // Find split points.
                        splitPoints = append(splitPoints[:0], 0)
@@ -164,11 +173,11 @@ func cse(f *Func) {
        // if v and w are in the same equivalence class and v dominates w.
        rewrite := f.Cache.allocValueSlice(f.NumValues())
        defer f.Cache.freeValueSlice(rewrite)
-       byDom := new(partitionByDom) // reusable partitionByDom to reduce allocs
        for _, e := range partition {
-               byDom.a = e
-               byDom.sdom = sdom
-               sort.Sort(byDom)
+               slices.SortFunc(e, func(v, w *Value) int {
+                       return cmp.Compare(sdom.domorder(v.Block), sdom.domorder(w.Block))
+               })
+
                for i := 0; i < len(e)-1; i++ {
                        // e is sorted by domorder, so a maximal dominant element is first in the slice
                        v := e[i]
@@ -253,7 +262,17 @@ type eqclass []*Value
 // backed by the same storage as the input slice.
 // Equivalence classes of size 1 are ignored.
 func partitionValues(a []*Value, auxIDs auxmap) []eqclass {
-       sort.Sort(sortvalues{a, auxIDs})
+       slices.SortFunc(a, func(v, w *Value) int {
+               switch cmpVal(v, w, auxIDs) {
+               case types.CMPlt:
+                       return -1
+               case types.CMPgt:
+                       return +1
+               default:
+                       // Sort by value ID last to keep the sort result deterministic.
+                       return cmp.Compare(v.ID, w.ID)
+               }
+       })
 
        var partition []eqclass
        for len(a) > 0 {
@@ -322,57 +341,3 @@ func cmpVal(v, w *Value, auxIDs auxmap) types.Cmp {
 
        return types.CMPeq
 }
-
-// Sort values to make the initial partition.
-type sortvalues struct {
-       a      []*Value // array of values
-       auxIDs auxmap   // aux -> aux ID map
-}
-
-func (sv sortvalues) Len() int      { return len(sv.a) }
-func (sv sortvalues) Swap(i, j int) { sv.a[i], sv.a[j] = sv.a[j], sv.a[i] }
-func (sv sortvalues) Less(i, j int) bool {
-       v := sv.a[i]
-       w := sv.a[j]
-       if cmp := cmpVal(v, w, sv.auxIDs); cmp != types.CMPeq {
-               return cmp == types.CMPlt
-       }
-
-       // Sort by value ID last to keep the sort result deterministic.
-       return v.ID < w.ID
-}
-
-type partitionByDom struct {
-       a    []*Value // array of values
-       sdom SparseTree
-}
-
-func (sv partitionByDom) Len() int      { return len(sv.a) }
-func (sv partitionByDom) Swap(i, j int) { sv.a[i], sv.a[j] = sv.a[j], sv.a[i] }
-func (sv partitionByDom) Less(i, j int) bool {
-       v := sv.a[i]
-       w := sv.a[j]
-       return sv.sdom.domorder(v.Block) < sv.sdom.domorder(w.Block)
-}
-
-type partitionByArgClass struct {
-       a       []*Value // array of values
-       eqClass []ID     // equivalence class IDs of values
-}
-
-func (sv partitionByArgClass) Len() int      { return len(sv.a) }
-func (sv partitionByArgClass) Swap(i, j int) { sv.a[i], sv.a[j] = sv.a[j], sv.a[i] }
-func (sv partitionByArgClass) Less(i, j int) bool {
-       v := sv.a[i]
-       w := sv.a[j]
-       for i, a := range v.Args {
-               b := w.Args[i]
-               if sv.eqClass[a.ID] < sv.eqClass[b.ID] {
-                       return true
-               }
-               if sv.eqClass[a.ID] > sv.eqClass[b.ID] {
-                       return false
-               }
-       }
-       return false
-}
index 04025f78829a50cd01745a41e647da8968844013..ccd403386e05ece9d62f0c681393a46e629f4dc8 100644 (file)
@@ -12,11 +12,12 @@ import (
        "cmd/internal/dwarf"
        "cmd/internal/obj"
        "cmd/internal/src"
+       "cmp"
        "encoding/hex"
        "fmt"
        "internal/buildcfg"
        "math/bits"
-       "sort"
+       "slices"
        "strings"
 )
 
@@ -231,10 +232,9 @@ type debugState struct {
        // The pending location list entry for each user variable, indexed by VarID.
        pendingEntries []pendingEntry
 
-       varParts         map[*ir.Name][]SlotID
-       blockDebug       []BlockDebug
-       pendingSlotLocs  []VarLoc
-       partsByVarOffset sort.Interface
+       varParts        map[*ir.Name][]SlotID
+       blockDebug      []BlockDebug
+       pendingSlotLocs []VarLoc
 }
 
 func (state *debugState) initializeCache(f *Func, numVars, numSlots int) {
@@ -649,17 +649,16 @@ func BuildFuncDebug(ctxt *obj.Link, f *Func, loggingLevel int, stackOffset func(
                state.slotVars = state.slotVars[:len(state.slots)]
        }
 
-       if state.partsByVarOffset == nil {
-               state.partsByVarOffset = &partsByVarOffset{}
-       }
        for varID, n := range state.vars {
                parts := state.varParts[n]
+               slices.SortFunc(parts, func(a, b SlotID) int {
+                       return cmp.Compare(varOffset(state.slots[a]), varOffset(state.slots[b]))
+               })
+
                state.varSlots[varID] = parts
                for _, slotID := range parts {
                        state.slotVars[slotID] = VarID(varID)
                }
-               *state.partsByVarOffset.(*partsByVarOffset) = partsByVarOffset{parts, state.slots}
-               sort.Sort(state.partsByVarOffset)
        }
 
        state.initializeCache(f, len(state.varParts), len(state.slots))
@@ -1180,17 +1179,6 @@ func varOffset(slot LocalSlot) int64 {
        return offset
 }
 
-type partsByVarOffset struct {
-       slotIDs []SlotID
-       slots   []LocalSlot
-}
-
-func (a partsByVarOffset) Len() int { return len(a.slotIDs) }
-func (a partsByVarOffset) Less(i, j int) bool {
-       return varOffset(a.slots[a.slotIDs[i]]) < varOffset(a.slots[a.slotIDs[j]])
-}
-func (a partsByVarOffset) Swap(i, j int) { a.slotIDs[i], a.slotIDs[j] = a.slotIDs[j], a.slotIDs[i] }
-
 // A pendingEntry represents the beginning of a location list entry, missing
 // only its end coordinate.
 type pendingEntry struct {
index ea170fbcdba6892c6f52a61e0de2fabb72ab0268..1d6b47da6d4650fce68aefe4d50a9e05aba9f6bd 100644 (file)
@@ -7,6 +7,7 @@ package ssa
 import (
        "bytes"
        "cmd/internal/src"
+       "cmp"
        "fmt"
        "html"
        "io"
@@ -827,19 +828,13 @@ type FuncLines struct {
        Lines       []string
 }
 
-// ByTopo sorts topologically: target function is on top,
+// ByTopoCmp sorts topologically: target function is on top,
 // followed by inlined functions sorted by filename and line numbers.
-type ByTopo []*FuncLines
-
-func (x ByTopo) Len() int      { return len(x) }
-func (x ByTopo) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-func (x ByTopo) Less(i, j int) bool {
-       a := x[i]
-       b := x[j]
-       if a.Filename == b.Filename {
-               return a.StartLineno < b.StartLineno
+func ByTopoCmp(a, b *FuncLines) int {
+       if r := strings.Compare(a.Filename, b.Filename); r != 0 {
+               return r
        }
-       return a.Filename < b.Filename
+       return cmp.Compare(a.StartLineno, b.StartLineno)
 }
 
 // WriteSources writes lines as source code in a column headed by title.
index 4093a380c93f2cd5674bfb249ffd240401a6e478..b42727674f4cd2826ea5bd097abbe6dcbf45f005 100644 (file)
@@ -8,6 +8,7 @@ import (
        "cmd/compile/internal/base"
        "cmd/compile/internal/types"
        "container/heap"
+       "slices"
        "sort"
 )
 
@@ -525,13 +526,13 @@ func storeOrder(values []*Value, sset *sparseSet, storeNumber []int32) []*Value
                                }
                        } else {
                                if start != -1 {
-                                       sort.Sort(bySourcePos(order[start:i]))
+                                       slices.SortFunc(order[start:i], valuePosCmp)
                                        start = -1
                                }
                        }
                }
                if start != -1 {
-                       sort.Sort(bySourcePos(order[start:]))
+                       slices.SortFunc(order[start:], valuePosCmp)
                }
        }
 
@@ -568,8 +569,12 @@ func (v *Value) hasFlagInput() bool {
        return false
 }
 
-type bySourcePos []*Value
-
-func (s bySourcePos) Len() int           { return len(s) }
-func (s bySourcePos) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-func (s bySourcePos) Less(i, j int) bool { return s[i].Pos.Before(s[j].Pos) }
+func valuePosCmp(a, b *Value) int {
+       if a.Pos.Before(b.Pos) {
+               return -1
+       }
+       if a.Pos.After(b.Pos) {
+               return +1
+       }
+       return 0
+}
index 5b63cbc47c8fb79623f72c8bc8dbbb5ccb1c17cb..c05b5a62410ed717999aed9491bea25bb82f3e19 100644 (file)
@@ -13,7 +13,7 @@ import (
        "internal/buildcfg"
        "os"
        "path/filepath"
-       "sort"
+       "slices"
        "strings"
 
        "cmd/compile/internal/abi"
@@ -789,7 +789,7 @@ func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *ir.Func) {
                inlFns = append(inlFns, fnLines)
        }
 
-       sort.Sort(ssa.ByTopo(inlFns))
+       slices.SortFunc(inlFns, ssa.ByTopoCmp)
        if targetFn != nil {
                inlFns = append([]*ssa.FuncLines{targetFn}, inlFns...)
        }
index d64b0f0e2230542681655c69e64f3776a819afa3..af7ab38638ad17724004aa34fe69105bd9ba1ab7 100644 (file)
@@ -6,7 +6,7 @@ package typecheck
 
 import (
        "fmt"
-       "sort"
+       "slices"
        "strings"
 
        "cmd/compile/internal/base"
@@ -144,7 +144,7 @@ func CalcMethods(t *types.Type) {
        }
 
        ms = append(ms, t.Methods()...)
-       sort.Sort(types.MethodsByName(ms))
+       slices.SortFunc(ms, types.MethodsByNameCmp)
        t.SetAllMethods(ms)
 }
 
index 00707fc86e6a4954b20b3d377b18fe868c1b74f5..308245d9b7299bbaeedd3c3a061e59a4abe14621 100644 (file)
@@ -6,6 +6,7 @@ package types
 
 import (
        "math"
+       "slices"
        "sort"
 
        "cmd/compile/internal/base"
@@ -146,7 +147,7 @@ func expandiface(t *Type) {
                m.Pos = src.NoXPos
        }
 
-       sort.Sort(MethodsByName(methods))
+       slices.SortFunc(methods, MethodsByNameCmp)
 
        if int64(len(methods)) >= MaxWidth/int64(PtrSize) {
                base.ErrorfAt(typePos(t), 0, "interface too large")
index 765c070cd94193c4c37db0f4415d1ee3ea06b031..83b12376345ab765785d0faa87811637f39c1804 100644 (file)
@@ -4,16 +4,13 @@
 
 package types
 
-// MethodsByName sorts methods by name.
-type MethodsByName []*Field
-
-func (x MethodsByName) Len() int           { return len(x) }
-func (x MethodsByName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x MethodsByName) Less(i, j int) bool { return x[i].Sym.Less(x[j].Sym) }
-
-// EmbeddedsByName sorts embedded types by name.
-type EmbeddedsByName []*Field
-
-func (x EmbeddedsByName) Len() int           { return len(x) }
-func (x EmbeddedsByName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x EmbeddedsByName) Less(i, j int) bool { return x[i].Type.Sym().Less(x[j].Type.Sym()) }
+// MethodsByNameCmp sorts methods by name.
+func MethodsByNameCmp(x, y *Field) int {
+       if x.Sym.Less(y.Sym) {
+               return -1
+       }
+       if y.Sym.Less(x.Sym) {
+               return +1
+       }
+       return 0
+}
index 28e4a7faa6ce8df3396981e5f44af41a5eeb0156..9a3664eafdc70296b9abb9d72c36fb01363494c8 100644 (file)
@@ -716,6 +716,7 @@ func (check *Checker) packageObjects() {
 }
 
 // inSourceOrder implements the sort.Sort interface.
+// TODO(gri) replace with slices.SortFunc
 type inSourceOrder []Object
 
 func (a inSourceOrder) Len() int           { return len(a) }
index 01636ed379a090c2cbcf3543c1b7b0d1919acd59..83498ad21d08c2f272a9a46d85a467ba7937e5dc 100644 (file)
@@ -360,6 +360,7 @@ func assertSortedMethods(list []*Func) {
 }
 
 // byUniqueMethodName method lists can be sorted by their unique method names.
+// todo: replace with slices.SortFunc
 type byUniqueMethodName []*Func
 
 func (a byUniqueMethodName) Len() int           { return len(a) }
index d8bb989bcce2444baf75405cbc25f9c25aeff665..9207fa0e8b0987de895bdc95d3d5555f603b8d66 100644 (file)
@@ -7,6 +7,7 @@ package main
 import (
        "bytes"
        "cmd/internal/cov/covcmd"
+       "cmp"
        "encoding/json"
        "flag"
        "fmt"
@@ -20,7 +21,7 @@ import (
        "log"
        "os"
        "path/filepath"
-       "sort"
+       "slices"
        "strconv"
        "strings"
 
@@ -975,12 +976,6 @@ type block1 struct {
        index int
 }
 
-type blockSlice []block1
-
-func (b blockSlice) Len() int           { return len(b) }
-func (b blockSlice) Less(i, j int) bool { return b[i].startByte < b[j].startByte }
-func (b blockSlice) Swap(i, j int)      { b[i], b[j] = b[j], b[i] }
-
 // offset translates a token position into a 0-indexed byte offset.
 func (f *File) offset(pos token.Pos) int {
        return f.fset.Position(pos).Offset
@@ -997,7 +992,9 @@ func (f *File) addVariables(w io.Writer) {
                t[i].Block = f.blocks[i]
                t[i].index = i
        }
-       sort.Sort(blockSlice(t))
+       slices.SortFunc(t, func(a, b block1) int {
+               return cmp.Compare(a.startByte, b.startByte)
+       })
        for i := 1; i < len(t); i++ {
                if t[i-1].endByte > t[i].startByte {
                        fmt.Fprintf(os.Stderr, "cover: internal error: block %d overlaps block %d\n", t[i-1].index, t[i].index)
index 7abdab28a8df21095aebc8ea009919406dd03128..26adae41ee44106cdc86763ae3ae287b0ed4ac08 100644 (file)
@@ -20,20 +20,6 @@ type fix struct {
        disabled bool // whether this fix should be disabled by default
 }
 
-// main runs sort.Sort(byName(fixes)) before printing list of fixes.
-type byName []fix
-
-func (f byName) Len() int           { return len(f) }
-func (f byName) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
-func (f byName) Less(i, j int) bool { return f[i].name < f[j].name }
-
-// main runs sort.Sort(byDate(fixes)) before applying fixes.
-type byDate []fix
-
-func (f byDate) Len() int           { return len(f) }
-func (f byDate) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
-func (f byDate) Less(i, j int) bool { return f[i].date < f[j].date }
-
 var fixes []fix
 
 func register(f fix) {
index 6f1ff120da1057c8bfe59c5ee33e7f3c4721701a..44ce396e372198c21cef239c327641f40014eb24 100644 (file)
@@ -19,7 +19,7 @@ import (
        "io/fs"
        "os"
        "path/filepath"
-       "sort"
+       "slices"
        "strings"
 
        "cmd/internal/telemetry/counter"
@@ -50,7 +50,9 @@ func usage() {
        fmt.Fprintf(os.Stderr, "usage: go tool fix [-diff] [-r fixname,...] [-force fixname,...] [path ...]\n")
        flag.PrintDefaults()
        fmt.Fprintf(os.Stderr, "\nAvailable rewrites are:\n")
-       sort.Sort(byName(fixes))
+       slices.SortFunc(fixes, func(a, b fix) int {
+               return strings.Compare(a.name, b.name)
+       })
        for _, f := range fixes {
                if f.disabled {
                        fmt.Fprintf(os.Stderr, "\n%s (disabled)\n", f.name)
@@ -76,7 +78,9 @@ func main() {
                os.Exit(exitCode)
        }
 
-       sort.Sort(byDate(fixes))
+       slices.SortFunc(fixes, func(a, b fix) int {
+               return strings.Compare(a.date, b.date)
+       })
 
        if *allowedRewrites != "" {
                allowed = make(map[string]bool)
index 6d4e78fb265edfcea6db4a0eec015391a313b34a..eb363a2436d056ae3a37e8b8865f1e5eaedbd149 100644 (file)
@@ -10,11 +10,12 @@ package dwarf
 import (
        "bytes"
        "cmd/internal/src"
+       "cmp"
        "errors"
        "fmt"
        "internal/buildcfg"
        "os/exec"
-       "sort"
+       "slices"
        "strconv"
        "strings"
 )
@@ -1112,7 +1113,7 @@ func putPrunedScopes(ctxt Context, s *FnState, fnabbrev int) error {
                                pruned.Vars = append(pruned.Vars, s.Vars[i])
                        }
                }
-               sort.Sort(byChildIndex(pruned.Vars))
+               slices.SortFunc(pruned.Vars, byChildIndexCmp)
                scopes[k] = pruned
        }
 
@@ -1181,7 +1182,7 @@ func PutAbstractFunc(ctxt Context, s *FnState) error {
                        }
                }
                if len(flattened) > 0 {
-                       sort.Sort(byChildIndex(flattened))
+                       slices.SortFunc(flattened, byChildIndexCmp)
 
                        if logDwarf {
                                ctxt.Logf("putAbstractScope(%v): vars:", s.Info)
@@ -1245,7 +1246,7 @@ func putInlinedFunc(ctxt Context, s *FnState, callIdx int) error {
 
        // Variables associated with this inlined routine instance.
        vars := ic.InlVars
-       sort.Sort(byChildIndex(vars))
+       slices.SortFunc(vars, byChildIndexCmp)
        inlIndex := ic.InlIndex
        var encbuf [20]byte
        for _, v := range vars {
@@ -1562,12 +1563,8 @@ func putvar(ctxt Context, s *FnState, v *Var, absfn Sym, fnabbrev, inlIndex int,
        // Var has no children => no terminator
 }
 
-// byChildIndex implements sort.Interface for []*dwarf.Var by child index.
-type byChildIndex []*Var
-
-func (s byChildIndex) Len() int           { return len(s) }
-func (s byChildIndex) Less(i, j int) bool { return s[i].ChildIndex < s[j].ChildIndex }
-func (s byChildIndex) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
+// byChildIndexCmp compares two *dwarf.Var by child index.
+func byChildIndexCmp(a, b *Var) int { return cmp.Compare(a.ChildIndex, b.ChildIndex) }
 
 // IsDWARFEnabledOnAIXLd returns true if DWARF is possible on the
 // current extld.
index 4e6eff9e17ca8ac55ff68b373fa97e1358fb7ef3..a02519c147a3470b91ac7da16e9eba5e6029ac79 100644 (file)
@@ -37,7 +37,7 @@ import (
        "internal/buildcfg"
        "log"
        "math"
-       "sort"
+       "slices"
 )
 
 // ctxt5 holds state while assembling a single function.
@@ -1203,36 +1203,20 @@ func cmp(a int, b int) bool {
        return false
 }
 
-type ocmp []Optab
-
-func (x ocmp) Len() int {
-       return len(x)
-}
-
-func (x ocmp) Swap(i, j int) {
-       x[i], x[j] = x[j], x[i]
-}
-
-func (x ocmp) Less(i, j int) bool {
-       p1 := &x[i]
-       p2 := &x[j]
-       n := int(p1.as) - int(p2.as)
-       if n != 0 {
-               return n < 0
+func ocmp(a, b Optab) int {
+       if a.as != b.as {
+               return int(a.as) - int(b.as)
        }
-       n = int(p1.a1) - int(p2.a1)
-       if n != 0 {
-               return n < 0
+       if a.a1 != b.a1 {
+               return int(a.a1) - int(b.a1)
        }
-       n = int(p1.a2) - int(p2.a2)
-       if n != 0 {
-               return n < 0
+       if a.a2 != b.a2 {
+               return int(a.a2) - int(b.a2)
        }
-       n = int(p1.a3) - int(p2.a3)
-       if n != 0 {
-               return n < 0
+       if a.a3 != b.a3 {
+               return int(a.a3) - int(b.a3)
        }
-       return false
+       return 0
 }
 
 func opset(a, b0 obj.As) {
@@ -1271,7 +1255,7 @@ func buildop(ctxt *obj.Link) {
                }
        }
 
-       sort.Sort(ocmp(optab[:n]))
+       slices.SortFunc(optab[:n], ocmp)
        for i := 0; i < n; i++ {
                r := optab[i].as
                r0 := r & obj.AMask
index bd2bd037ba850cd5380dfa178a50a87bedeefd03..33c0b196110e36529a42ad0e43c2332d1ce642be 100644 (file)
@@ -36,7 +36,7 @@ import (
        "fmt"
        "log"
        "math"
-       "sort"
+       "slices"
        "strings"
 )
 
@@ -2700,38 +2700,26 @@ func cmp(a int, b int) bool {
        return false
 }
 
-type ocmp []Optab
-
-func (x ocmp) Len() int {
-       return len(x)
-}
-
-func (x ocmp) Swap(i, j int) {
-       x[i], x[j] = x[j], x[i]
-}
-
-func (x ocmp) Less(i, j int) bool {
-       p1 := &x[i]
-       p2 := &x[j]
+func ocmp(p1, p2 Optab) int {
        if p1.as != p2.as {
-               return p1.as < p2.as
+               return int(p1.as) - int(p2.as)
        }
        if p1.a1 != p2.a1 {
-               return p1.a1 < p2.a1
+               return int(p1.a1) - int(p2.a1)
        }
        if p1.a2 != p2.a2 {
-               return p1.a2 < p2.a2
+               return int(p1.a2) - int(p2.a2)
        }
        if p1.a3 != p2.a3 {
-               return p1.a3 < p2.a3
+               return int(p1.a3) - int(p2.a3)
        }
        if p1.a4 != p2.a4 {
-               return p1.a4 < p2.a4
+               return int(p1.a4) - int(p2.a4)
        }
        if p1.scond != p2.scond {
-               return p1.scond < p2.scond
+               return int(p1.scond) - int(p2.scond)
        }
-       return false
+       return 0
 }
 
 func oprangeset(a obj.As, t []Optab) {
@@ -2754,7 +2742,7 @@ func buildop(ctxt *obj.Link) {
                }
        }
 
-       sort.Sort(ocmp(optab))
+       slices.SortFunc(optab, ocmp)
        for i := 0; i < len(optab); i++ {
                as, start := optab[i].as, i
                for ; i < len(optab)-1; i++ {
index 47882723ddd71d87e8260e2c1a3433db80eb23f6..9b38cebf839023ef3d74422f591c37ece312599c 100644 (file)
@@ -11,7 +11,8 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/src"
        "fmt"
-       "sort"
+       "slices"
+       "strings"
        "sync"
 )
 
@@ -665,7 +666,9 @@ func (ft *DwarfFixupTable) Finalize(myimportpath string, trace bool) {
                fns[idx] = fn
                idx++
        }
-       sort.Sort(BySymName(fns))
+       slices.SortFunc(fns, func(a, b *LSym) int {
+               return strings.Compare(a.Name, b.Name)
+       })
 
        // Should not be called during parallel portion of compilation.
        if ft.ctxt.InParallel {
@@ -692,9 +695,3 @@ func (ft *DwarfFixupTable) Finalize(myimportpath string, trace bool) {
                }
        }
 }
-
-type BySymName []*LSym
-
-func (s BySymName) Len() int           { return len(s) }
-func (s BySymName) Less(i, j int) bool { return s[i].Name < s[j].Name }
-func (s BySymName) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
index d78e594fc97961c604f1fcf77184eb154e9e6d38..261e4a13c8b26e44cd4fce37aaefe148bebdfcd5 100644 (file)
@@ -9,7 +9,7 @@ import (
        "cmd/internal/objabi"
        "fmt"
        "log"
-       "sort"
+       "slices"
 )
 
 // ctxt0 holds state while assembling a single function.
@@ -964,36 +964,20 @@ func cmp(a int, b int) bool {
        return false
 }
 
-type ocmp []Optab
-
-func (x ocmp) Len() int {
-       return len(x)
-}
-
-func (x ocmp) Swap(i, j int) {
-       x[i], x[j] = x[j], x[i]
-}
-
-func (x ocmp) Less(i, j int) bool {
-       p1 := &x[i]
-       p2 := &x[j]
-       n := int(p1.as) - int(p2.as)
-       if n != 0 {
-               return n < 0
+func ocmp(p1, p2 Optab) int {
+       if p1.as != p2.as {
+               return int(p1.as) - int(p2.as)
        }
-       n = int(p1.from1) - int(p2.from1)
-       if n != 0 {
-               return n < 0
+       if p1.from1 != p2.from1 {
+               return int(p1.from1) - int(p2.from1)
        }
-       n = int(p1.reg) - int(p2.reg)
-       if n != 0 {
-               return n < 0
+       if p1.reg != p2.reg {
+               return int(p1.reg) - int(p2.reg)
        }
-       n = int(p1.to1) - int(p2.to1)
-       if n != 0 {
-               return n < 0
+       if p1.to1 != p2.to1 {
+               return int(p1.to1) - int(p2.to1)
        }
-       return false
+       return 0
 }
 
 func opset(a, b0 obj.As) {
@@ -1025,7 +1009,7 @@ func buildop(ctxt *obj.Link) {
        }
        for n = 0; optab[n].as != obj.AXXX; n++ {
        }
-       sort.Sort(ocmp(optab[:n]))
+       slices.SortFunc(optab[:n], ocmp)
        for i := 0; i < n; i++ {
                r := optab[i].as
                r0 := r & obj.AMask
index 2dd4818ded7eeae366e1828179aa90f3bd164d59..5c52ee63a47d354bf7f889ab71a1658fd941622b 100644 (file)
@@ -35,7 +35,7 @@ import (
        "cmd/internal/sys"
        "fmt"
        "log"
-       "sort"
+       "slices"
 )
 
 // ctxt0 holds state while assembling a single function.
@@ -875,36 +875,20 @@ func cmp(a int, b int) bool {
        return false
 }
 
-type ocmp []Optab
-
-func (x ocmp) Len() int {
-       return len(x)
-}
-
-func (x ocmp) Swap(i, j int) {
-       x[i], x[j] = x[j], x[i]
-}
-
-func (x ocmp) Less(i, j int) bool {
-       p1 := &x[i]
-       p2 := &x[j]
-       n := int(p1.as) - int(p2.as)
-       if n != 0 {
-               return n < 0
+func ocmp(p1, p2 Optab) int {
+       if p1.as != p2.as {
+               return int(p1.as) - int(p2.as)
        }
-       n = int(p1.a1) - int(p2.a1)
-       if n != 0 {
-               return n < 0
+       if p1.a1 != p2.a1 {
+               return int(p1.a1) - int(p2.a1)
        }
-       n = int(p1.a2) - int(p2.a2)
-       if n != 0 {
-               return n < 0
+       if p1.a2 != p2.a2 {
+               return int(p1.a2) - int(p2.a2)
        }
-       n = int(p1.a3) - int(p2.a3)
-       if n != 0 {
-               return n < 0
+       if p1.a3 != p2.a3 {
+               return int(p1.a3) - int(p2.a3)
        }
-       return false
+       return 0
 }
 
 func opset(a, b0 obj.As) {
@@ -930,7 +914,7 @@ func buildop(ctxt *obj.Link) {
        }
        for n = 0; optab[n].as != obj.AXXX; n++ {
        }
-       sort.Sort(ocmp(optab[:n]))
+       slices.SortFunc(optab[:n], ocmp)
        for i := 0; i < n; i++ {
                r := optab[i].as
                r0 := r & obj.AMask
index de383499305f5e2fa7ea0d43e7db51de417dbdcd..bf135af554dfac353bbd1234fbeaee1b6c0b6d70 100644 (file)
@@ -13,6 +13,7 @@ import (
        "cmd/internal/notsha256"
        "cmd/internal/objabi"
        "cmd/internal/sys"
+       "cmp"
        "encoding/binary"
        "fmt"
        "internal/abi"
@@ -20,6 +21,7 @@ import (
        "log"
        "os"
        "path/filepath"
+       "slices"
        "sort"
        "strings"
 )
@@ -177,7 +179,7 @@ func WriteObjFile(ctxt *Link, b *bio.Writer) {
        h.Offsets[goobj.BlkReloc] = w.Offset()
        for _, list := range lists {
                for _, s := range list {
-                       sort.Sort(relocByOff(s.R)) // some platforms (e.g. PE) requires relocations in address order
+                       slices.SortFunc(s.R, relocByOffCmp) // some platforms (e.g. PE) requires relocations in address order
                        for i := range s.R {
                                w.Reloc(&s.R[i])
                        }
@@ -935,7 +937,7 @@ func (ctxt *Link) writeSymDebugNamed(s *LSym, name string) {
                fmt.Fprintf(ctxt.Bso, "\n")
        }
 
-       sort.Sort(relocByOff(s.R)) // generate stable output
+       slices.SortFunc(s.R, relocByOffCmp) // generate stable output
        for _, r := range s.R {
                name := ""
                ver := ""
@@ -955,9 +957,7 @@ func (ctxt *Link) writeSymDebugNamed(s *LSym, name string) {
        }
 }
 
-// relocByOff sorts relocations by their offsets.
-type relocByOff []Reloc
-
-func (x relocByOff) Len() int           { return len(x) }
-func (x relocByOff) Less(i, j int) bool { return x[i].Off < x[j].Off }
-func (x relocByOff) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
+// relocByOffCmp compare relocations by their offsets.
+func relocByOffCmp(x, y Reloc) int {
+       return cmp.Compare(x.Off, y.Off)
+}
index 6d2962acd62740ef08cae33836c38e92ed12bf84..4af92a27f8d8235a65e499c561d748f8191300e6 100644 (file)
@@ -35,7 +35,7 @@ import (
        "fmt"
        "log"
        "math"
-       "sort"
+       "slices"
 )
 
 // ctxtz holds state while assembling a single function.
@@ -853,40 +853,23 @@ func cmp(a int, b int) bool {
        return false
 }
 
-type ocmp []Optab
-
-func (x ocmp) Len() int {
-       return len(x)
-}
-
-func (x ocmp) Swap(i, j int) {
-       x[i], x[j] = x[j], x[i]
-}
-
-func (x ocmp) Less(i, j int) bool {
-       p1 := &x[i]
-       p2 := &x[j]
-       n := int(p1.as) - int(p2.as)
-       if n != 0 {
-               return n < 0
+func ocmp(p1, p2 Optab) int {
+       if p1.as != p2.as {
+               return int(p1.as) - int(p2.as)
        }
-       n = int(p1.a1) - int(p2.a1)
-       if n != 0 {
-               return n < 0
+       if p1.a1 != p2.a1 {
+               return int(p1.a1) - int(p2.a1)
        }
-       n = int(p1.a2) - int(p2.a2)
-       if n != 0 {
-               return n < 0
+       if p1.a2 != p2.a2 {
+               return int(p1.a2) - int(p2.a2)
        }
-       n = int(p1.a3) - int(p2.a3)
-       if n != 0 {
-               return n < 0
+       if p1.a3 != p2.a3 {
+               return int(p1.a3) - int(p2.a3)
        }
-       n = int(p1.a4) - int(p2.a4)
-       if n != 0 {
-               return n < 0
+       if p1.a4 != p2.a4 {
+               return int(p1.a4) - int(p2.a4)
        }
-       return false
+       return 0
 }
 func opset(a, b obj.As) {
        oprange[a&obj.AMask] = oprange[b&obj.AMask]
@@ -907,7 +890,7 @@ func buildop(ctxt *obj.Link) {
                        }
                }
        }
-       sort.Sort(ocmp(optab))
+       slices.SortFunc(optab, ocmp)
        for i := 0; i < len(optab); i++ {
                r := optab[i].as
                start := i
index c92497527a412de23fbcdb89b1951f462e321c5e..8258145f26f3424720d8caf40ee4bad64df2d948 100644 (file)
@@ -11,6 +11,7 @@ import (
        "debug/macho"
        "fmt"
        "io"
+       "slices"
        "sort"
 )
 
@@ -42,7 +43,7 @@ func (f *machoFile) symbols() ([]Sym, error) {
                        addrs = append(addrs, s.Value)
                }
        }
-       sort.Sort(uint64s(addrs))
+       slices.Sort(addrs)
 
        var syms []Sym
        for _, s := range f.macho.Symtab.Syms {
@@ -121,12 +122,6 @@ func (f *machoFile) goarch() string {
        return ""
 }
 
-type uint64s []uint64
-
-func (x uint64s) Len() int           { return len(x) }
-func (x uint64s) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-func (x uint64s) Less(i, j int) bool { return x[i] < x[j] }
-
 func (f *machoFile) loadAddress() (uint64, error) {
        if seg := f.macho.Segment("__TEXT"); seg != nil {
                return seg.Addr, nil
index d890a0b7562cf4177afc03df877d271a0b499ad3..2f2d7718132d5741ee4c26e95b6516ef8e93a537 100644 (file)
@@ -7,12 +7,13 @@ package objfile
 
 import (
        "cmd/internal/archive"
+       "cmp"
        "debug/dwarf"
        "debug/gosym"
        "fmt"
        "io"
        "os"
-       "sort"
+       "slices"
 )
 
 type rawFile interface {
@@ -131,16 +132,12 @@ func (e *Entry) Symbols() ([]Sym, error) {
        if err != nil {
                return nil, err
        }
-       sort.Sort(byAddr(syms))
+       slices.SortFunc(syms, func(a, b Sym) int {
+               return cmp.Compare(a.Addr, b.Addr)
+       })
        return syms, nil
 }
 
-type byAddr []Sym
-
-func (x byAddr) Less(i, j int) bool { return x[i].Addr < x[j].Addr }
-func (x byAddr) Len() int           { return len(x) }
-func (x byAddr) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
-
 func (e *Entry) PCLineTable() (Liner, error) {
        // If the raw file implements Liner directly, use that.
        // Currently, only Go intermediate objects and archives (goobj) use this path.
index 4c4be1e6b7c04c95873e2d0c88efe974428bfae1..774760829c3d0a7741037732eb3cfaa6376a5b75 100644 (file)
@@ -11,6 +11,7 @@ import (
        "debug/pe"
        "fmt"
        "io"
+       "slices"
        "sort"
 )
 
@@ -78,7 +79,7 @@ func (f *peFile) symbols() ([]Sym, error) {
                addrs = append(addrs, sym.Addr)
        }
 
-       sort.Sort(uint64s(addrs))
+       slices.Sort(addrs)
        for i := range syms {
                j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
                if j < len(addrs) {
index da0b345f53274cafbb618cfc7be4898d2db45815..c91970762c79ee2543cb29868da783cb4caffea6 100644 (file)
@@ -12,6 +12,7 @@ import (
        "errors"
        "fmt"
        "io"
+       "slices"
        "sort"
 )
 
@@ -51,7 +52,7 @@ func (f *plan9File) symbols() ([]Sym, error) {
                }
                addrs = append(addrs, s.Value)
        }
-       sort.Sort(uint64s(addrs))
+       slices.Sort(addrs)
 
        var syms []Sym
 
index c44a689a105870db68a9fd5afbb76993fe7bccbb..da4ca6d5ccb660560d59a9454f999558030076df 100644 (file)
@@ -21,13 +21,14 @@ import (
        "cmd/internal/sys"
        "cmd/link/internal/loader"
        "cmd/link/internal/sym"
+       "cmp"
        "fmt"
        "internal/abi"
        "internal/buildcfg"
        "log"
        "path"
        "runtime"
-       "sort"
+       "slices"
        "strings"
        "sync"
 )
@@ -2090,7 +2091,7 @@ func (d *dwctxt) dwarfGenerateDebugSyms() {
        abbrevSec := d.writeabbrev()
        dwarfp = append(dwarfp, abbrevSec)
        d.calcCompUnitRanges()
-       sort.Sort(compilationUnitByStartPC(d.linkctxt.compUnits))
+       slices.SortFunc(d.linkctxt.compUnits, compilationUnitByStartPCCmp)
 
        // newdie adds DIEs to the *beginning* of the parent's DIE list.
        // Now that we're done creating DIEs, reverse the trees so DIEs
@@ -2357,21 +2358,16 @@ func dwarfcompress(ctxt *Link) {
        Segdwarf.Length = pos - Segdwarf.Vaddr
 }
 
-type compilationUnitByStartPC []*sym.CompilationUnit
-
-func (v compilationUnitByStartPC) Len() int      { return len(v) }
-func (v compilationUnitByStartPC) Swap(i, j int) { v[i], v[j] = v[j], v[i] }
-
-func (v compilationUnitByStartPC) Less(i, j int) bool {
+func compilationUnitByStartPCCmp(a, b *sym.CompilationUnit) int {
        switch {
-       case len(v[i].Textp) == 0 && len(v[j].Textp) == 0:
-               return v[i].Lib.Pkg < v[j].Lib.Pkg
-       case len(v[i].Textp) != 0 && len(v[j].Textp) == 0:
-               return true
-       case len(v[i].Textp) == 0 && len(v[j].Textp) != 0:
-               return false
+       case len(a.Textp) == 0 && len(b.Textp) == 0:
+               return strings.Compare(a.Lib.Pkg, b.Lib.Pkg)
+       case len(a.Textp) != 0 && len(b.Textp) == 0:
+               return -1
+       case len(a.Textp) == 0 && len(b.Textp) != 0:
+               return +1
        default:
-               return v[i].PCs[0].Start < v[j].PCs[0].Start
+               return cmp.Compare(a.PCs[0].Start, b.PCs[0].Start)
        }
 }
 
index 0d8455d92e336bb342d4078ae865cd216826e8db..3a1bcbfd63e0516764126e212f1844cd0fb44cd0 100644 (file)
@@ -18,7 +18,7 @@ import (
        "os"
        "path/filepath"
        "runtime"
-       "sort"
+       "slices"
        "strings"
 )
 
@@ -1678,8 +1678,9 @@ func (ctxt *Link) doelf() {
                ldr.SetAttrSpecial(s, true)
                sb.SetReachable(true)
                sb.SetSize(notsha256.Size)
-
-               sort.Sort(byPkg(ctxt.Library))
+               slices.SortFunc(ctxt.Library, func(a, b *sym.Library) int {
+                       return strings.Compare(a.Pkg, b.Pkg)
+               })
                h := notsha256.New()
                for _, l := range ctxt.Library {
                        h.Write(l.Fingerprint[:])
index 6d6eda4b33640309767858a6f2c17dc203cffa50..cd553e909ad2fe7731e0dca176566bcc1ea8dcd8 100644 (file)
@@ -17,6 +17,7 @@ import (
        "fmt"
        "internal/buildcfg"
        "math"
+       "slices"
        "sort"
        "strconv"
        "strings"
@@ -1490,10 +1491,6 @@ type peBaseRelocBlock struct {
 // it can be sorted.
 type pePages []uint32
 
-func (p pePages) Len() int           { return len(p) }
-func (p pePages) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
-func (p pePages) Less(i, j int) bool { return p[i] < p[j] }
-
 // A PE base relocation table is a list of blocks, where each block
 // contains relocation information for a single page. The blocks
 // must be emitted in order of page virtual address.
@@ -1547,7 +1544,7 @@ func (rt *peBaseRelocTable) write(ctxt *Link) {
        out := ctxt.Out
 
        // sort the pages array
-       sort.Sort(rt.pages)
+       slices.Sort(rt.pages)
 
        // .reloc section must be 32-bit aligned
        if out.Offset()&3 != 0 {
index 92e856a7660d5e52f56cf0a580a3a2c5f599f75b..f48e2087c19768087662e713a6ff87227fa01c33 100644 (file)
@@ -361,20 +361,6 @@ func asmbPlan9Sym(ctxt *Link) {
        }
 }
 
-type byPkg []*sym.Library
-
-func (libs byPkg) Len() int {
-       return len(libs)
-}
-
-func (libs byPkg) Less(a, b int) bool {
-       return libs[a].Pkg < libs[b].Pkg
-}
-
-func (libs byPkg) Swap(a, b int) {
-       libs[a], libs[b] = libs[b], libs[a]
-}
-
 // Create a table with information on the text sections.
 // Return the symbol of the table, and number of sections.
 func textsectionmap(ctxt *Link) (loader.Sym, uint32) {
index 5eca6e01817e185bdb870471cc8ef6857164db4f..966de5571c3077853cfa2afbf35fe4b977a34481 100644 (file)
@@ -8,26 +8,21 @@ import (
        "cmd/internal/objabi"
        "cmd/link/internal/loader"
        "cmd/link/internal/sym"
-       "sort"
+       "slices"
+       "strings"
 )
 
-type byTypeStr []typelinkSortKey
-
 type typelinkSortKey struct {
        TypeStr string
        Type    loader.Sym
 }
 
-func (s byTypeStr) Less(i, j int) bool { return s[i].TypeStr < s[j].TypeStr }
-func (s byTypeStr) Len() int           { return len(s) }
-func (s byTypeStr) Swap(i, j int)      { s[i], s[j] = s[j], s[i] }
-
 // typelink generates the typelink table which is used by reflect.typelinks().
 // Types that should be added to the typelinks table are marked with the
 // MakeTypelink attribute by the compiler.
 func (ctxt *Link) typelink() {
        ldr := ctxt.loader
-       typelinks := byTypeStr{}
+       var typelinks []typelinkSortKey
        var itabs []loader.Sym
        for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
                if !ldr.AttrReachable(s) {
@@ -39,7 +34,9 @@ func (ctxt *Link) typelink() {
                        itabs = append(itabs, s)
                }
        }
-       sort.Sort(typelinks)
+       slices.SortFunc(typelinks, func(a, b typelinkSortKey) int {
+               return strings.Compare(a.TypeStr, b.TypeStr)
+       })
 
        tl := ldr.CreateSymForUpdate("runtime.typelink", 0)
        tl.SetType(sym.STYPELINK)
index b9eaca7fb6fd61c9e41b6d5d1b90220dbb1831ea..8abbb931e5f51b935214a0579b6ff60783523e4d 100644 (file)
@@ -9,7 +9,8 @@ import (
        "cmd/internal/objabi"
        "cmd/internal/sys"
        "cmd/link/internal/sym"
-       "sort"
+       "cmp"
+       "slices"
 )
 
 // SymbolBuilder is a helper designed to help with the construction
@@ -154,18 +155,11 @@ func (sb *SymbolBuilder) AddRel(typ objabi.RelocType) (Reloc, int) {
        return relocs.At(j), j
 }
 
-// Sort relocations by offset.
+// SortRelocs Sort relocations by offset.
 func (sb *SymbolBuilder) SortRelocs() {
-       sort.Sort((*relocsByOff)(sb.extSymPayload))
-}
-
-// Implement sort.Interface
-type relocsByOff extSymPayload
-
-func (p *relocsByOff) Len() int           { return len(p.relocs) }
-func (p *relocsByOff) Less(i, j int) bool { return p.relocs[i].Off() < p.relocs[j].Off() }
-func (p *relocsByOff) Swap(i, j int) {
-       p.relocs[i], p.relocs[j] = p.relocs[j], p.relocs[i]
+       slices.SortFunc(sb.extSymPayload.relocs, func(a, b goobj.Reloc) int {
+               return cmp.Compare(a.Off(), b.Off())
+       })
 }
 
 func (sb *SymbolBuilder) Reachable() bool {
index 2953c4fffc86f0a54d86d7efb840ea5c87d8679c..3ca9bb5422ea32ae3e0d38c4d49fa7086cb1a24b 100644 (file)
@@ -713,6 +713,7 @@ func (check *Checker) packageObjects() {
 }
 
 // inSourceOrder implements the sort.Sort interface.
+// TODO(gri) replace with slices.SortFunc
 type inSourceOrder []Object
 
 func (a inSourceOrder) Len() int           { return len(a) }
index a94d4fada460587be25b3e2f0e595a05be8a83bb..1ffe6ee14c2db471898f1f58294c978c98a779e4 100644 (file)
@@ -363,6 +363,7 @@ func assertSortedMethods(list []*Func) {
 }
 
 // byUniqueMethodName method lists can be sorted by their unique method names.
+// todo: replace with slices.SortFunc
 type byUniqueMethodName []*Func
 
 func (a byUniqueMethodName) Len() int           { return len(a) }