aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2019-09-28 23:30:08 +0700
committerKeith Randall <khr@golang.org>2019-10-08 06:09:26 +0000
commit77f5adba554c80dc536f3076b2fa882d2cf0e992 (patch)
treee9752bd4f90ba6570c0db6d88b1808da83a11aae /src
parentecba83520d4c34870e0f5f0997d59d4496957240 (diff)
downloadgo-77f5adba554c80dc536f3076b2fa882d2cf0e992.tar.xz
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: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/gc/go.go6
-rw-r--r--src/cmd/compile/internal/gc/sinit.go12
2 files changed, 17 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go
index f36e2716d6..bfd2ce27c9 100644
--- a/src/cmd/compile/internal/gc/go.go
+++ b/src/cmd/compile/internal/gc/go.go
@@ -29,6 +29,12 @@ var (
// s := []byte("...") allocating [n]byte on the stack
// Note: the flag smallframes can update this value.
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.
diff --git a/src/cmd/compile/internal/gc/sinit.go b/src/cmd/compile/internal/gc/sinit.go
index a6d13d1ac5..96b343081a 100644
--- a/src/cmd/compile/internal/gc/sinit.go
+++ b/src/cmd/compile/internal/gc/sinit.go
@@ -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) {
// make an array type corresponding the number of elements we have
t := types.NewArray(n.Type.Elem(), n.Right.Int64())
@@ -639,7 +649,7 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
var vstat *Node
mode := getdyn(n, true)
- if mode&initConst != 0 {
+ if mode&initConst != 0 && !isSmallSliceLit(n) {
vstat = staticname(t)
if ctxt == inInitFunction {
vstat.Name.SetReadonly(true)