]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: don't use statictmps for small object in slice literal
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Sat, 28 Sep 2019 16:30:08 +0000 (23:30 +0700)
committerKeith Randall <khr@golang.org>
Tue, 8 Oct 2019 06:09:26 +0000 (06:09 +0000)
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>

src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/sinit.go
test/codegen/slices.go

index f36e2716d667392afd79360a3c2c27fc74a4da36..bfd2ce27c920f71be871744a6bdd832debb4935b 100644 (file)
@@ -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.
index a6d13d1ac5f1d10813194d935e303e6c24a24a27..96b343081a625ee4788e58befeb3deff14d72581 100644 (file)
@@ -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)
index fccd711d7174cdc190ef6123fcc58ba53d9775bb..cf569e27fbde136ba75327705460d4a4144f48df 100644 (file)
@@ -113,3 +113,54 @@ func SliceNilCheck(s []int) {
        // amd64:-`TESTB`
        _ = *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,
+       }
+}