github.com/primecitizens/pcz/std@v0.2.1/core/mark/noescape.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 4 package mark 5 6 import ( 7 "unsafe" 8 _ "unsafe" // for go:linkname 9 10 _ "github.com/primecitizens/pcz/std/core/mark/internal/reflect" // import reflect.noescape 11 ) 12 13 // NoEscape hides a pointer from escape analysis. USE CAREFULLY! 14 // 15 // It is the identity function but escape analysis doesn't think the output 16 // depends on the input. 17 // 18 // It is inlined and currently compiles down to zero instructions. 19 // 20 //go:nosplit 21 func NoEscape[T any](p *T) *T { 22 return (*T)(NoEscapeUnsafePointer(unsafe.Pointer(p))) 23 } 24 25 //go:linkname NoEscapeUnsafePointer reflect.noescape 26 //go:noescape 27 func NoEscapeUnsafePointer(p unsafe.Pointer) unsafe.Pointer 28 29 // NoEscapePointer is [NoEscape] but returns unsafe.Pointer. 30 // 31 //go:nosplit 32 func NoEscapePointer[T any](p *T) unsafe.Pointer { 33 return NoEscapeUnsafePointer(unsafe.Pointer(p)) 34 } 35 36 // NoEscapeSlice is [NoEscape] for slices. 37 // 38 //go:nosplit 39 func NoEscapeSlice[T any](p []T) []T { 40 return unsafe.Slice(NoEscape(unsafe.SliceData(p)), cap(p))[:len(p)] 41 } 42 43 // NoEscapeSliceData is [NoEscapeSlice] but returns the pointer 44 // to the underlay array. 45 // 46 //go:nosplit 47 func NoEscapeSliceData[T any](p []T) *T { 48 return NoEscape(unsafe.SliceData(p)) 49 } 50 51 // NoEscapeSliceDataPointer is [NoEscapeSliceData] but returns an 52 // unsafe.Pointer. 53 // 54 //go:nosplit 55 func NoEscapeSliceDataPointer[T any](p []T) unsafe.Pointer { 56 return NoEscapeUnsafePointer(unsafe.Pointer(unsafe.SliceData(p))) 57 } 58 59 // NoEscapeString is [NoEscape] for string. 60 // 61 //go:nosplit 62 func NoEscapeString[String ~string](s String) String { 63 return String( 64 unsafe.String( 65 NoEscape(unsafe.StringData(string(s))), 66 len(s), 67 ), 68 ) 69 } 70 71 // NoEscapeStringData is [NoEscapeString] but returns the pointer to 72 // the underlay byte array. 73 // 74 //go:nosplit 75 func NoEscapeStringData[String ~string](s String) *byte { 76 return NoEscape(unsafe.StringData(string(s))) 77 } 78 79 // NoEscapeStringDataPointer is [NoEscapeStringData] but returns an 80 // unsafe.Pointer. 81 // 82 //go:nosplit 83 func NoEscapeStringDataPointer[String ~string](s String) unsafe.Pointer { 84 return NoEscapeUnsafePointer(unsafe.Pointer(unsafe.StringData(string(s)))) 85 } 86 87 // NoEscapeBytesString is [NoEscapeString] but taking bytes as the argument. 88 func NoEscapeBytesString[T ~byte](s []T) string { 89 return unsafe.String( 90 (*byte)(NoEscapeUnsafePointer(unsafe.Pointer(unsafe.SliceData(s)))), 91 len(s), 92 ) 93 }