Skip to content

Commit 77f5adb

Browse files
cuonglmrandall77
authored andcommitted
cmd/compile: don't use statictmps for small object in slice literal
Fixes golang#21561 Change-Id: I89c59752060dd9570d17d73acbbaceaefce5d8ce Reviewed-on: https://go-review.googlesource.com/c/go/+/197560 Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
1 parent ecba835 commit 77f5adb

File tree

3 files changed

+68
-1
lines changed

3 files changed

+68
-1
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ var (
2929
// s := []byte("...") allocating [n]byte on the stack
3030
// Note: the flag smallframes can update this value.
3131
maxImplicitStackVarSize = int64(64 * 1024)
32+
33+
// smallArrayBytes is the maximum size of an array which is considered small.
34+
// Small arrays will be initialized directly with a sequence of constant stores.
35+
// Large arrays will be initialized by copying from a static temp.
36+
// 256 bytes was chosen to minimize generated code + statictmp size.
37+
smallArrayBytes = int64(256)
3238
)
3339

3440
// isRuntimePkg reports whether p is package runtime.

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,16 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
582582
}
583583
}
584584

585+
func isSmallSliceLit(n *Node) bool {
586+
if n.Op != OSLICELIT {
587+
return false
588+
}
589+
590+
r := n.Right
591+
592+
return smallintconst(r) && (n.Type.Elem().Width == 0 || r.Int64() <= smallArrayBytes/n.Type.Elem().Width)
593+
}
594+
585595
func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
586596
// make an array type corresponding the number of elements we have
587597
t := types.NewArray(n.Type.Elem(), n.Right.Int64())
@@ -639,7 +649,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
639649
var vstat *Node
640650

641651
mode := getdyn(n, true)
642-
if mode&initConst != 0 {
652+
if mode&initConst != 0 && !isSmallSliceLit(n) {
643653
vstat = staticname(t)
644654
if ctxt == inInitFunction {
645655
vstat.Name.SetReadonly(true)

test/codegen/slices.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,54 @@ func SliceNilCheck(s []int) {
113113
// amd64:-`TESTB`
114114
_ = *p
115115
}
116+
117+
// ---------------------- //
118+
// Init slice literal //
119+
// ---------------------- //
120+
// See issue 21561
121+
func InitSmallSliceLiteral() []int {
122+
// amd64:`MOVQ\t[$]42`
123+
return []int{42}
124+
}
125+
126+
func InitNotSmallSliceLiteral() []int {
127+
// amd64:`MOVQ\t.*autotmp_`
128+
return []int{
129+
42,
130+
42,
131+
42,
132+
42,
133+
42,
134+
42,
135+
42,
136+
42,
137+
42,
138+
42,
139+
42,
140+
42,
141+
42,
142+
42,
143+
42,
144+
42,
145+
42,
146+
42,
147+
42,
148+
42,
149+
42,
150+
42,
151+
42,
152+
42,
153+
42,
154+
42,
155+
42,
156+
42,
157+
42,
158+
42,
159+
42,
160+
42,
161+
42,
162+
42,
163+
42,
164+
42,
165+
}
166+
}

0 commit comments

Comments
 (0)