github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/internal/rt/fastmem.go (about) 1 /* 2 * Copyright 2021 ByteDance Inc. 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 `reflect` 22 ) 23 24 //go:nosplit 25 func Get16(v []byte) int16 { 26 return *(*int16)((*GoSlice)(unsafe.Pointer(&v)).Ptr) 27 } 28 29 //go:nosplit 30 func Get32(v []byte) int32 { 31 return *(*int32)((*GoSlice)(unsafe.Pointer(&v)).Ptr) 32 } 33 34 //go:nosplit 35 func Get64(v []byte) int64 { 36 return *(*int64)((*GoSlice)(unsafe.Pointer(&v)).Ptr) 37 } 38 39 //go:nosplit 40 func Mem2Str(v []byte) (s string) { 41 (*GoString)(unsafe.Pointer(&s)).Len = (*GoSlice)(unsafe.Pointer(&v)).Len 42 (*GoString)(unsafe.Pointer(&s)).Ptr = (*GoSlice)(unsafe.Pointer(&v)).Ptr 43 return 44 } 45 46 //go:nosplit 47 func Str2Mem(s string) (v []byte) { 48 (*GoSlice)(unsafe.Pointer(&v)).Cap = (*GoString)(unsafe.Pointer(&s)).Len 49 (*GoSlice)(unsafe.Pointer(&v)).Len = (*GoString)(unsafe.Pointer(&s)).Len 50 (*GoSlice)(unsafe.Pointer(&v)).Ptr = (*GoString)(unsafe.Pointer(&s)).Ptr 51 return 52 } 53 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 func FuncAddr(f interface{}) unsafe.Pointer { 62 if vv := UnpackEface(f); vv.Type.Kind() != reflect.Func { 63 panic("f is not a function") 64 } else { 65 return *(*unsafe.Pointer)(vv.Value) 66 } 67 } 68 69 //go:nocheckptr 70 func IndexChar(src string, index int) unsafe.Pointer { 71 return unsafe.Pointer(uintptr((*GoString)(unsafe.Pointer(&src)).Ptr) + uintptr(index)) 72 } 73 74 //go:nocheckptr 75 func IndexByte(ptr []byte, index int) unsafe.Pointer { 76 return unsafe.Pointer(uintptr((*GoSlice)(unsafe.Pointer(&ptr)).Ptr) + uintptr(index)) 77 } 78 79 func GuardSlice(buf *[]byte, n int) { 80 c := cap(*buf) 81 l := len(*buf) 82 if c-l < n { 83 c = c>>1 + n + l 84 if c < 32 { 85 c = 32 86 } 87 tmp := make([]byte, l, c) 88 copy(tmp, *buf) 89 *buf = tmp 90 } 91 } 92 93 //go:nosplit 94 func Ptr2SlicePtr(s unsafe.Pointer, l int, c int) unsafe.Pointer { 95 slice := &GoSlice{ 96 Ptr: s, 97 Len: l, 98 Cap: c, 99 } 100 return unsafe.Pointer(slice) 101 } 102 103 //go:nosplit 104 func StrPtr(s string) unsafe.Pointer { 105 return (*GoString)(unsafe.Pointer(&s)).Ptr 106 } 107 108 //go:nosplit 109 func StrFrom(p unsafe.Pointer, n int64) (s string) { 110 (*GoString)(unsafe.Pointer(&s)).Ptr = p 111 (*GoString)(unsafe.Pointer(&s)).Len = int(n) 112 return 113 } 114 115 // NoEscape hides a pointer from escape analysis. NoEscape is 116 // the identity function but escape analysis doesn't think the 117 // output depends on the input. NoEscape is inlined and currently 118 // compiles down to zero instructions. 119 // USE CAREFULLY! 120 //go:nosplit 121 //goland:noinspection GoVetUnsafePointer 122 func NoEscape(p unsafe.Pointer) unsafe.Pointer { 123 x := uintptr(p) 124 return unsafe.Pointer(x ^ 0) 125 }