unsafe: optimize Slice bounds checking

This reduces the number of branches to bounds check non-empty slices
from 5 to 3. It does also increase the number of branches to handle
empty slices from 1 to 3; but for non-panicking calls, they should all
be predictable.

Updates #48798.

Change-Id: I3ffa66857096486f4dee417e1a66eb8fdf7a3777
Reviewed-on: https://go-review.googlesource.com/c/go/+/355490
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Matthew Dempsky 2021-10-12 15:38:52 -07:00
parent 4efa216c9d
commit 40f82f8a09

View file

@ -115,16 +115,15 @@ func makeslice64(et *_type, len64, cap64 int64) unsafe.Pointer {
}
func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
if len == 0 {
return
}
if ptr == nil {
panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
if len < 0 {
panicunsafeslicelen()
}
mem, overflow := math.MulUintptr(et.size, uintptr(len))
if overflow || mem > -uintptr(ptr) || len < 0 {
if overflow || mem > -uintptr(ptr) {
if ptr == nil {
panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
}
panicunsafeslicelen()
}
}