mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd: replace many sort.Interface with slices.Sort and SortFunc
with slices there's no need to implement sort.Interface
Change-Id: I59167e78881cb1df89a71e33d738d6aeca7adb71
GitHub-Last-Rev: 507ba84453
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>
This commit is contained in:
parent
7cd0a4be5c
commit
d91a2e5b11
38 changed files with 239 additions and 417 deletions
|
|
@ -9,7 +9,9 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"internal/buildcfg"
|
"internal/buildcfg"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"cmd/compile/internal/base"
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/ir"
|
"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 {
|
for t := range fnsym.Func().Autot {
|
||||||
typesyms = append(typesyms, t)
|
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 {
|
for _, sym := range typesyms {
|
||||||
r := obj.Addrel(infosym)
|
r := obj.Addrel(infosym)
|
||||||
r.Sym = sym
|
r.Sym = sym
|
||||||
|
|
|
||||||
|
|
@ -245,9 +245,3 @@ func Import(packages map[string]*types2.Package, path, srcDir string, lookup fun
|
||||||
|
|
||||||
return
|
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() }
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"go/token"
|
"go/token"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -188,7 +189,9 @@ func ImportData(imports map[string]*types2.Package, data, path string) (pkg *typ
|
||||||
}
|
}
|
||||||
// record all referenced packages as imports
|
// record all referenced packages as imports
|
||||||
list := append(([]*types2.Package)(nil), pkgList[1:]...)
|
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)
|
localpkg.SetImports(list)
|
||||||
|
|
||||||
// package was imported completely and without errors
|
// package was imported completely and without errors
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"internal/abi"
|
"internal/abi"
|
||||||
"internal/buildcfg"
|
"internal/buildcfg"
|
||||||
"os"
|
"os"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -991,7 +992,7 @@ func WriteRuntimeTypes() {
|
||||||
for len(signatslice) > 0 {
|
for len(signatslice) > 0 {
|
||||||
signats := signatslice
|
signats := signatslice
|
||||||
// Sort for reproducible builds.
|
// Sort for reproducible builds.
|
||||||
sort.Sort(typesByString(signats))
|
slices.SortFunc(signats, typesStrCmp)
|
||||||
for _, ts := range signats {
|
for _, ts := range signats {
|
||||||
t := ts.t
|
t := ts.t
|
||||||
writeType(t)
|
writeType(t)
|
||||||
|
|
@ -1009,7 +1010,7 @@ func WriteGCSymbols() {
|
||||||
for t := range gcsymset {
|
for t := range gcsymset {
|
||||||
gcsyms = append(gcsyms, typeAndStr{t: t, short: types.TypeSymName(t), regular: t.String()})
|
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 {
|
for _, ts := range gcsyms {
|
||||||
dgcsym(ts.t, true)
|
dgcsym(ts.t, true)
|
||||||
}
|
}
|
||||||
|
|
@ -1187,20 +1188,17 @@ type typeAndStr struct {
|
||||||
regular string
|
regular string
|
||||||
}
|
}
|
||||||
|
|
||||||
type typesByString []typeAndStr
|
func typesStrCmp(a, b typeAndStr) int {
|
||||||
|
|
||||||
func (a typesByString) Len() int { return len(a) }
|
|
||||||
func (a typesByString) Less(i, j int) bool {
|
|
||||||
// put named types before unnamed types
|
// put named types before unnamed types
|
||||||
if a[i].t.Sym() != nil && a[j].t.Sym() == nil {
|
if a.t.Sym() != nil && b.t.Sym() == nil {
|
||||||
return true
|
return -1
|
||||||
}
|
}
|
||||||
if a[i].t.Sym() == nil && a[j].t.Sym() != nil {
|
if a.t.Sym() == nil && b.t.Sym() != nil {
|
||||||
return false
|
return +1
|
||||||
}
|
}
|
||||||
|
|
||||||
if a[i].short != a[j].short {
|
if r := strings.Compare(a.short, b.short); r != 0 {
|
||||||
return a[i].short < a[j].short
|
return r
|
||||||
}
|
}
|
||||||
// When the only difference between the types is whether
|
// When the only difference between the types is whether
|
||||||
// they refer to byte or uint8, such as **byte vs **uint8,
|
// 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
|
// avoid naming collisions, and there shouldn't be a reason to care
|
||||||
// about "byte" vs "uint8": they share the same runtime type
|
// about "byte" vs "uint8": they share the same runtime type
|
||||||
// descriptor anyway.
|
// descriptor anyway.
|
||||||
if a[i].regular != a[j].regular {
|
if r := strings.Compare(a.regular, b.regular); r != 0 {
|
||||||
return a[i].regular < a[j].regular
|
return r
|
||||||
}
|
}
|
||||||
// Identical anonymous interfaces defined in different locations
|
// Identical anonymous interfaces defined in different locations
|
||||||
// will be equal for the above checks, but different in DWARF output.
|
// will be equal for the above checks, but different in DWARF output.
|
||||||
// Sort by source position to ensure deterministic order.
|
// Sort by source position to ensure deterministic order.
|
||||||
// See issues 27013 and 30202.
|
// See issues 27013 and 30202.
|
||||||
if a[i].t.Kind() == types.TINTER && len(a[i].t.AllMethods()) > 0 {
|
if a.t.Kind() == types.TINTER && len(a.t.AllMethods()) > 0 {
|
||||||
return a[i].t.AllMethods()[0].Pos.Before(a[j].t.AllMethods()[0].Pos)
|
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
|
// 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
|
// with a boolean reporting whether the UseGCProg bit should be set in the
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
"runtime/trace"
|
"runtime/trace"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -142,7 +143,9 @@ func main() {
|
||||||
defer trace.Stop()
|
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
|
// The generate tasks are run concurrently, since they are CPU-intensive
|
||||||
// that can easily make use of many cores on a machine.
|
// 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) Len() int { return len(a) }
|
||||||
func (a byKey) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
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 }
|
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 }
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,9 @@ package ssa
|
||||||
import (
|
import (
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
"cmp"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// cse does common-subexpression elimination on the Function.
|
// 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
|
// non-equivalent arguments. Repeat until we can't find any
|
||||||
// more splits.
|
// more splits.
|
||||||
var splitPoints []int
|
var splitPoints []int
|
||||||
byArgClass := new(partitionByArgClass) // reusable partitionByArgClass to reduce allocations
|
|
||||||
for {
|
for {
|
||||||
changed := false
|
changed := false
|
||||||
|
|
||||||
|
|
@ -105,9 +105,18 @@ func cse(f *Func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort by eq class of arguments.
|
// Sort by eq class of arguments.
|
||||||
byArgClass.a = e
|
slices.SortFunc(e, func(v, w *Value) int {
|
||||||
byArgClass.eqClass = valueEqClass
|
for i, a := range v.Args {
|
||||||
sort.Sort(byArgClass)
|
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.
|
// Find split points.
|
||||||
splitPoints = append(splitPoints[:0], 0)
|
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.
|
// if v and w are in the same equivalence class and v dominates w.
|
||||||
rewrite := f.Cache.allocValueSlice(f.NumValues())
|
rewrite := f.Cache.allocValueSlice(f.NumValues())
|
||||||
defer f.Cache.freeValueSlice(rewrite)
|
defer f.Cache.freeValueSlice(rewrite)
|
||||||
byDom := new(partitionByDom) // reusable partitionByDom to reduce allocs
|
|
||||||
for _, e := range partition {
|
for _, e := range partition {
|
||||||
byDom.a = e
|
slices.SortFunc(e, func(v, w *Value) int {
|
||||||
byDom.sdom = sdom
|
return cmp.Compare(sdom.domorder(v.Block), sdom.domorder(w.Block))
|
||||||
sort.Sort(byDom)
|
})
|
||||||
|
|
||||||
for i := 0; i < len(e)-1; i++ {
|
for i := 0; i < len(e)-1; i++ {
|
||||||
// e is sorted by domorder, so a maximal dominant element is first in the slice
|
// e is sorted by domorder, so a maximal dominant element is first in the slice
|
||||||
v := e[i]
|
v := e[i]
|
||||||
|
|
@ -253,7 +262,17 @@ type eqclass []*Value
|
||||||
// backed by the same storage as the input slice.
|
// backed by the same storage as the input slice.
|
||||||
// Equivalence classes of size 1 are ignored.
|
// Equivalence classes of size 1 are ignored.
|
||||||
func partitionValues(a []*Value, auxIDs auxmap) []eqclass {
|
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
|
var partition []eqclass
|
||||||
for len(a) > 0 {
|
for len(a) > 0 {
|
||||||
|
|
@ -322,57 +341,3 @@ func cmpVal(v, w *Value, auxIDs auxmap) types.Cmp {
|
||||||
|
|
||||||
return types.CMPeq
|
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
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,12 @@ import (
|
||||||
"cmd/internal/dwarf"
|
"cmd/internal/dwarf"
|
||||||
"cmd/internal/obj"
|
"cmd/internal/obj"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
"cmp"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"internal/buildcfg"
|
"internal/buildcfg"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
"sort"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -231,10 +232,9 @@ type debugState struct {
|
||||||
// The pending location list entry for each user variable, indexed by VarID.
|
// The pending location list entry for each user variable, indexed by VarID.
|
||||||
pendingEntries []pendingEntry
|
pendingEntries []pendingEntry
|
||||||
|
|
||||||
varParts map[*ir.Name][]SlotID
|
varParts map[*ir.Name][]SlotID
|
||||||
blockDebug []BlockDebug
|
blockDebug []BlockDebug
|
||||||
pendingSlotLocs []VarLoc
|
pendingSlotLocs []VarLoc
|
||||||
partsByVarOffset sort.Interface
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (state *debugState) initializeCache(f *Func, numVars, numSlots int) {
|
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)]
|
state.slotVars = state.slotVars[:len(state.slots)]
|
||||||
}
|
}
|
||||||
|
|
||||||
if state.partsByVarOffset == nil {
|
|
||||||
state.partsByVarOffset = &partsByVarOffset{}
|
|
||||||
}
|
|
||||||
for varID, n := range state.vars {
|
for varID, n := range state.vars {
|
||||||
parts := state.varParts[n]
|
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
|
state.varSlots[varID] = parts
|
||||||
for _, slotID := range parts {
|
for _, slotID := range parts {
|
||||||
state.slotVars[slotID] = VarID(varID)
|
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))
|
state.initializeCache(f, len(state.varParts), len(state.slots))
|
||||||
|
|
@ -1180,17 +1179,6 @@ func varOffset(slot LocalSlot) int64 {
|
||||||
return offset
|
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
|
// A pendingEntry represents the beginning of a location list entry, missing
|
||||||
// only its end coordinate.
|
// only its end coordinate.
|
||||||
type pendingEntry struct {
|
type pendingEntry struct {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package ssa
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
"cmp"
|
||||||
"fmt"
|
"fmt"
|
||||||
"html"
|
"html"
|
||||||
"io"
|
"io"
|
||||||
|
|
@ -827,19 +828,13 @@ type FuncLines struct {
|
||||||
Lines []string
|
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.
|
// followed by inlined functions sorted by filename and line numbers.
|
||||||
type ByTopo []*FuncLines
|
func ByTopoCmp(a, b *FuncLines) int {
|
||||||
|
if r := strings.Compare(a.Filename, b.Filename); r != 0 {
|
||||||
func (x ByTopo) Len() int { return len(x) }
|
return r
|
||||||
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
|
|
||||||
}
|
}
|
||||||
return a.Filename < b.Filename
|
return cmp.Compare(a.StartLineno, b.StartLineno)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteSources writes lines as source code in a column headed by title.
|
// WriteSources writes lines as source code in a column headed by title.
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"cmd/compile/internal/base"
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
"container/heap"
|
"container/heap"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -525,13 +526,13 @@ func storeOrder(values []*Value, sset *sparseSet, storeNumber []int32) []*Value
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if start != -1 {
|
if start != -1 {
|
||||||
sort.Sort(bySourcePos(order[start:i]))
|
slices.SortFunc(order[start:i], valuePosCmp)
|
||||||
start = -1
|
start = -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if 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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type bySourcePos []*Value
|
func valuePosCmp(a, b *Value) int {
|
||||||
|
if a.Pos.Before(b.Pos) {
|
||||||
func (s bySourcePos) Len() int { return len(s) }
|
return -1
|
||||||
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) }
|
if a.Pos.After(b.Pos) {
|
||||||
|
return +1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"internal/buildcfg"
|
"internal/buildcfg"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"cmd/compile/internal/abi"
|
"cmd/compile/internal/abi"
|
||||||
|
|
@ -789,7 +789,7 @@ func dumpSourcesColumn(writer *ssa.HTMLWriter, fn *ir.Func) {
|
||||||
inlFns = append(inlFns, fnLines)
|
inlFns = append(inlFns, fnLines)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(ssa.ByTopo(inlFns))
|
slices.SortFunc(inlFns, ssa.ByTopoCmp)
|
||||||
if targetFn != nil {
|
if targetFn != nil {
|
||||||
inlFns = append([]*ssa.FuncLines{targetFn}, inlFns...)
|
inlFns = append([]*ssa.FuncLines{targetFn}, inlFns...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ package typecheck
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"cmd/compile/internal/base"
|
"cmd/compile/internal/base"
|
||||||
|
|
@ -144,7 +144,7 @@ func CalcMethods(t *types.Type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ms = append(ms, t.Methods()...)
|
ms = append(ms, t.Methods()...)
|
||||||
sort.Sort(types.MethodsByName(ms))
|
slices.SortFunc(ms, types.MethodsByNameCmp)
|
||||||
t.SetAllMethods(ms)
|
t.SetAllMethods(ms)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"cmd/compile/internal/base"
|
"cmd/compile/internal/base"
|
||||||
|
|
@ -146,7 +147,7 @@ func expandiface(t *Type) {
|
||||||
m.Pos = src.NoXPos
|
m.Pos = src.NoXPos
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(MethodsByName(methods))
|
slices.SortFunc(methods, MethodsByNameCmp)
|
||||||
|
|
||||||
if int64(len(methods)) >= MaxWidth/int64(PtrSize) {
|
if int64(len(methods)) >= MaxWidth/int64(PtrSize) {
|
||||||
base.ErrorfAt(typePos(t), 0, "interface too large")
|
base.ErrorfAt(typePos(t), 0, "interface too large")
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,13 @@
|
||||||
|
|
||||||
package types
|
package types
|
||||||
|
|
||||||
// MethodsByName sorts methods by name.
|
// MethodsByNameCmp sorts methods by name.
|
||||||
type MethodsByName []*Field
|
func MethodsByNameCmp(x, y *Field) int {
|
||||||
|
if x.Sym.Less(y.Sym) {
|
||||||
func (x MethodsByName) Len() int { return len(x) }
|
return -1
|
||||||
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) }
|
if y.Sym.Less(x.Sym) {
|
||||||
|
return +1
|
||||||
// EmbeddedsByName sorts embedded types by name.
|
}
|
||||||
type EmbeddedsByName []*Field
|
return 0
|
||||||
|
}
|
||||||
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()) }
|
|
||||||
|
|
|
||||||
|
|
@ -716,6 +716,7 @@ func (check *Checker) packageObjects() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// inSourceOrder implements the sort.Sort interface.
|
// inSourceOrder implements the sort.Sort interface.
|
||||||
|
// TODO(gri) replace with slices.SortFunc
|
||||||
type inSourceOrder []Object
|
type inSourceOrder []Object
|
||||||
|
|
||||||
func (a inSourceOrder) Len() int { return len(a) }
|
func (a inSourceOrder) Len() int { return len(a) }
|
||||||
|
|
|
||||||
|
|
@ -360,6 +360,7 @@ func assertSortedMethods(list []*Func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// byUniqueMethodName method lists can be sorted by their unique method names.
|
// byUniqueMethodName method lists can be sorted by their unique method names.
|
||||||
|
// todo: replace with slices.SortFunc
|
||||||
type byUniqueMethodName []*Func
|
type byUniqueMethodName []*Func
|
||||||
|
|
||||||
func (a byUniqueMethodName) Len() int { return len(a) }
|
func (a byUniqueMethodName) Len() int { return len(a) }
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"cmd/internal/cov/covcmd"
|
"cmd/internal/cov/covcmd"
|
||||||
|
"cmp"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -20,7 +21,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
|
@ -975,12 +976,6 @@ type block1 struct {
|
||||||
index int
|
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.
|
// offset translates a token position into a 0-indexed byte offset.
|
||||||
func (f *File) offset(pos token.Pos) int {
|
func (f *File) offset(pos token.Pos) int {
|
||||||
return f.fset.Position(pos).Offset
|
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].Block = f.blocks[i]
|
||||||
t[i].index = 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++ {
|
for i := 1; i < len(t); i++ {
|
||||||
if t[i-1].endByte > t[i].startByte {
|
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)
|
fmt.Fprintf(os.Stderr, "cover: internal error: block %d overlaps block %d\n", t[i-1].index, t[i].index)
|
||||||
|
|
|
||||||
|
|
@ -20,20 +20,6 @@ type fix struct {
|
||||||
disabled bool // whether this fix should be disabled by default
|
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
|
var fixes []fix
|
||||||
|
|
||||||
func register(f fix) {
|
func register(f fix) {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import (
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"cmd/internal/telemetry/counter"
|
"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")
|
fmt.Fprintf(os.Stderr, "usage: go tool fix [-diff] [-r fixname,...] [-force fixname,...] [path ...]\n")
|
||||||
flag.PrintDefaults()
|
flag.PrintDefaults()
|
||||||
fmt.Fprintf(os.Stderr, "\nAvailable rewrites are:\n")
|
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 {
|
for _, f := range fixes {
|
||||||
if f.disabled {
|
if f.disabled {
|
||||||
fmt.Fprintf(os.Stderr, "\n%s (disabled)\n", f.name)
|
fmt.Fprintf(os.Stderr, "\n%s (disabled)\n", f.name)
|
||||||
|
|
@ -76,7 +78,9 @@ func main() {
|
||||||
os.Exit(exitCode)
|
os.Exit(exitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(byDate(fixes))
|
slices.SortFunc(fixes, func(a, b fix) int {
|
||||||
|
return strings.Compare(a.date, b.date)
|
||||||
|
})
|
||||||
|
|
||||||
if *allowedRewrites != "" {
|
if *allowedRewrites != "" {
|
||||||
allowed = make(map[string]bool)
|
allowed = make(map[string]bool)
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,12 @@ package dwarf
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
|
"cmp"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"internal/buildcfg"
|
"internal/buildcfg"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"sort"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -1112,7 +1113,7 @@ func putPrunedScopes(ctxt Context, s *FnState, fnabbrev int) error {
|
||||||
pruned.Vars = append(pruned.Vars, s.Vars[i])
|
pruned.Vars = append(pruned.Vars, s.Vars[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Sort(byChildIndex(pruned.Vars))
|
slices.SortFunc(pruned.Vars, byChildIndexCmp)
|
||||||
scopes[k] = pruned
|
scopes[k] = pruned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1181,7 +1182,7 @@ func PutAbstractFunc(ctxt Context, s *FnState) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(flattened) > 0 {
|
if len(flattened) > 0 {
|
||||||
sort.Sort(byChildIndex(flattened))
|
slices.SortFunc(flattened, byChildIndexCmp)
|
||||||
|
|
||||||
if logDwarf {
|
if logDwarf {
|
||||||
ctxt.Logf("putAbstractScope(%v): vars:", s.Info)
|
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.
|
// Variables associated with this inlined routine instance.
|
||||||
vars := ic.InlVars
|
vars := ic.InlVars
|
||||||
sort.Sort(byChildIndex(vars))
|
slices.SortFunc(vars, byChildIndexCmp)
|
||||||
inlIndex := ic.InlIndex
|
inlIndex := ic.InlIndex
|
||||||
var encbuf [20]byte
|
var encbuf [20]byte
|
||||||
for _, v := range vars {
|
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
|
// Var has no children => no terminator
|
||||||
}
|
}
|
||||||
|
|
||||||
// byChildIndex implements sort.Interface for []*dwarf.Var by child index.
|
// byChildIndexCmp compares two *dwarf.Var by child index.
|
||||||
type byChildIndex []*Var
|
func byChildIndexCmp(a, b *Var) int { return cmp.Compare(a.ChildIndex, b.ChildIndex) }
|
||||||
|
|
||||||
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] }
|
|
||||||
|
|
||||||
// IsDWARFEnabledOnAIXLd returns true if DWARF is possible on the
|
// IsDWARFEnabledOnAIXLd returns true if DWARF is possible on the
|
||||||
// current extld.
|
// current extld.
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ import (
|
||||||
"internal/buildcfg"
|
"internal/buildcfg"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ctxt5 holds state while assembling a single function.
|
// ctxt5 holds state while assembling a single function.
|
||||||
|
|
@ -1203,36 +1203,20 @@ func cmp(a int, b int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type ocmp []Optab
|
func ocmp(a, b Optab) int {
|
||||||
|
if a.as != b.as {
|
||||||
func (x ocmp) Len() int {
|
return int(a.as) - int(b.as)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
n = int(p1.a1) - int(p2.a1)
|
if a.a1 != b.a1 {
|
||||||
if n != 0 {
|
return int(a.a1) - int(b.a1)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
n = int(p1.a2) - int(p2.a2)
|
if a.a2 != b.a2 {
|
||||||
if n != 0 {
|
return int(a.a2) - int(b.a2)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
n = int(p1.a3) - int(p2.a3)
|
if a.a3 != b.a3 {
|
||||||
if n != 0 {
|
return int(a.a3) - int(b.a3)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
return false
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func opset(a, b0 obj.As) {
|
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++ {
|
for i := 0; i < n; i++ {
|
||||||
r := optab[i].as
|
r := optab[i].as
|
||||||
r0 := r & obj.AMask
|
r0 := r & obj.AMask
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -2700,38 +2700,26 @@ func cmp(a int, b int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type ocmp []Optab
|
func ocmp(p1, p2 Optab) int {
|
||||||
|
|
||||||
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]
|
|
||||||
if p1.as != p2.as {
|
if p1.as != p2.as {
|
||||||
return p1.as < p2.as
|
return int(p1.as) - int(p2.as)
|
||||||
}
|
}
|
||||||
if p1.a1 != p2.a1 {
|
if p1.a1 != p2.a1 {
|
||||||
return p1.a1 < p2.a1
|
return int(p1.a1) - int(p2.a1)
|
||||||
}
|
}
|
||||||
if p1.a2 != p2.a2 {
|
if p1.a2 != p2.a2 {
|
||||||
return p1.a2 < p2.a2
|
return int(p1.a2) - int(p2.a2)
|
||||||
}
|
}
|
||||||
if p1.a3 != p2.a3 {
|
if p1.a3 != p2.a3 {
|
||||||
return p1.a3 < p2.a3
|
return int(p1.a3) - int(p2.a3)
|
||||||
}
|
}
|
||||||
if p1.a4 != p2.a4 {
|
if p1.a4 != p2.a4 {
|
||||||
return p1.a4 < p2.a4
|
return int(p1.a4) - int(p2.a4)
|
||||||
}
|
}
|
||||||
if p1.scond != p2.scond {
|
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) {
|
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++ {
|
for i := 0; i < len(optab); i++ {
|
||||||
as, start := optab[i].as, i
|
as, start := optab[i].as, i
|
||||||
for ; i < len(optab)-1; i++ {
|
for ; i < len(optab)-1; i++ {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"slices"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -665,7 +666,9 @@ func (ft *DwarfFixupTable) Finalize(myimportpath string, trace bool) {
|
||||||
fns[idx] = fn
|
fns[idx] = fn
|
||||||
idx++
|
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.
|
// Should not be called during parallel portion of compilation.
|
||||||
if ft.ctxt.InParallel {
|
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] }
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"sort"
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ctxt0 holds state while assembling a single function.
|
// ctxt0 holds state while assembling a single function.
|
||||||
|
|
@ -964,36 +964,20 @@ func cmp(a int, b int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type ocmp []Optab
|
func ocmp(p1, p2 Optab) int {
|
||||||
|
if p1.as != p2.as {
|
||||||
func (x ocmp) Len() int {
|
return int(p1.as) - int(p2.as)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
n = int(p1.from1) - int(p2.from1)
|
if p1.from1 != p2.from1 {
|
||||||
if n != 0 {
|
return int(p1.from1) - int(p2.from1)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
n = int(p1.reg) - int(p2.reg)
|
if p1.reg != p2.reg {
|
||||||
if n != 0 {
|
return int(p1.reg) - int(p2.reg)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
n = int(p1.to1) - int(p2.to1)
|
if p1.to1 != p2.to1 {
|
||||||
if n != 0 {
|
return int(p1.to1) - int(p2.to1)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
return false
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func opset(a, b0 obj.As) {
|
func opset(a, b0 obj.As) {
|
||||||
|
|
@ -1025,7 +1009,7 @@ func buildop(ctxt *obj.Link) {
|
||||||
}
|
}
|
||||||
for n = 0; optab[n].as != obj.AXXX; n++ {
|
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++ {
|
for i := 0; i < n; i++ {
|
||||||
r := optab[i].as
|
r := optab[i].as
|
||||||
r0 := r & obj.AMask
|
r0 := r & obj.AMask
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import (
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"sort"
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ctxt0 holds state while assembling a single function.
|
// ctxt0 holds state while assembling a single function.
|
||||||
|
|
@ -875,36 +875,20 @@ func cmp(a int, b int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type ocmp []Optab
|
func ocmp(p1, p2 Optab) int {
|
||||||
|
if p1.as != p2.as {
|
||||||
func (x ocmp) Len() int {
|
return int(p1.as) - int(p2.as)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
n = int(p1.a1) - int(p2.a1)
|
if p1.a1 != p2.a1 {
|
||||||
if n != 0 {
|
return int(p1.a1) - int(p2.a1)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
n = int(p1.a2) - int(p2.a2)
|
if p1.a2 != p2.a2 {
|
||||||
if n != 0 {
|
return int(p1.a2) - int(p2.a2)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
n = int(p1.a3) - int(p2.a3)
|
if p1.a3 != p2.a3 {
|
||||||
if n != 0 {
|
return int(p1.a3) - int(p2.a3)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
return false
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func opset(a, b0 obj.As) {
|
func opset(a, b0 obj.As) {
|
||||||
|
|
@ -930,7 +914,7 @@ func buildop(ctxt *obj.Link) {
|
||||||
}
|
}
|
||||||
for n = 0; optab[n].as != obj.AXXX; n++ {
|
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++ {
|
for i := 0; i < n; i++ {
|
||||||
r := optab[i].as
|
r := optab[i].as
|
||||||
r0 := r & obj.AMask
|
r0 := r & obj.AMask
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"cmd/internal/notsha256"
|
"cmd/internal/notsha256"
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
|
"cmp"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"internal/abi"
|
"internal/abi"
|
||||||
|
|
@ -20,6 +21,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -177,7 +179,7 @@ func WriteObjFile(ctxt *Link, b *bio.Writer) {
|
||||||
h.Offsets[goobj.BlkReloc] = w.Offset()
|
h.Offsets[goobj.BlkReloc] = w.Offset()
|
||||||
for _, list := range lists {
|
for _, list := range lists {
|
||||||
for _, s := range list {
|
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 {
|
for i := range s.R {
|
||||||
w.Reloc(&s.R[i])
|
w.Reloc(&s.R[i])
|
||||||
}
|
}
|
||||||
|
|
@ -935,7 +937,7 @@ func (ctxt *Link) writeSymDebugNamed(s *LSym, name string) {
|
||||||
fmt.Fprintf(ctxt.Bso, "\n")
|
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 {
|
for _, r := range s.R {
|
||||||
name := ""
|
name := ""
|
||||||
ver := ""
|
ver := ""
|
||||||
|
|
@ -955,9 +957,7 @@ func (ctxt *Link) writeSymDebugNamed(s *LSym, name string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// relocByOff sorts relocations by their offsets.
|
// relocByOffCmp compare relocations by their offsets.
|
||||||
type relocByOff []Reloc
|
func relocByOffCmp(x, y Reloc) int {
|
||||||
|
return cmp.Compare(x.Off, y.Off)
|
||||||
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] }
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ctxtz holds state while assembling a single function.
|
// ctxtz holds state while assembling a single function.
|
||||||
|
|
@ -853,40 +853,23 @@ func cmp(a int, b int) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
type ocmp []Optab
|
func ocmp(p1, p2 Optab) int {
|
||||||
|
if p1.as != p2.as {
|
||||||
func (x ocmp) Len() int {
|
return int(p1.as) - int(p2.as)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
n = int(p1.a1) - int(p2.a1)
|
if p1.a1 != p2.a1 {
|
||||||
if n != 0 {
|
return int(p1.a1) - int(p2.a1)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
n = int(p1.a2) - int(p2.a2)
|
if p1.a2 != p2.a2 {
|
||||||
if n != 0 {
|
return int(p1.a2) - int(p2.a2)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
n = int(p1.a3) - int(p2.a3)
|
if p1.a3 != p2.a3 {
|
||||||
if n != 0 {
|
return int(p1.a3) - int(p2.a3)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
n = int(p1.a4) - int(p2.a4)
|
if p1.a4 != p2.a4 {
|
||||||
if n != 0 {
|
return int(p1.a4) - int(p2.a4)
|
||||||
return n < 0
|
|
||||||
}
|
}
|
||||||
return false
|
return 0
|
||||||
}
|
}
|
||||||
func opset(a, b obj.As) {
|
func opset(a, b obj.As) {
|
||||||
oprange[a&obj.AMask] = oprange[b&obj.AMask]
|
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++ {
|
for i := 0; i < len(optab); i++ {
|
||||||
r := optab[i].as
|
r := optab[i].as
|
||||||
start := i
|
start := i
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"debug/macho"
|
"debug/macho"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -42,7 +43,7 @@ func (f *machoFile) symbols() ([]Sym, error) {
|
||||||
addrs = append(addrs, s.Value)
|
addrs = append(addrs, s.Value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sort.Sort(uint64s(addrs))
|
slices.Sort(addrs)
|
||||||
|
|
||||||
var syms []Sym
|
var syms []Sym
|
||||||
for _, s := range f.macho.Symtab.Syms {
|
for _, s := range f.macho.Symtab.Syms {
|
||||||
|
|
@ -121,12 +122,6 @@ func (f *machoFile) goarch() string {
|
||||||
return ""
|
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) {
|
func (f *machoFile) loadAddress() (uint64, error) {
|
||||||
if seg := f.macho.Segment("__TEXT"); seg != nil {
|
if seg := f.macho.Segment("__TEXT"); seg != nil {
|
||||||
return seg.Addr, nil
|
return seg.Addr, nil
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,13 @@ package objfile
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/archive"
|
"cmd/internal/archive"
|
||||||
|
"cmp"
|
||||||
"debug/dwarf"
|
"debug/dwarf"
|
||||||
"debug/gosym"
|
"debug/gosym"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
type rawFile interface {
|
type rawFile interface {
|
||||||
|
|
@ -131,16 +132,12 @@ func (e *Entry) Symbols() ([]Sym, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
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) {
|
func (e *Entry) PCLineTable() (Liner, error) {
|
||||||
// If the raw file implements Liner directly, use that.
|
// If the raw file implements Liner directly, use that.
|
||||||
// Currently, only Go intermediate objects and archives (goobj) use this path.
|
// Currently, only Go intermediate objects and archives (goobj) use this path.
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"debug/pe"
|
"debug/pe"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -78,7 +79,7 @@ func (f *peFile) symbols() ([]Sym, error) {
|
||||||
addrs = append(addrs, sym.Addr)
|
addrs = append(addrs, sym.Addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(uint64s(addrs))
|
slices.Sort(addrs)
|
||||||
for i := range syms {
|
for i := range syms {
|
||||||
j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
|
j := sort.Search(len(addrs), func(x int) bool { return addrs[x] > syms[i].Addr })
|
||||||
if j < len(addrs) {
|
if j < len(addrs) {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -51,7 +52,7 @@ func (f *plan9File) symbols() ([]Sym, error) {
|
||||||
}
|
}
|
||||||
addrs = append(addrs, s.Value)
|
addrs = append(addrs, s.Value)
|
||||||
}
|
}
|
||||||
sort.Sort(uint64s(addrs))
|
slices.Sort(addrs)
|
||||||
|
|
||||||
var syms []Sym
|
var syms []Sym
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,14 @@ import (
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/loader"
|
"cmd/link/internal/loader"
|
||||||
"cmd/link/internal/sym"
|
"cmd/link/internal/sym"
|
||||||
|
"cmp"
|
||||||
"fmt"
|
"fmt"
|
||||||
"internal/abi"
|
"internal/abi"
|
||||||
"internal/buildcfg"
|
"internal/buildcfg"
|
||||||
"log"
|
"log"
|
||||||
"path"
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
@ -2090,7 +2091,7 @@ func (d *dwctxt) dwarfGenerateDebugSyms() {
|
||||||
abbrevSec := d.writeabbrev()
|
abbrevSec := d.writeabbrev()
|
||||||
dwarfp = append(dwarfp, abbrevSec)
|
dwarfp = append(dwarfp, abbrevSec)
|
||||||
d.calcCompUnitRanges()
|
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.
|
// newdie adds DIEs to the *beginning* of the parent's DIE list.
|
||||||
// Now that we're done creating DIEs, reverse the trees so DIEs
|
// 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
|
Segdwarf.Length = pos - Segdwarf.Vaddr
|
||||||
}
|
}
|
||||||
|
|
||||||
type compilationUnitByStartPC []*sym.CompilationUnit
|
func compilationUnitByStartPCCmp(a, b *sym.CompilationUnit) int {
|
||||||
|
|
||||||
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 {
|
|
||||||
switch {
|
switch {
|
||||||
case len(v[i].Textp) == 0 && len(v[j].Textp) == 0:
|
case len(a.Textp) == 0 && len(b.Textp) == 0:
|
||||||
return v[i].Lib.Pkg < v[j].Lib.Pkg
|
return strings.Compare(a.Lib.Pkg, b.Lib.Pkg)
|
||||||
case len(v[i].Textp) != 0 && len(v[j].Textp) == 0:
|
case len(a.Textp) != 0 && len(b.Textp) == 0:
|
||||||
return true
|
return -1
|
||||||
case len(v[i].Textp) == 0 && len(v[j].Textp) != 0:
|
case len(a.Textp) == 0 && len(b.Textp) != 0:
|
||||||
return false
|
return +1
|
||||||
default:
|
default:
|
||||||
return v[i].PCs[0].Start < v[j].PCs[0].Start
|
return cmp.Compare(a.PCs[0].Start, b.PCs[0].Start)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sort"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1678,8 +1678,9 @@ func (ctxt *Link) doelf() {
|
||||||
ldr.SetAttrSpecial(s, true)
|
ldr.SetAttrSpecial(s, true)
|
||||||
sb.SetReachable(true)
|
sb.SetReachable(true)
|
||||||
sb.SetSize(notsha256.Size)
|
sb.SetSize(notsha256.Size)
|
||||||
|
slices.SortFunc(ctxt.Library, func(a, b *sym.Library) int {
|
||||||
sort.Sort(byPkg(ctxt.Library))
|
return strings.Compare(a.Pkg, b.Pkg)
|
||||||
|
})
|
||||||
h := notsha256.New()
|
h := notsha256.New()
|
||||||
for _, l := range ctxt.Library {
|
for _, l := range ctxt.Library {
|
||||||
h.Write(l.Fingerprint[:])
|
h.Write(l.Fingerprint[:])
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"internal/buildcfg"
|
"internal/buildcfg"
|
||||||
"math"
|
"math"
|
||||||
|
"slices"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -1490,10 +1491,6 @@ type peBaseRelocBlock struct {
|
||||||
// it can be sorted.
|
// it can be sorted.
|
||||||
type pePages []uint32
|
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
|
// A PE base relocation table is a list of blocks, where each block
|
||||||
// contains relocation information for a single page. The blocks
|
// contains relocation information for a single page. The blocks
|
||||||
// must be emitted in order of page virtual address.
|
// must be emitted in order of page virtual address.
|
||||||
|
|
@ -1547,7 +1544,7 @@ func (rt *peBaseRelocTable) write(ctxt *Link) {
|
||||||
out := ctxt.Out
|
out := ctxt.Out
|
||||||
|
|
||||||
// sort the pages array
|
// sort the pages array
|
||||||
sort.Sort(rt.pages)
|
slices.Sort(rt.pages)
|
||||||
|
|
||||||
// .reloc section must be 32-bit aligned
|
// .reloc section must be 32-bit aligned
|
||||||
if out.Offset()&3 != 0 {
|
if out.Offset()&3 != 0 {
|
||||||
|
|
|
||||||
|
|
@ -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.
|
// Create a table with information on the text sections.
|
||||||
// Return the symbol of the table, and number of sections.
|
// Return the symbol of the table, and number of sections.
|
||||||
func textsectionmap(ctxt *Link) (loader.Sym, uint32) {
|
func textsectionmap(ctxt *Link) (loader.Sym, uint32) {
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,21 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/link/internal/loader"
|
"cmd/link/internal/loader"
|
||||||
"cmd/link/internal/sym"
|
"cmd/link/internal/sym"
|
||||||
"sort"
|
"slices"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type byTypeStr []typelinkSortKey
|
|
||||||
|
|
||||||
type typelinkSortKey struct {
|
type typelinkSortKey struct {
|
||||||
TypeStr string
|
TypeStr string
|
||||||
Type loader.Sym
|
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().
|
// typelink generates the typelink table which is used by reflect.typelinks().
|
||||||
// Types that should be added to the typelinks table are marked with the
|
// Types that should be added to the typelinks table are marked with the
|
||||||
// MakeTypelink attribute by the compiler.
|
// MakeTypelink attribute by the compiler.
|
||||||
func (ctxt *Link) typelink() {
|
func (ctxt *Link) typelink() {
|
||||||
ldr := ctxt.loader
|
ldr := ctxt.loader
|
||||||
typelinks := byTypeStr{}
|
var typelinks []typelinkSortKey
|
||||||
var itabs []loader.Sym
|
var itabs []loader.Sym
|
||||||
for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
|
for s := loader.Sym(1); s < loader.Sym(ldr.NSym()); s++ {
|
||||||
if !ldr.AttrReachable(s) {
|
if !ldr.AttrReachable(s) {
|
||||||
|
|
@ -39,7 +34,9 @@ func (ctxt *Link) typelink() {
|
||||||
itabs = append(itabs, 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 := ldr.CreateSymForUpdate("runtime.typelink", 0)
|
||||||
tl.SetType(sym.STYPELINK)
|
tl.SetType(sym.STYPELINK)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ import (
|
||||||
"cmd/internal/objabi"
|
"cmd/internal/objabi"
|
||||||
"cmd/internal/sys"
|
"cmd/internal/sys"
|
||||||
"cmd/link/internal/sym"
|
"cmd/link/internal/sym"
|
||||||
"sort"
|
"cmp"
|
||||||
|
"slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SymbolBuilder is a helper designed to help with the construction
|
// 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
|
return relocs.At(j), j
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort relocations by offset.
|
// SortRelocs Sort relocations by offset.
|
||||||
func (sb *SymbolBuilder) SortRelocs() {
|
func (sb *SymbolBuilder) SortRelocs() {
|
||||||
sort.Sort((*relocsByOff)(sb.extSymPayload))
|
slices.SortFunc(sb.extSymPayload.relocs, func(a, b goobj.Reloc) int {
|
||||||
}
|
return cmp.Compare(a.Off(), b.Off())
|
||||||
|
})
|
||||||
// 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]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sb *SymbolBuilder) Reachable() bool {
|
func (sb *SymbolBuilder) Reachable() bool {
|
||||||
|
|
|
||||||
|
|
@ -713,6 +713,7 @@ func (check *Checker) packageObjects() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// inSourceOrder implements the sort.Sort interface.
|
// inSourceOrder implements the sort.Sort interface.
|
||||||
|
// TODO(gri) replace with slices.SortFunc
|
||||||
type inSourceOrder []Object
|
type inSourceOrder []Object
|
||||||
|
|
||||||
func (a inSourceOrder) Len() int { return len(a) }
|
func (a inSourceOrder) Len() int { return len(a) }
|
||||||
|
|
|
||||||
|
|
@ -363,6 +363,7 @@ func assertSortedMethods(list []*Func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// byUniqueMethodName method lists can be sorted by their unique method names.
|
// byUniqueMethodName method lists can be sorted by their unique method names.
|
||||||
|
// todo: replace with slices.SortFunc
|
||||||
type byUniqueMethodName []*Func
|
type byUniqueMethodName []*Func
|
||||||
|
|
||||||
func (a byUniqueMethodName) Len() int { return len(a) }
|
func (a byUniqueMethodName) Len() int { return len(a) }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue