github.com/cloudwego/dynamicgo@v0.2.6-0.20240519101509-707f41b6b834/internal/rt/fastmem.go (about) 1 /* 2 * Copyright 2023 CloudWeGo Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package rt 18 19 import ( 20 "unsafe" 21 ) 22 23 //go:nosplit 24 func Get16(v []byte) int16 { 25 return *(*int16)((*GoSlice)(unsafe.Pointer(&v)).Ptr) 26 } 27 28 //go:nosplit 29 func Get32(v []byte) int32 { 30 return *(*int32)((*GoSlice)(unsafe.Pointer(&v)).Ptr) 31 } 32 33 //go:nosplit 34 func Get64(v []byte) int64 { 35 return *(*int64)((*GoSlice)(unsafe.Pointer(&v)).Ptr) 36 } 37 38 //go:nosplit 39 func Mem2Str(v []byte) (s string) { 40 (*GoString)(unsafe.Pointer(&s)).Len = (*GoSlice)(unsafe.Pointer(&v)).Len 41 (*GoString)(unsafe.Pointer(&s)).Ptr = (*GoSlice)(unsafe.Pointer(&v)).Ptr 42 return 43 } 44 45 //go:nosplit 46 func Str2Mem(s string) (v []byte) { 47 (*GoSlice)(unsafe.Pointer(&v)).Cap = (*GoString)(unsafe.Pointer(&s)).Len 48 (*GoSlice)(unsafe.Pointer(&v)).Len = (*GoString)(unsafe.Pointer(&s)).Len 49 (*GoSlice)(unsafe.Pointer(&v)).Ptr = (*GoString)(unsafe.Pointer(&s)).Ptr 50 return 51 } 52 53 //go:nosplit 54 func BytesFrom(p unsafe.Pointer, n int, c int) (r []byte) { 55 (*GoSlice)(unsafe.Pointer(&r)).Ptr = p 56 (*GoSlice)(unsafe.Pointer(&r)).Len = n 57 (*GoSlice)(unsafe.Pointer(&r)).Cap = c 58 return 59 } 60 61 //go:nosplit 62 func StringFrom(p unsafe.Pointer, n int) (r string) { 63 (*GoString)(unsafe.Pointer(&r)).Ptr = p 64 (*GoString)(unsafe.Pointer(&r)).Len = n 65 return 66 } 67 68 func IndexSlice(slice unsafe.Pointer, size uintptr, index int) unsafe.Pointer { 69 // if slice.Ptr == nil || slice.Cap == 0 { 70 // return nil 71 // } 72 return unsafe.Pointer(uintptr(*(*unsafe.Pointer)(slice)) + uintptr(index)*size) 73 } 74 75 func IndexPtr(ptr unsafe.Pointer, size uintptr, index int) unsafe.Pointer { 76 // if slice.Ptr == nil || slice.Cap == 0 { 77 // return nil 78 // } 79 return unsafe.Pointer(uintptr(ptr) + uintptr(index)*size) 80 } 81 82 func IndexByte(ptr *[]byte, index int) unsafe.Pointer { 83 // if slice.Ptr == nil || slice.Cap == 0 { 84 // return nil 85 // } 86 return unsafe.Pointer(uintptr((*GoSlice)(unsafe.Pointer(ptr)).Ptr) + uintptr(index)) 87 } 88 89 func IndexChar(src string, index int) unsafe.Pointer { 90 // if slice.Ptr == nil || slice.Cap == 0 { 91 // return nil 92 // } 93 return unsafe.Pointer(uintptr((*GoString)(unsafe.Pointer(&src)).Ptr) + uintptr(index)) 94 } 95 96 func GuardSlice(buf *[]byte, n int) { 97 c := cap(*buf) 98 l := len(*buf) 99 if c-l < n { 100 c = c>>1 + n + l 101 if c < 1024 { 102 c = 1024 103 } 104 tmp := make([]byte, l, c) 105 copy(tmp, *buf) 106 *buf = tmp 107 } 108 } 109 110 func AddPtr(a unsafe.Pointer, b uintptr) unsafe.Pointer { 111 return unsafe.Pointer(uintptr(a) + b) 112 } 113 114 func SubPtr(a unsafe.Pointer, b uintptr) unsafe.Pointer { 115 return unsafe.Pointer(uintptr(a) - b) 116 } 117 118 func PtrOffset(a unsafe.Pointer, b unsafe.Pointer) int { 119 return int(uintptr(a)) - int(uintptr(b)) 120 } 121 122 func GetBytePtr(b []byte) unsafe.Pointer { 123 return *(*unsafe.Pointer)(unsafe.Pointer(&b)) 124 } 125 126 func Growslice(et *GoType, old GoSlice, cap int) GoSlice { 127 return growslice(et, old, cap) 128 } 129 130 // NoEscape hides a pointer from escape analysis. NoEscape is 131 // the identity function but escape analysis doesn't think the 132 // output depends on the input. NoEscape is inlined and currently 133 // compiles down to zero instructions. 134 // USE CAREFULLY! 135 //go:nosplit 136 //goland:noinspection GoVetUnsafePointer 137 func NoEscape(p unsafe.Pointer) unsafe.Pointer { 138 x := uintptr(p) 139 return unsafe.Pointer(x ^ 0) 140 }