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  }