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  }