"flag"
"fmt"
"internal/buildcfg"
+ "slices"
"sort"
+ "strings"
"cmd/compile/internal/base"
"cmd/compile/internal/ir"
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
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() }
"go/token"
"io"
"math/big"
+ "slices"
"sort"
"strings"
)
}
// 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
"internal/abi"
"internal/buildcfg"
"os"
+ "slices"
"sort"
"strings"
"sync"
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)
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)
}
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,
// 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
"runtime"
"runtime/pprof"
"runtime/trace"
+ "slices"
"sort"
"strings"
"sync"
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.
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 }
import (
"cmd/compile/internal/types"
"cmd/internal/src"
+ "cmp"
"fmt"
- "sort"
+ "slices"
)
// cse does common-subexpression elimination on the Function.
// 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
}
// 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)
// 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]
// 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 {
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
-}
"cmd/internal/dwarf"
"cmd/internal/obj"
"cmd/internal/src"
+ "cmp"
"encoding/hex"
"fmt"
"internal/buildcfg"
"math/bits"
- "sort"
+ "slices"
"strings"
)
// 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) {
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))
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 {
import (
"bytes"
"cmd/internal/src"
+ "cmp"
"fmt"
"html"
"io"
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.
"cmd/compile/internal/base"
"cmd/compile/internal/types"
"container/heap"
+ "slices"
"sort"
)
}
} 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)
}
}
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
+}
"internal/buildcfg"
"os"
"path/filepath"
- "sort"
+ "slices"
"strings"
"cmd/compile/internal/abi"
inlFns = append(inlFns, fnLines)
}
- sort.Sort(ssa.ByTopo(inlFns))
+ slices.SortFunc(inlFns, ssa.ByTopoCmp)
if targetFn != nil {
inlFns = append([]*ssa.FuncLines{targetFn}, inlFns...)
}
import (
"fmt"
- "sort"
+ "slices"
"strings"
"cmd/compile/internal/base"
}
ms = append(ms, t.Methods()...)
- sort.Sort(types.MethodsByName(ms))
+ slices.SortFunc(ms, types.MethodsByNameCmp)
t.SetAllMethods(ms)
}
import (
"math"
+ "slices"
"sort"
"cmd/compile/internal/base"
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")
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
+}
}
// inSourceOrder implements the sort.Sort interface.
+// TODO(gri) replace with slices.SortFunc
type inSourceOrder []Object
func (a inSourceOrder) Len() int { return len(a) }
}
// 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) }
import (
"bytes"
"cmd/internal/cov/covcmd"
+ "cmp"
"encoding/json"
"flag"
"fmt"
"log"
"os"
"path/filepath"
- "sort"
+ "slices"
"strconv"
"strings"
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
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)
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) {
"io/fs"
"os"
"path/filepath"
- "sort"
+ "slices"
"strings"
"cmd/internal/telemetry/counter"
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)
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)
import (
"bytes"
"cmd/internal/src"
+ "cmp"
"errors"
"fmt"
"internal/buildcfg"
"os/exec"
- "sort"
+ "slices"
"strconv"
"strings"
)
pruned.Vars = append(pruned.Vars, s.Vars[i])
}
}
- sort.Sort(byChildIndex(pruned.Vars))
+ slices.SortFunc(pruned.Vars, byChildIndexCmp)
scopes[k] = pruned
}
}
}
if len(flattened) > 0 {
- sort.Sort(byChildIndex(flattened))
+ slices.SortFunc(flattened, byChildIndexCmp)
if logDwarf {
ctxt.Logf("putAbstractScope(%v): vars:", s.Info)
// 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 {
// 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.
"internal/buildcfg"
"log"
"math"
- "sort"
+ "slices"
)
// ctxt5 holds state while assembling a single function.
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) {
}
}
- sort.Sort(ocmp(optab[:n]))
+ slices.SortFunc(optab[:n], ocmp)
for i := 0; i < n; i++ {
r := optab[i].as
r0 := r & obj.AMask
"fmt"
"log"
"math"
- "sort"
+ "slices"
"strings"
)
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) {
}
}
- 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++ {
"cmd/internal/objabi"
"cmd/internal/src"
"fmt"
- "sort"
+ "slices"
+ "strings"
"sync"
)
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 {
}
}
}
-
-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] }
"cmd/internal/objabi"
"fmt"
"log"
- "sort"
+ "slices"
)
// ctxt0 holds state while assembling a single function.
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) {
}
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
"cmd/internal/sys"
"fmt"
"log"
- "sort"
+ "slices"
)
// ctxt0 holds state while assembling a single function.
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) {
}
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
"cmd/internal/notsha256"
"cmd/internal/objabi"
"cmd/internal/sys"
+ "cmp"
"encoding/binary"
"fmt"
"internal/abi"
"log"
"os"
"path/filepath"
+ "slices"
"sort"
"strings"
)
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])
}
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 := ""
}
}
-// 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)
+}
"fmt"
"log"
"math"
- "sort"
+ "slices"
)
// ctxtz holds state while assembling a single function.
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]
}
}
}
- sort.Sort(ocmp(optab))
+ slices.SortFunc(optab, ocmp)
for i := 0; i < len(optab); i++ {
r := optab[i].as
start := i
"debug/macho"
"fmt"
"io"
+ "slices"
"sort"
)
addrs = append(addrs, s.Value)
}
}
- sort.Sort(uint64s(addrs))
+ slices.Sort(addrs)
var syms []Sym
for _, s := range f.macho.Symtab.Syms {
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
import (
"cmd/internal/archive"
+ "cmp"
"debug/dwarf"
"debug/gosym"
"fmt"
"io"
"os"
- "sort"
+ "slices"
)
type rawFile interface {
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.
"debug/pe"
"fmt"
"io"
+ "slices"
"sort"
)
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) {
"errors"
"fmt"
"io"
+ "slices"
"sort"
)
}
addrs = append(addrs, s.Value)
}
- sort.Sort(uint64s(addrs))
+ slices.Sort(addrs)
var syms []Sym
"cmd/internal/sys"
"cmd/link/internal/loader"
"cmd/link/internal/sym"
+ "cmp"
"fmt"
"internal/abi"
"internal/buildcfg"
"log"
"path"
"runtime"
- "sort"
+ "slices"
"strings"
"sync"
)
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
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)
}
}
"os"
"path/filepath"
"runtime"
- "sort"
+ "slices"
"strings"
)
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[:])
"fmt"
"internal/buildcfg"
"math"
+ "slices"
"sort"
"strconv"
"strings"
// 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.
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 {
}
}
-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) {
"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) {
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)
"cmd/internal/objabi"
"cmd/internal/sys"
"cmd/link/internal/sym"
- "sort"
+ "cmp"
+ "slices"
)
// SymbolBuilder is a helper designed to help with the construction
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 {
}
// inSourceOrder implements the sort.Sort interface.
+// TODO(gri) replace with slices.SortFunc
type inSourceOrder []Object
func (a inSourceOrder) Len() int { return len(a) }
}
// 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) }