mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile,runtime: open code unsafe.Slice
So prevent heavy runtime call overhead, and the compiler will have a chance to optimize the bound check. With this optimization, changing runtime/stack.go to use unsafe.Slice no longer negatively impacts stack copying performance: name old time/op new time/op delta StackCopyWithStkobj-8 16.3ms ± 6% 16.5ms ± 5% ~ (p=0.382 n=8+8) name old alloc/op new alloc/op delta StackCopyWithStkobj-8 17.0B ± 0% 17.0B ± 0% ~ (all equal) name old allocs/op new allocs/op delta StackCopyWithStkobj-8 1.00 ± 0% 1.00 ± 0% ~ (all equal) Fixes #48798 Change-Id: I731a9a4abd6dd6846f44eece7f86025b7bb1141b Reviewed-on: https://go-review.googlesource.com/c/go/+/362934 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
ccb798741b
commit
579902d0b1
5 changed files with 76 additions and 21 deletions
|
|
@ -117,6 +117,13 @@ func makeslice64(et *_type, len64, cap64 int64) unsafe.Pointer {
|
|||
return makeslice(et, len, cap)
|
||||
}
|
||||
|
||||
// This is a wrapper over runtime/internal/math.MulUintptr,
|
||||
// so the compiler can recognize and treat it as an intrinsic.
|
||||
func mulUintptr(a, b uintptr) (uintptr, bool) {
|
||||
return math.MulUintptr(a, b)
|
||||
}
|
||||
|
||||
// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
|
||||
func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
|
||||
if len < 0 {
|
||||
panicunsafeslicelen()
|
||||
|
|
@ -125,12 +132,13 @@ func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
|
|||
mem, overflow := math.MulUintptr(et.size, uintptr(len))
|
||||
if overflow || mem > -uintptr(ptr) {
|
||||
if ptr == nil {
|
||||
panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
|
||||
panicunsafeslicenilptr()
|
||||
}
|
||||
panicunsafeslicelen()
|
||||
}
|
||||
}
|
||||
|
||||
// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
|
||||
func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
|
||||
len := int(len64)
|
||||
if int64(len) != len64 {
|
||||
|
|
@ -153,6 +161,10 @@ func panicunsafeslicelen() {
|
|||
panic(errorString("unsafe.Slice: len out of range"))
|
||||
}
|
||||
|
||||
func panicunsafeslicenilptr() {
|
||||
panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
|
||||
}
|
||||
|
||||
// growslice handles slice growth during append.
|
||||
// It is passed the slice element 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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue