github.com/oarkflow/sio@v0.0.6/internal/maps/maphash/runtime.go (about)

     1  //go:build go1.18 || go1.19
     2  // +build go1.18 go1.19
     3  
     4  package maphash
     5  
     6  import (
     7  	"math/rand"
     8  	"unsafe"
     9  )
    10  
    11  type hashfn func(unsafe.Pointer, uintptr) uintptr
    12  
    13  func getRuntimeHasher[K comparable]() (h hashfn) {
    14  	a := any(make(map[K]struct{}))
    15  	i := (*mapiface)(unsafe.Pointer(&a))
    16  	h = i.typ.hasher
    17  	return
    18  }
    19  
    20  func newHashSeed() uintptr {
    21  	return uintptr(rand.Int())
    22  }
    23  
    24  // noescape hides a pointer from escape analysis. It is the identity function
    25  // but escape analysis doesn't think the output depends on the input.
    26  // noescape is inlined and currently compiles down to zero instructions.
    27  // USE CAREFULLY!
    28  // This was copied from the runtime (via pkg "strings"); see issues 23382 and 7921.
    29  //
    30  //go:nosplit
    31  //go:nocheckptr
    32  func noescape(p unsafe.Pointer) unsafe.Pointer {
    33  	x := uintptr(p)
    34  	return unsafe.Pointer(x ^ 0)
    35  }
    36  
    37  type mapiface struct {
    38  	typ *maptype
    39  	val *hmap
    40  }
    41  
    42  // go/src/runtime/type.go
    43  type maptype struct {
    44  	typ    _type
    45  	key    *_type
    46  	elem   *_type
    47  	bucket *_type
    48  	// function for hashing keys (ptr to key, seed) -> hash
    49  	hasher     func(unsafe.Pointer, uintptr) uintptr
    50  	keysize    uint8
    51  	elemsize   uint8
    52  	bucketsize uint16
    53  	flags      uint32
    54  }
    55  
    56  // go/src/runtime/map.go
    57  type hmap struct {
    58  	count     int
    59  	flags     uint8
    60  	B         uint8
    61  	noverflow uint16
    62  	// hash seed
    63  	hash0      uint32
    64  	buckets    unsafe.Pointer
    65  	oldbuckets unsafe.Pointer
    66  	nevacuate  uintptr
    67  	// true type is *mapextra
    68  	// but we don't need this data
    69  	extra unsafe.Pointer
    70  }
    71  
    72  // go/src/runtime/type.go
    73  type tflag uint8
    74  type nameOff int32
    75  type typeOff int32
    76  
    77  // go/src/runtime/type.go
    78  type _type struct {
    79  	size       uintptr
    80  	ptrdata    uintptr
    81  	hash       uint32
    82  	tflag      tflag
    83  	align      uint8
    84  	fieldAlign uint8
    85  	kind       uint8
    86  	equal      func(unsafe.Pointer, unsafe.Pointer) bool
    87  	gcdata     *byte
    88  	str        nameOff
    89  	ptrToThis  typeOff
    90  }