Files
visor/pkg/gohacks/slice_go113_unsafe.go
Michael PrattandgVisor bot f941bf69c4 Replace gohacks.SliceHeader with unsafe.Slice
All remaining uses of gohacks.SliceHeader are to create a slice pointing to
some other backing array. Go 1.20 introduces unsafe.Slice to do exactly this,
so switch to this interface.

For now we want code to continue to build with Go 1.19, so we still use a
gohacks.Slice wrapper, which uses unsafe.Slice on 1.20 and SliceHeader on
<1.20. Once 1.19 support is dropped, uses can drop gohacks altogether.

gohacks.Slice is inlined into callers, and unsafe.Slice is a compiler
intrinsic, so these wrappers have minimal overhead. The primary difference is
the addition of a nil check on the pointer and an overflow check on
ptr+length*size.

I think these are minimal enough to not cause problems, but if they are (e.g.,
in safemem), we could consider adding a SliceUnchecked function that continues
to use SliceHeader. But I'd like to try to avoid that, as it adds process to
verify it is still compatible with new Go releases.

For #8422.

PiperOrigin-RevId: 504926819
2023-01-26 13:35:25 -08:00

46 lines
1.4 KiB
Go

// Copyright 2023 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build go1.13 && !go1.20
// +build go1.13,!go1.20
// TODO(go.dev/issue/8422): Remove this once Go 1.19 is no longer supported,
// and update callers to use unsafe.Slice directly.
package gohacks
import (
"unsafe"
)
// sliceHeader is equivalent to reflect.SliceHeader, but represents the pointer
// to the underlying array as unsafe.Pointer rather than uintptr, allowing
// sliceHeaders to be directly converted to slice objects.
type sliceHeader struct {
Data unsafe.Pointer
Len int
Cap int
}
// Slice returns a slice whose underlying array starts at ptr an which length
// and capacity are len.
func Slice[T any](ptr *T, length int) []T {
var s []T
hdr := (*sliceHeader)(unsafe.Pointer(&s))
hdr.Data = unsafe.Pointer(ptr)
hdr.Len = length
hdr.Cap = length
return s
}