Skip to content

Commit 2333c62

Browse files
committed
runtime: use old capacity to decide on append growth regime
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 <[email protected]> Trust: Josh Bleecher Snyder <[email protected]> Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Josh Bleecher Snyder <[email protected]>
1 parent fa04d48 commit 2333c62

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/runtime/slice.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ func growslice(et *_type, old slice, cap int) slice {
146146
if cap > doublecap {
147147
newcap = cap
148148
} else {
149-
if old.len < 1024 {
149+
if old.cap < 1024 {
150150
newcap = doublecap
151151
} else {
152152
// Check 0 < newcap to detect overflow

test/fixedbugs/issue41239.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// run
2+
3+
// Copyright 2020 The Go Authors. All rights reserved. Use of this
4+
// source code is governed by a BSD-style license that can be found in
5+
// the LICENSE file.
6+
7+
package main
8+
9+
import "fmt"
10+
11+
func main() {
12+
const N = 1024
13+
var a [N]int
14+
x := cap(append(a[:N-1:N], 9, 9))
15+
y := cap(append(a[:N:N], 9))
16+
if x != y {
17+
panic(fmt.Sprintf("different capacity on append: %d vs %d", x, y))
18+
}
19+
}

0 commit comments

Comments
 (0)