aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/slice.go
diff options
context:
space:
mode:
authorMartin Möhrmann <moehrmann@google.com>2018-10-16 00:27:42 +0200
committerMartin Möhrmann <martisch@uos.de>2018-10-23 07:23:15 +0000
commit05166bf54d053fcc833cf862b7cfb1fbf05b42ba (patch)
treea1f19084b450d42dabb1cc18d499a86d32392463 /src/runtime/slice.go
parent3b091bf6cceca868e2063a2c8b3cec90411ea18e (diff)
downloadgo-05166bf54d053fcc833cf862b7cfb1fbf05b42ba.tar.xz
runtime: use multiplication with overflow check for makeslice
This improves performance for slices with an element size larger than 32 bytes and removes loading a value from the maxElems array for smaller element sizes. name old time/op new time/op delta MakeSlice/Byte 18.0ns ± 4% 18.0ns ± 2% ~ (p=0.575 n=20+17) MakeSlice/Int16 21.8ns ± 2% 21.6ns ± 1% -0.63% (p=0.035 n=20+19) MakeSlice/Int 42.0ns ± 2% 41.6ns ± 1% ~ (p=0.121 n=20+18) MakeSlice/Ptr 62.6ns ± 2% 62.4ns ± 2% ~ (p=0.491 n=20+18) MakeSlice/Struct/24 57.4ns ± 3% 56.0ns ± 2% -2.40% (p=0.000 n=19+19) MakeSlice/Struct/32 62.1ns ± 2% 60.6ns ± 3% -2.43% (p=0.000 n=20+20) MakeSlice/Struct/40 77.3ns ± 3% 68.9ns ± 3% -10.91% (p=0.000 n=20+20) Updates #21588 Change-Id: Ie12807bf8f77c0e15453413f47e3d7de771b798f Reviewed-on: https://go-review.googlesource.com/c/142377 Run-TryBot: Martin Möhrmann <martisch@uos.de> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/runtime/slice.go')
-rw-r--r--src/runtime/slice.go24
1 files changed, 12 insertions, 12 deletions
diff --git a/src/runtime/slice.go b/src/runtime/slice.go
index 2c5c52a6e6..095ddc5bbd 100644
--- a/src/runtime/slice.go
+++ b/src/runtime/slice.go
@@ -54,21 +54,21 @@ func panicmakeslicecap() {
}
func makeslice(et *_type, len, cap int) slice {
- // NOTE: The len > maxElements check here is not strictly necessary,
- // but it produces a 'len out of range' error instead of a 'cap out of range' error
- // when someone does make([]T, bignumber). 'cap out of range' is true too,
- // but since the cap is only being supplied implicitly, saying len is clearer.
- // See issue 4085.
- maxElements := maxSliceCap(et.size)
- if len < 0 || uintptr(len) > maxElements {
- panicmakeslicelen()
- }
-
- if cap < len || uintptr(cap) > maxElements {
+ mem, overflow := math.MulUintptr(et.size, uintptr(cap))
+ if overflow || mem > maxAlloc || len < 0 || len > cap {
+ // NOTE: Produce a 'len out of range' error instead of a
+ // 'cap out of range' error when someone does make([]T, bignumber).
+ // 'cap out of range' is true too, but since the cap is only being
+ // supplied implicitly, saying len is clearer.
+ // See golang.org/issue/4085.
+ mem, overflow := math.MulUintptr(et.size, uintptr(len))
+ if overflow || mem > maxAlloc || len < 0 {
+ panicmakeslicelen()
+ }
panicmakeslicecap()
}
+ p := mallocgc(mem, et, true)
- p := mallocgc(et.size*uintptr(cap), et, true)
return slice{p, len, cap}
}