mirror of
https://github.com/golang/go
synced 2024-11-23 15:20:03 -07:00
a8a60ac2a7
Changes the compiler to recognize the slice extension pattern append(x, make([]T, y)...) and replace it with growslice and an optional memclr to avoid an allocation for make([]T, y). Memclr is not called in case growslice already allocated a new cleared backing array when T contains pointers. amd64: name old time/op new time/op delta ExtendSlice/IntSlice 103ns ± 4% 57ns ± 4% -44.55% (p=0.000 n=18+18) ExtendSlice/PointerSlice 155ns ± 3% 77ns ± 3% -49.93% (p=0.000 n=20+20) ExtendSlice/NoGrow 50.2ns ± 3% 5.2ns ± 2% -89.67% (p=0.000 n=18+18) name old alloc/op new alloc/op delta ExtendSlice/IntSlice 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=20+20) ExtendSlice/PointerSlice 64.0B ± 0% 32.0B ± 0% -50.00% (p=0.000 n=20+20) ExtendSlice/NoGrow 32.0B ± 0% 0.0B -100.00% (p=0.000 n=20+20) name old allocs/op new allocs/op delta ExtendSlice/IntSlice 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=20+20) ExtendSlice/PointerSlice 2.00 ± 0% 1.00 ± 0% -50.00% (p=0.000 n=20+20) ExtendSlice/NoGrow 1.00 ± 0% 0.00 -100.00% (p=0.000 n=20+20) Fixes #21266 Change-Id: Idc3077665f63cbe89762b590c5967a864fd1c07f Reviewed-on: https://go-review.googlesource.com/109517 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
59 lines
1.8 KiB
Go
59 lines
1.8 KiB
Go
// run
|
|
|
|
// Copyright 2013 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 (
|
|
"strings"
|
|
"unsafe"
|
|
)
|
|
|
|
type T []int
|
|
|
|
func main() {
|
|
n := -1
|
|
shouldPanic("len out of range", func() { _ = make(T, n) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, n) })
|
|
shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
|
|
var t *byte
|
|
if unsafe.Sizeof(t) == 8 {
|
|
var n2 int64 = 1 << 50
|
|
shouldPanic("len out of range", func() { _ = make(T, int(n2)) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int(n2)) })
|
|
n2 = 1<<63 - 1
|
|
shouldPanic("len out of range", func() { _ = make(T, int(n2)) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int(n2)) })
|
|
} else {
|
|
n = 1<<31 - 1
|
|
shouldPanic("len out of range", func() { _ = make(T, n) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, n) })
|
|
shouldPanic("len out of range", func() { _ = make(T, int64(n)) })
|
|
shouldPanic("cap out of range", func() { _ = make(T, 0, int64(n)) })
|
|
}
|
|
|
|
// Test make in append panics since the gc compiler optimizes makes in appends.
|
|
shouldPanic("len out of range", func() { _ = append(T{}, make(T, n)...) })
|
|
shouldPanic("cap out of range", func() { _ = append(T{}, make(T, 0, n)...) })
|
|
shouldPanic("len out of range", func() { _ = append(T{}, make(T, int64(n))...) })
|
|
shouldPanic("cap out of range", func() { _ = append(T{}, make(T, 0, int64(n))...) })
|
|
}
|
|
|
|
func shouldPanic(str string, f func()) {
|
|
defer func() {
|
|
err := recover()
|
|
if err == nil {
|
|
panic("did not panic")
|
|
}
|
|
s := err.(error).Error()
|
|
if !strings.Contains(s, str) {
|
|
panic("got panic " + s + ", want " + str)
|
|
}
|
|
}()
|
|
|
|
f()
|
|
}
|