summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Bleecher Snyder <josharian@gmail.com>2017-04-09 15:02:35 -0700
committerJosh Bleecher Snyder <josharian@gmail.com>2017-04-11 20:29:04 +0000
commit826a09cd65bbbf39bd377f34e24a5870275014ad (patch)
treed0276bc5f38d761b64ccb7bd2dd8155fe47dc521
parentd6dd7ce1c5eb0df4694f9f8ad09dc47d8d689690 (diff)
downloadgo-git-826a09cd65bbbf39bd377f34e24a5870275014ad.tar.gz
cmd/internal/obj: add SortSlice
sort.Slice was added in Go 1.8. It's nice to use, and faster than sort.Sort, so it'd be nice to be able to use it in the toolchain. This CL adds obj.SortSlice, which is sort.Slice, but with a slower fallback version for bootstrapping. This CL also includes a single demo+test use. Change-Id: I2accc60b61f8e48c8ab4f1a63473e3b87af9b691 Reviewed-on: https://go-review.googlesource.com/40114 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
-rw-r--r--src/cmd/compile/internal/gc/reflect.go13
-rw-r--r--src/cmd/compile/internal/gc/reflect_test.go7
-rw-r--r--src/cmd/internal/obj/bootstrap.go34
-rw-r--r--src/cmd/internal/obj/sort.go13
4 files changed, 52 insertions, 15 deletions
diff --git a/src/cmd/compile/internal/gc/reflect.go b/src/cmd/compile/internal/gc/reflect.go
index 66af2bf01c..9597aa893d 100644
--- a/src/cmd/compile/internal/gc/reflect.go
+++ b/src/cmd/compile/internal/gc/reflect.go
@@ -49,16 +49,7 @@ type Sig struct {
offset int32
}
-// byMethodNameAndPackagePath sorts method signatures by name, then package path.
-type byMethodNameAndPackagePath []*Sig
-
-func (x byMethodNameAndPackagePath) Len() int { return len(x) }
-func (x byMethodNameAndPackagePath) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-func (x byMethodNameAndPackagePath) Less(i, j int) bool {
- return siglt(x[i], x[j])
-}
-
-// siglt reports whether a < b
+// siglt sorts method signatures by name, then package path.
func siglt(a, b *Sig) bool {
if a.name != b.name {
return a.name < b.name
@@ -382,7 +373,7 @@ func methods(t *types.Type) []*Sig {
}
}
- sort.Sort(byMethodNameAndPackagePath(ms))
+ obj.SortSlice(ms, func(i, j int) bool { return siglt(ms[i], ms[j]) })
return ms
}
diff --git a/src/cmd/compile/internal/gc/reflect_test.go b/src/cmd/compile/internal/gc/reflect_test.go
index ad3cad73c0..fe6dcf0d2e 100644
--- a/src/cmd/compile/internal/gc/reflect_test.go
+++ b/src/cmd/compile/internal/gc/reflect_test.go
@@ -6,12 +6,12 @@ package gc
import (
"cmd/compile/internal/types"
+ "cmd/internal/obj"
"reflect"
- "sort"
"testing"
)
-func TestSortingByMethodNameAndPackagePath(t *testing.T) {
+func TestSortingBySigLT(t *testing.T) {
data := []*Sig{
&Sig{name: "b", pkg: &types.Pkg{Path: "abc"}},
&Sig{name: "b", pkg: nil},
@@ -38,11 +38,10 @@ func TestSortingByMethodNameAndPackagePath(t *testing.T) {
if reflect.DeepEqual(data, want) {
t.Fatal("data must be shuffled")
}
- sort.Sort(byMethodNameAndPackagePath(data))
+ obj.SortSlice(data, func(i, j int) bool { return siglt(data[i], data[j]) })
if !reflect.DeepEqual(data, want) {
t.Logf("want: %#v", want)
t.Logf("data: %#v", data)
t.Errorf("sorting failed")
}
-
}
diff --git a/src/cmd/internal/obj/bootstrap.go b/src/cmd/internal/obj/bootstrap.go
new file mode 100644
index 0000000000..42835e1d9d
--- /dev/null
+++ b/src/cmd/internal/obj/bootstrap.go
@@ -0,0 +1,34 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.8
+
+package obj
+
+import (
+ "reflect"
+ "sort"
+)
+
+func SortSlice(slice interface{}, less func(i, j int) bool) {
+ val := reflect.ValueOf(slice)
+ tmp := reflect.New(val.Type().Elem()).Elem()
+ x := sliceByFn{val: val, tmp: tmp, less: less}
+ sort.Sort(x)
+}
+
+type sliceByFn struct {
+ val reflect.Value
+ tmp reflect.Value
+ less func(i, j int) bool
+}
+
+func (x sliceByFn) Len() int { return x.val.Len() }
+func (x sliceByFn) Less(i, j int) bool { return x.less(i, j) }
+func (x sliceByFn) Swap(i, j int) {
+ a, b := x.val.Index(i), x.val.Index(j)
+ x.tmp.Set(a)
+ a.Set(b)
+ b.Set(x.tmp)
+}
diff --git a/src/cmd/internal/obj/sort.go b/src/cmd/internal/obj/sort.go
new file mode 100644
index 0000000000..0cb801ee98
--- /dev/null
+++ b/src/cmd/internal/obj/sort.go
@@ -0,0 +1,13 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.8
+
+package obj
+
+import "sort"
+
+func SortSlice(slice interface{}, less func(i, j int) bool) {
+ sort.Slice(slice, less)
+}