package runtime
import (
)
const (
c0 = uintptr((8-sys.PtrSize)/4*2860486313 + (sys.PtrSize-4)/4*33054211828000289)
c1 = uintptr((8-sys.PtrSize)/4*3267000013 + (sys.PtrSize-4)/4*23344194077549503)
)
func ( unsafe.Pointer, uintptr) uintptr {
return
}
func ( unsafe.Pointer, uintptr) uintptr {
return memhash(, , 1)
}
func ( unsafe.Pointer, uintptr) uintptr {
return memhash(, , 2)
}
func ( unsafe.Pointer, uintptr) uintptr {
return memhash(, , 16)
}
func ( unsafe.Pointer, uintptr) uintptr {
:= getclosureptr()
:= *(*uintptr)(unsafe.Pointer( + unsafe.Sizeof()))
return memhash(, , )
}
var useAeshash bool
func ( unsafe.Pointer, , uintptr) uintptr
func ( unsafe.Pointer, uintptr) uintptr
func ( unsafe.Pointer, uintptr) uintptr
func ( unsafe.Pointer, uintptr) uintptr
func ( unsafe.Pointer, uintptr) uintptr {
:= (*stringStruct)()
return memhashFallback(.str, , uintptr(.len))
}
func ( unsafe.Pointer, uintptr) uintptr {
:= *(*float32)()
switch {
case == 0:
return c1 * (c0 ^ )
case != :
return c1 * (c0 ^ ^ uintptr(fastrand()))
default:
return memhash(, , 4)
}
}
func ( unsafe.Pointer, uintptr) uintptr {
:= *(*float64)()
switch {
case == 0:
return c1 * (c0 ^ )
case != :
return c1 * (c0 ^ ^ uintptr(fastrand()))
default:
return memhash(, , 8)
}
}
func ( unsafe.Pointer, uintptr) uintptr {
:= (*[2]float32)()
return f32hash(unsafe.Pointer(&[1]), f32hash(unsafe.Pointer(&[0]), ))
}
func ( unsafe.Pointer, uintptr) uintptr {
:= (*[2]float64)()
return f64hash(unsafe.Pointer(&[1]), f64hash(unsafe.Pointer(&[0]), ))
}
func ( unsafe.Pointer, uintptr) uintptr {
:= (*iface)()
:= .tab
if == nil {
return
}
:= ._type
if .equal == nil {
panic(errorString("hash of unhashable type " + .string()))
}
if isDirectIface() {
return c1 * typehash(, unsafe.Pointer(&.data), ^c0)
} else {
return c1 * typehash(, .data, ^c0)
}
}
func ( unsafe.Pointer, uintptr) uintptr {
:= (*eface)()
:= ._type
if == nil {
return
}
if .equal == nil {
panic(errorString("hash of unhashable type " + .string()))
}
if isDirectIface() {
return c1 * typehash(, unsafe.Pointer(&.data), ^c0)
} else {
return c1 * typehash(, .data, ^c0)
}
}
func ( *_type, unsafe.Pointer, uintptr) uintptr {
if .tflag&tflagRegularMemory != 0 {
switch .size {
case 4:
return memhash32(, )
case 8:
return memhash64(, )
default:
return memhash(, , .size)
}
}
switch .kind & kindMask {
case kindFloat32:
return f32hash(, )
case kindFloat64:
return f64hash(, )
case kindComplex64:
return c64hash(, )
case kindComplex128:
return c128hash(, )
case kindString:
return strhash(, )
case kindInterface:
:= (*interfacetype)(unsafe.Pointer())
if len(.mhdr) == 0 {
return nilinterhash(, )
}
return interhash(, )
case kindArray:
:= (*arraytype)(unsafe.Pointer())
for := uintptr(0); < .len; ++ {
= (.elem, add(, *.elem.size), )
}
return
case kindStruct:
:= (*structtype)(unsafe.Pointer())
:= uintptr(0)
:= uintptr(0)
for , := range .fields {
if > && (.name.isBlank() || .offset() != || .typ.tflag&tflagRegularMemory == 0) {
= memhash(add(, ), , -)
=
}
if .name.isBlank() {
continue
}
if .typ.tflag&tflagRegularMemory == 0 {
= (.typ, add(, .offset()), )
continue
}
if == {
= .offset()
}
= .offset() + .typ.size
}
if > {
= memhash(add(, ), , -)
}
return
default:
panic(errorString("hash of unhashable type " + .string()))
}
}
func ( *_type, unsafe.Pointer, uintptr) uintptr {
return typehash(, , )
}
func (, unsafe.Pointer) bool {
return true
}
func (, unsafe.Pointer) bool {
return *(*int8)() == *(*int8)()
}
func (, unsafe.Pointer) bool {
return *(*int16)() == *(*int16)()
}
func (, unsafe.Pointer) bool {
return *(*int32)() == *(*int32)()
}
func (, unsafe.Pointer) bool {
return *(*int64)() == *(*int64)()
}
func (, unsafe.Pointer) bool {
return *(*[2]int64)() == *(*[2]int64)()
}
func (, unsafe.Pointer) bool {
return *(*float32)() == *(*float32)()
}
func (, unsafe.Pointer) bool {
return *(*float64)() == *(*float64)()
}
func (, unsafe.Pointer) bool {
return *(*complex64)() == *(*complex64)()
}
func (, unsafe.Pointer) bool {
return *(*complex128)() == *(*complex128)()
}
func (, unsafe.Pointer) bool {
return *(*string)() == *(*string)()
}
func (, unsafe.Pointer) bool {
:= *(*iface)()
:= *(*iface)()
return .tab == .tab && ifaceeq(.tab, .data, .data)
}
func (, unsafe.Pointer) bool {
:= *(*eface)()
:= *(*eface)()
return ._type == ._type && efaceeq(._type, .data, .data)
}
func ( *_type, , unsafe.Pointer) bool {
if == nil {
return true
}
:= .equal
if == nil {
panic(errorString("comparing uncomparable type " + .string()))
}
if isDirectIface() {
return ==
}
return (, )
}
func ( *itab, , unsafe.Pointer) bool {
if == nil {
return true
}
:= ._type
:= .equal
if == nil {
panic(errorString("comparing uncomparable type " + .string()))
}
if isDirectIface() {
return ==
}
return (, )
}
func ( string, uintptr) uintptr {
return strhash(noescape(unsafe.Pointer(&)), )
}
func ( []byte, uintptr) uintptr {
:= (*slice)(unsafe.Pointer(&))
return memhash(.array, , uintptr(.len))
}
func ( uint32, uintptr) uintptr {
return memhash32(noescape(unsafe.Pointer(&)), )
}
func ( uint64, uintptr) uintptr {
return memhash64(noescape(unsafe.Pointer(&)), )
}
func ( interface{}, uintptr) uintptr {
return nilinterhash(noescape(unsafe.Pointer(&)), )
}
func ( interface {
()
}, uintptr) uintptr {
return interhash(noescape(unsafe.Pointer(&)), )
}
const hashRandomBytes = sys.PtrSize / 4 * 64
var aeskeysched [hashRandomBytes]byte
var hashkey [4]uintptr
func () {
if (GOARCH == "386" || GOARCH == "amd64") &&
cpu.X86.HasAES &&
cpu.X86.HasSSSE3 &&
cpu.X86.HasSSE41 {
initAlgAES()
return
}
if GOARCH == "arm64" && cpu.ARM64.HasAES {
initAlgAES()
return
}
getRandomData((*[len(hashkey) * sys.PtrSize]byte)(unsafe.Pointer(&hashkey))[:])
hashkey[0] |= 1
hashkey[1] |= 1
hashkey[2] |= 1
hashkey[3] |= 1
}
func () {
useAeshash = true
getRandomData(aeskeysched[:])
}
func ( unsafe.Pointer) uint32 {
:= (*[4]byte)()
if sys.BigEndian {
return uint32([3]) | uint32([2])<<8 | uint32([1])<<16 | uint32([0])<<24
}
return uint32([0]) | uint32([1])<<8 | uint32([2])<<16 | uint32([3])<<24
}
func ( unsafe.Pointer) uint64 {
:= (*[8]byte)()
if sys.BigEndian {
return uint64([7]) | uint64([6])<<8 | uint64([5])<<16 | uint64([4])<<24 |
uint64([3])<<32 | uint64([2])<<40 | uint64([1])<<48 | uint64([0])<<56
}
return uint64([0]) | uint64([1])<<8 | uint64([2])<<16 | uint64([3])<<24 | uint64([4])<<32 | uint64([5])<<40 | uint64([6])<<48 | uint64([7])<<56
}