Skip to content

Commit d1341d6

Browse files
committed
cmd/compile, runtime: eliminate growslice_n
Fixes #11419. Change-Id: I7935a253e3e96191a33f5041bab203ecc5f0c976 Reviewed-on: https://go-review.googlesource.com/20647 Reviewed-by: Keith Randall <[email protected]>
1 parent 8ec8017 commit d1341d6

File tree

4 files changed

+29
-42
lines changed

4 files changed

+29
-42
lines changed

src/cmd/compile/internal/gc/builtin.go

-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ const runtimeimport = "" +
128128
"func @\"\".block ()\n" +
129129
"func @\"\".makeslice (@\"\".typ·2 *byte, @\"\".nel·3 int64, @\"\".cap·4 int64) (@\"\".ary·1 []any)\n" +
130130
"func @\"\".growslice (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".cap·4 int) (@\"\".ary·1 []any)\n" +
131-
"func @\"\".growslice_n (@\"\".typ·2 *byte, @\"\".old·3 []any, @\"\".n·4 int) (@\"\".ary·1 []any)\n" +
132131
"func @\"\".memmove (@\"\".to·1 *any, @\"\".frm·2 *any, @\"\".length·3 uintptr \"unsafe-uintptr\")\n" +
133132
"func @\"\".memclr (@\"\".ptr·1 *byte, @\"\".length·2 uintptr \"unsafe-uintptr\")\n" +
134133
"func @\"\".memequal (@\"\".x·2 *any, @\"\".y·3 *any, @\"\".size·4 uintptr \"unsafe-uintptr\") (? bool)\n" +

src/cmd/compile/internal/gc/builtin/runtime.go

-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ func block()
165165

166166
func makeslice(typ *byte, nel int64, cap int64) (ary []any)
167167
func growslice(typ *byte, old []any, cap int) (ary []any)
168-
func growslice_n(typ *byte, old []any, n int) (ary []any)
169168
func memmove(to *any, frm *any, length uintptr)
170169
func memclr(ptr *byte, length uintptr)
171170

src/cmd/compile/internal/gc/walk.go

+29-29
Original file line numberDiff line numberDiff line change
@@ -2777,10 +2777,12 @@ func addstr(n *Node, init *Nodes) *Node {
27772777
// expand append(l1, l2...) to
27782778
// init {
27792779
// s := l1
2780-
// if n := len(l1) + len(l2) - cap(s); n > 0 {
2781-
// s = growslice_n(s, n)
2780+
// n := len(s) + len(l2)
2781+
// // Compare as uint so growslice can panic on overflow.
2782+
// if uint(n) > uint(cap(s)) {
2783+
// s = growslice(s, n)
27822784
// }
2783-
// s = s[:len(l1)+len(l2)]
2785+
// s = s[:n]
27842786
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
27852787
// }
27862788
// s
@@ -2800,33 +2802,38 @@ func appendslice(n *Node, init *Nodes) *Node {
28002802
l1 := n.List.First()
28012803
l2 := n.List.Second()
28022804

2803-
s := temp(l1.Type) // var s []T
28042805
var l []*Node
2806+
2807+
// var s []T
2808+
s := temp(l1.Type)
28052809
l = append(l, Nod(OAS, s, l1)) // s = l1
28062810

2807-
nt := temp(Types[TINT])
2811+
// n := len(s) + len(l2)
2812+
nn := temp(Types[TINT])
2813+
l = append(l, Nod(OAS, nn, Nod(OADD, Nod(OLEN, s, nil), Nod(OLEN, l2, nil))))
28082814

2815+
// if uint(n) > uint(cap(s))
28092816
nif := Nod(OIF, nil, nil)
2817+
nif.Left = Nod(OGT, Nod(OCONV, nn, nil), Nod(OCONV, Nod(OCAP, s, nil), nil))
2818+
nif.Left.Left.Type = Types[TUINT]
2819+
nif.Left.Right.Type = Types[TUINT]
28102820

2811-
// n := len(s) + len(l2) - cap(s)
2812-
nif.Ninit.Set1(Nod(OAS, nt, Nod(OSUB,
2813-
Nod(OADD, Nod(OLEN, s, nil), Nod(OLEN, l2, nil)),
2814-
Nod(OCAP, s, nil))))
2815-
2816-
nif.Left = Nod(OGT, nt, Nodintconst(0))
2817-
2818-
// instantiate growslice_n(Type*, []any, int) []any
2819-
fn := syslook("growslice_n") // growslice_n(<type>, old []T, n int64) (ret []T)
2821+
// instantiate growslice(Type*, []any, int) []any
2822+
fn := syslook("growslice")
28202823
substArgTypes(&fn, s.Type.Type, s.Type.Type)
28212824

2822-
// s = growslice_n(T, s, n)
2823-
nif.Nbody.Set1(Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, nt)))
2824-
2825+
// s = growslice(T, s, n)
2826+
nif.Nbody.Set1(Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, nn)))
28252827
l = append(l, nif)
28262828

2829+
// s = s[:n]
2830+
nt := Nod(OSLICE, s, Nod(OKEY, nil, nn))
2831+
nt.Etype = 1
2832+
l = append(l, Nod(OAS, s, nt))
2833+
28272834
if haspointers(l1.Type.Type) {
2828-
// copy(s[len(l1):len(l1)+len(l2)], l2)
2829-
nptr1 := Nod(OSLICE, s, Nod(OKEY, Nod(OLEN, l1, nil), Nod(OADD, Nod(OLEN, l1, nil), Nod(OLEN, l2, nil))))
2835+
// copy(s[len(l1):], l2)
2836+
nptr1 := Nod(OSLICE, s, Nod(OKEY, Nod(OLEN, l1, nil), nil))
28302837

28312838
nptr1.Etype = 1
28322839
nptr2 := l2
@@ -2838,8 +2845,8 @@ func appendslice(n *Node, init *Nodes) *Node {
28382845
l = append(ln.Slice(), nt)
28392846
} else if instrumenting {
28402847
// rely on runtime to instrument copy.
2841-
// copy(s[len(l1):len(l1)+len(l2)], l2)
2842-
nptr1 := Nod(OSLICE, s, Nod(OKEY, Nod(OLEN, l1, nil), Nod(OADD, Nod(OLEN, l1, nil), Nod(OLEN, l2, nil))))
2848+
// copy(s[len(l1):], l2)
2849+
nptr1 := Nod(OSLICE, s, Nod(OKEY, Nod(OLEN, l1, nil), nil))
28432850

28442851
nptr1.Etype = 1
28452852
nptr2 := l2
@@ -2857,8 +2864,8 @@ func appendslice(n *Node, init *Nodes) *Node {
28572864
} else {
28582865
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
28592866
nptr1 := Nod(OINDEX, s, Nod(OLEN, l1, nil))
2860-
28612867
nptr1.Bounded = true
2868+
28622869
nptr1 = Nod(OADDR, nptr1, nil)
28632870

28642871
nptr2 := Nod(OSPTR, l2, nil)
@@ -2875,13 +2882,6 @@ func appendslice(n *Node, init *Nodes) *Node {
28752882
l = append(ln.Slice(), nt)
28762883
}
28772884

2878-
// s = s[:len(l1)+len(l2)]
2879-
nt = Nod(OADD, Nod(OLEN, l1, nil), Nod(OLEN, l2, nil))
2880-
2881-
nt = Nod(OSLICE, s, Nod(OKEY, nil, nt))
2882-
nt.Etype = 1
2883-
l = append(l, Nod(OAS, s, nt))
2884-
28852885
typechecklist(l, Etop)
28862886
walkstmtlist(l)
28872887
init.Append(l...)

src/runtime/slice.go

-11
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,6 @@ func makeslice(t *slicetype, len64, cap64 int64) slice {
3333
return slice{p, len, cap}
3434
}
3535

36-
// growslice_n is a variant of growslice that takes the number of new elements
37-
// instead of the new minimum capacity.
38-
// TODO(rsc): This is used by append(slice, slice...).
39-
// The compiler should change that code to use growslice directly (issue #11419).
40-
func growslice_n(t *slicetype, old slice, n int) slice {
41-
if n < 1 {
42-
panic(errorString("growslice: invalid n"))
43-
}
44-
return growslice(t, old, old.cap+n)
45-
}
46-
4736
// growslice handles slice growth during append.
4837
// It is passed the slice type, the old slice, and the desired new minimum capacity,
4938
// and it returns a new slice with at least that capacity, with the old data

0 commit comments

Comments
 (0)