Commit 77f5adba authored by Cuong Manh Le's avatar Cuong Manh Le Committed by Keith Randall

cmd/compile: don't use statictmps for small object in slice literal

Fixes #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: default avatarKeith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent ecba8352
...@@ -29,6 +29,12 @@ var ( ...@@ -29,6 +29,12 @@ var (
// s := []byte("...") allocating [n]byte on the stack // s := []byte("...") allocating [n]byte on the stack
// Note: the flag smallframes can update this value. // Note: the flag smallframes can update this value.
maxImplicitStackVarSize = int64(64 * 1024) maxImplicitStackVarSize = int64(64 * 1024)
// smallArrayBytes is the maximum size of an array which is considered small.
// Small arrays will be initialized directly with a sequence of constant stores.
// Large arrays will be initialized by copying from a static temp.
// 256 bytes was chosen to minimize generated code + statictmp size.
smallArrayBytes = int64(256)
) )
// isRuntimePkg reports whether p is package runtime. // isRuntimePkg reports whether p is package runtime.
......
...@@ -582,6 +582,16 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes) ...@@ -582,6 +582,16 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
} }
} }
func isSmallSliceLit(n *Node) bool {
if n.Op != OSLICELIT {
return false
}
r := n.Right
return smallintconst(r) && (n.Type.Elem().Width == 0 || r.Int64() <= smallArrayBytes/n.Type.Elem().Width)
}
func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) { func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
// make an array type corresponding the number of elements we have // make an array type corresponding the number of elements we have
t := types.NewArray(n.Type.Elem(), n.Right.Int64()) t := types.NewArray(n.Type.Elem(), n.Right.Int64())
...@@ -639,7 +649,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) { ...@@ -639,7 +649,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
var vstat *Node var vstat *Node
mode := getdyn(n, true) mode := getdyn(n, true)
if mode&initConst != 0 { if mode&initConst != 0 && !isSmallSliceLit(n) {
vstat = staticname(t) vstat = staticname(t)
if ctxt == inInitFunction { if ctxt == inInitFunction {
vstat.Name.SetReadonly(true) vstat.Name.SetReadonly(true)
......
...@@ -113,3 +113,54 @@ func SliceNilCheck(s []int) { ...@@ -113,3 +113,54 @@ func SliceNilCheck(s []int) {
// amd64:-`TESTB` // amd64:-`TESTB`
_ = *p _ = *p
} }
// ---------------------- //
// Init slice literal //
// ---------------------- //
// See issue 21561
func InitSmallSliceLiteral() []int {
// amd64:`MOVQ\t[$]42`
return []int{42}
}
func InitNotSmallSliceLiteral() []int {
// amd64:`MOVQ\t.*autotmp_`
return []int{
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
42,
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment