aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/alg.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtime/alg.go')
-rw-r--r--src/runtime/alg.go33
1 files changed, 23 insertions, 10 deletions
diff --git a/src/runtime/alg.go b/src/runtime/alg.go
index b956f9d05a..c5951dc20b 100644
--- a/src/runtime/alg.go
+++ b/src/runtime/alg.go
@@ -14,10 +14,23 @@ import (
)
const (
- c0 = uintptr((8-goarch.PtrSize)/4*2860486313 + (goarch.PtrSize-4)/4*33054211828000289)
- c1 = uintptr((8-goarch.PtrSize)/4*3267000013 + (goarch.PtrSize-4)/4*23344194077549503)
+ // We use 32-bit hash on Wasm, see hash32.go.
+ hashSize = (1-goarch.IsWasm)*goarch.PtrSize + goarch.IsWasm*4
+ c0 = uintptr((8-hashSize)/4*2860486313 + (hashSize-4)/4*33054211828000289)
+ c1 = uintptr((8-hashSize)/4*3267000013 + (hashSize-4)/4*23344194077549503)
)
+func trimHash(h uintptr) uintptr {
+ if goarch.IsWasm != 0 {
+ // On Wasm, we use 32-bit hash, despite that uintptr is 64-bit.
+ // memhash* always returns a uintptr with high 32-bit being 0
+ // (see hash32.go). We trim the hash in other places where we
+ // compute the hash manually, e.g. in interhash.
+ return uintptr(uint32(h))
+ }
+ return h
+}
+
func memhash0(p unsafe.Pointer, h uintptr) uintptr {
return h
}
@@ -100,9 +113,9 @@ func f32hash(p unsafe.Pointer, h uintptr) uintptr {
f := *(*float32)(p)
switch {
case f == 0:
- return c1 * (c0 ^ h) // +0, -0
+ return trimHash(c1 * (c0 ^ h)) // +0, -0
case f != f:
- return c1 * (c0 ^ h ^ uintptr(rand())) // any kind of NaN
+ return trimHash(c1 * (c0 ^ h ^ uintptr(rand()))) // any kind of NaN
default:
return memhash(p, h, 4)
}
@@ -112,9 +125,9 @@ func f64hash(p unsafe.Pointer, h uintptr) uintptr {
f := *(*float64)(p)
switch {
case f == 0:
- return c1 * (c0 ^ h) // +0, -0
+ return trimHash(c1 * (c0 ^ h)) // +0, -0
case f != f:
- return c1 * (c0 ^ h ^ uintptr(rand())) // any kind of NaN
+ return trimHash(c1 * (c0 ^ h ^ uintptr(rand()))) // any kind of NaN
default:
return memhash(p, h, 8)
}
@@ -145,9 +158,9 @@ func interhash(p unsafe.Pointer, h uintptr) uintptr {
panic(errorString("hash of unhashable type " + toRType(t).string()))
}
if t.IsDirectIface() {
- return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
+ return trimHash(c1 * typehash(t, unsafe.Pointer(&a.data), h^c0))
} else {
- return c1 * typehash(t, a.data, h^c0)
+ return trimHash(c1 * typehash(t, a.data, h^c0))
}
}
@@ -172,9 +185,9 @@ func nilinterhash(p unsafe.Pointer, h uintptr) uintptr {
panic(errorString("hash of unhashable type " + toRType(t).string()))
}
if t.IsDirectIface() {
- return c1 * typehash(t, unsafe.Pointer(&a.data), h^c0)
+ return trimHash(c1 * typehash(t, unsafe.Pointer(&a.data), h^c0))
} else {
- return c1 * typehash(t, a.data, h^c0)
+ return trimHash(c1 * typehash(t, a.data, h^c0))
}
}