github.com/dolthub/maphash@v0.1.0/runtime.go (about) 1 // Copyright 2022 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // This file incorporates work covered by the following copyright and 16 // permission notice: 17 // 18 // Copyright 2022 The Go Authors. All rights reserved. 19 // Use of this source code is governed by a BSD-style 20 // license that can be found in the LICENSE file. 21 22 //go:build go1.18 || go1.19 23 // +build go1.18 go1.19 24 25 package maphash 26 27 import ( 28 "math/rand" 29 "unsafe" 30 ) 31 32 type hashfn func(unsafe.Pointer, uintptr) uintptr 33 34 func getRuntimeHasher[K comparable]() (h hashfn) { 35 a := any(make(map[K]struct{})) 36 i := (*mapiface)(unsafe.Pointer(&a)) 37 h = i.typ.hasher 38 return 39 } 40 41 func newHashSeed() uintptr { 42 return uintptr(rand.Int()) 43 } 44 45 // noescape hides a pointer from escape analysis. It is the identity function 46 // but escape analysis doesn't think the output depends on the input. 47 // noescape is inlined and currently compiles down to zero instructions. 48 // USE CAREFULLY! 49 // This was copied from the runtime (via pkg "strings"); see issues 23382 and 7921. 50 // 51 //go:nosplit 52 //go:nocheckptr 53 func noescape(p unsafe.Pointer) unsafe.Pointer { 54 x := uintptr(p) 55 return unsafe.Pointer(x ^ 0) 56 } 57 58 type mapiface struct { 59 typ *maptype 60 val *hmap 61 } 62 63 // go/src/runtime/type.go 64 type maptype struct { 65 typ _type 66 key *_type 67 elem *_type 68 bucket *_type 69 // function for hashing keys (ptr to key, seed) -> hash 70 hasher func(unsafe.Pointer, uintptr) uintptr 71 keysize uint8 72 elemsize uint8 73 bucketsize uint16 74 flags uint32 75 } 76 77 // go/src/runtime/map.go 78 type hmap struct { 79 count int 80 flags uint8 81 B uint8 82 noverflow uint16 83 // hash seed 84 hash0 uint32 85 buckets unsafe.Pointer 86 oldbuckets unsafe.Pointer 87 nevacuate uintptr 88 // true type is *mapextra 89 // but we don't need this data 90 extra unsafe.Pointer 91 } 92 93 // go/src/runtime/type.go 94 type tflag uint8 95 type nameOff int32 96 type typeOff int32 97 98 // go/src/runtime/type.go 99 type _type struct { 100 size uintptr 101 ptrdata uintptr 102 hash uint32 103 tflag tflag 104 align uint8 105 fieldAlign uint8 106 kind uint8 107 equal func(unsafe.Pointer, unsafe.Pointer) bool 108 gcdata *byte 109 str nameOff 110 ptrToThis typeOff 111 }