diff options
Diffstat (limited to 'src/runtime')
| -rw-r--r-- | src/runtime/runtime_test.go | 40 | ||||
| -rw-r--r-- | src/runtime/slice.go | 14 |
2 files changed, 52 insertions, 2 deletions
diff --git a/src/runtime/runtime_test.go b/src/runtime/runtime_test.go index f65562ab91..75fc9bcb84 100644 --- a/src/runtime/runtime_test.go +++ b/src/runtime/runtime_test.go @@ -261,3 +261,43 @@ func TestBadOpen(t *testing.T) { t.Errorf("close()=%d, want -1", c) } } + +func TestAppendGrowth(t *testing.T) { + var x []int64 + check := func(want int) { + if cap(x) != want { + t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want) + } + } + + check(0) + want := 1 + for i := 1; i <= 100; i++ { + x = append(x, 1) + check(want) + if i&(i-1) == 0 { + want = 2 * i + } + } +} + +var One = []int64{1} + +func TestAppendSliceGrowth(t *testing.T) { + var x []int64 + check := func(want int) { + if cap(x) != want { + t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want) + } + } + + check(0) + want := 1 + for i := 1; i <= 100; i++ { + x = append(x, One...) + check(want) + if i&(i-1) == 0 { + want = 2 * i + } + } +} diff --git a/src/runtime/slice.go b/src/runtime/slice.go index 15820a5181..5cda11d9b0 100644 --- a/src/runtime/slice.go +++ b/src/runtime/slice.go @@ -33,12 +33,22 @@ func makeslice(t *slicetype, len64, cap64 int64) slice { return slice{p, len, cap} } -func growslice(t *slicetype, old slice, n int) slice { +// growslice_n is a variant of growslice that takes the number of new elements +// instead of the new minimum capacity. +// TODO(rsc): This is used by append(slice, slice...). +// The compiler should change that code to use growslice directly (issue #11419). +func growslice_n(t *slicetype, old slice, n int) slice { if n < 1 { panic(errorString("growslice: invalid n")) } + return growslice(t, old, old.cap+n) +} - cap := old.cap + n +// growslice handles slice growth during append. +// It is passed the slice type, the old slice, and the desired new minimum capacity, +// and it returns a new slice with at least that capacity, with the old data +// copied into it. +func growslice(t *slicetype, old slice, cap int) slice { if cap < old.cap || t.elem.size > 0 && uintptr(cap) > _MaxMem/uintptr(t.elem.size) { panic(errorString("growslice: cap out of range")) } |
