]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: use old capacity to decide on append growth regime
authorKeith Randall <khr@golang.org>
Fri, 25 Sep 2020 02:26:33 +0000 (19:26 -0700)
committerKeith Randall <khr@golang.org>
Fri, 25 Sep 2020 03:59:54 +0000 (03:59 +0000)
We grow the backing store on append by 2x for small sizes and 1.25x
for large sizes. The threshold we use for picking the growth factor
used to depend on the old length, not the old capacity. That's kind of
unfortunate, because then doing append(s, 0, 0) and append(append(s,
0), 0) do different things. (If s has one more spot available, then
the former expression chooses its growth based on len(s) and the
latter on len(s)+1.)  If we instead use the old capacity, we get more
consistent behavior. (Both expressions use len(s)+1 == cap(s) to
decide.)

Fixes #41239

Change-Id: I40686471d256edd72ec92aef973a89b52e235d4b
Reviewed-on: https://go-review.googlesource.com/c/go/+/257338
Trust: Keith Randall <khr@golang.org>
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/runtime/slice.go
test/fixedbugs/issue41239.go [new file with mode: 0644]

index 82a45c78a9e054ff74c5cbbf34af1852f6f28f60..c0647d95a06cb3de31dda01bbe1fae9040ddff92 100644 (file)
@@ -146,7 +146,7 @@ func growslice(et *_type, old slice, cap int) slice {
        if cap > doublecap {
                newcap = cap
        } else {
-               if old.len < 1024 {
+               if old.cap < 1024 {
                        newcap = doublecap
                } else {
                        // Check 0 < newcap to detect overflow
diff --git a/test/fixedbugs/issue41239.go b/test/fixedbugs/issue41239.go
new file mode 100644 (file)
index 0000000..3e9ef5e
--- /dev/null
@@ -0,0 +1,19 @@
+// run
+
+// Copyright 2020 The Go Authors. All rights reserved.  Use of this
+// source code is governed by a BSD-style license that can be found in
+// the LICENSE file.
+
+package main
+
+import "fmt"
+
+func main() {
+       const N = 1024
+       var a [N]int
+       x := cap(append(a[:N-1:N], 9, 9))
+       y := cap(append(a[:N:N], 9))
+       if x != y {
+               panic(fmt.Sprintf("different capacity on append: %d vs %d", x, y))
+       }
+}