aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime/alg.goc
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/alg.goc')
-rw-r--r--src/pkg/runtime/alg.goc221
1 files changed, 46 insertions, 175 deletions
diff --git a/src/pkg/runtime/alg.goc b/src/pkg/runtime/alg.goc
index cb8e073151..70c877ebbb 100644
--- a/src/pkg/runtime/alg.goc
+++ b/src/pkg/runtime/alg.goc
@@ -7,34 +7,7 @@ package runtime
#include "type.h"
#include "../../cmd/ld/textflag.h"
-#define M0 (sizeof(uintptr)==4 ? 2860486313UL : 33054211828000289ULL)
-#define M1 (sizeof(uintptr)==4 ? 3267000013UL : 23344194077549503ULL)
-
-static bool use_aeshash;
-
-/*
- * map and chan helpers for
- * dealing with unknown types
- */
-void
-runtime·memhash(uintptr *h, uintptr s, void *a)
-{
- byte *b;
- uintptr hash;
- if(!NaCl && use_aeshash) {
- runtime·aeshash(h, s, a);
- return;
- }
-
- b = a;
- hash = M0 ^ *h;
- while(s > 0) {
- hash = (hash ^ *b) * M1;
- b++;
- s--;
- }
- *h = hash;
-}
+bool runtime·use_aeshash;
void
runtime·memequal(bool *eq, uintptr s, void *a, void *b)
@@ -224,67 +197,6 @@ runtime·c128equal(bool *eq, uintptr s, void *a, void *b)
*eq = ca->real == cb->real && ca->imag == cb->imag;
}
-// NOTE: Because NaN != NaN, a map can contain any
-// number of (mostly useless) entries keyed with NaNs.
-// To avoid long hash chains, we assign a random number
-// as the hash value for a NaN.
-
-void
-runtime·f32hash(uintptr *h, uintptr s, void *a)
-{
- uintptr hash;
- float32 f;
-
- USED(s);
- f = *(float32*)a;
- if(f == 0)
- hash = 0; // +0, -0
- else if(f != f)
- hash = runtime·fastrand1(); // any kind of NaN
- else
- hash = *(uint32*)a;
- *h = (*h ^ hash ^ M0) * M1;
-}
-
-void
-runtime·f64hash(uintptr *h, uintptr s, void *a)
-{
- uintptr hash;
- float64 f;
- uint64 u;
-
- USED(s);
- f = *(float64*)a;
- if(f == 0)
- hash = 0; // +0, -0
- else if(f != f)
- hash = runtime·fastrand1(); // any kind of NaN
- else {
- u = *(uint64*)a;
- if(sizeof(uintptr) == 4)
- hash = ((uint32)(u>>32) * M1) ^ (uint32)u;
- else
- hash = u;
- }
- *h = (*h ^ hash ^ M0) * M1;
-}
-
-void
-runtime·c64hash(uintptr *h, uintptr s, void *a)
-{
- USED(s);
- runtime·f32hash(h, 0, a);
- runtime·f32hash(h, 0, (float32*)a+1);
-}
-
-void
-runtime·c128hash(uintptr *h, uintptr s, void *a)
-{
- USED(s);
- runtime·f64hash(h, 0, a);
- runtime·f64hash(h, 0, (float64*)a+1);
-}
-
void
runtime·algslicecopy(uintptr s, void *a, void *b)
{
@@ -301,13 +213,6 @@ runtime·algslicecopy(uintptr s, void *a, void *b)
}
void
-runtime·strhash(uintptr *h, uintptr s, void *a)
-{
- USED(s);
- runtime·memhash(h, ((String*)a)->len, ((String*)a)->str);
-}
-
-void
runtime·strequal(bool *eq, uintptr s, void *a, void *b)
{
intgo alen;
@@ -349,13 +254,6 @@ runtime·strcopy(uintptr s, void *a, void *b)
}
void
-runtime·interhash(uintptr *h, uintptr s, void *a)
-{
- USED(s);
- *h = runtime·ifacehash(*(Iface*)a, *h ^ M0) * M1;
-}
-
-void
runtime·interprint(uintptr s, void *a)
{
USED(s);
@@ -383,13 +281,6 @@ runtime·intercopy(uintptr s, void *a, void *b)
}
void
-runtime·nilinterhash(uintptr *h, uintptr s, void *a)
-{
- USED(s);
- *h = runtime·efacehash(*(Eface*)a, *h ^ M0) * M1;
-}
-
-void
runtime·nilinterprint(uintptr s, void *a)
{
USED(s);
@@ -416,15 +307,6 @@ runtime·nilintercopy(uintptr s, void *a, void *b)
((Eface*)a)->data = ((Eface*)b)->data;
}
-void
-runtime·nohash(uintptr *h, uintptr s, void *a)
-{
- USED(s);
- USED(a);
- USED(h);
- runtime·panicstring("hash of unhashable type");
-}
-
extern uintptr runtime·nohashcode;
void
@@ -437,31 +319,46 @@ runtime·noequal(bool *eq, uintptr s, void *a, void *b)
runtime·panicstring("comparing uncomparable types");
}
+static FuncVal memhashfunc = {(void*)runtime·memhash};
+static FuncVal nohashfunc = {(void*)runtime·nohash};
+static FuncVal strhashfunc = {(void*)runtime·strhash};
+static FuncVal interhashfunc = {(void*)runtime·interhash};
+static FuncVal nilinterhashfunc = {(void*)runtime·nilinterhash};
+static FuncVal f32hashfunc = {(void*)runtime·f32hash};
+static FuncVal f64hashfunc = {(void*)runtime·f64hash};
+static FuncVal c64hashfunc = {(void*)runtime·c64hash};
+static FuncVal c128hashfunc = {(void*)runtime·c128hash};
+
+static FuncVal aeshashfunc = {(void*)runtime·aeshash};
+static FuncVal aeshash32func = {(void*)runtime·aeshash32};
+static FuncVal aeshash64func = {(void*)runtime·aeshash64};
+static FuncVal aeshashstrfunc = {(void*)runtime·aeshashstr};
+
Alg
runtime·algarray[] =
{
-[AMEM] { runtime·memhash, runtime·memequal, runtime·memprint, runtime·memcopy },
-[ANOEQ] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy },
-[ASTRING] { runtime·strhash, runtime·strequal, runtime·strprint, runtime·strcopy },
-[AINTER] { runtime·interhash, runtime·interequal, runtime·interprint, runtime·intercopy },
-[ANILINTER] { runtime·nilinterhash, runtime·nilinterequal, runtime·nilinterprint, runtime·nilintercopy },
-[ASLICE] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·algslicecopy },
-[AFLOAT32] { runtime·f32hash, runtime·f32equal, runtime·memprint, runtime·memcopy },
-[AFLOAT64] { runtime·f64hash, runtime·f64equal, runtime·memprint, runtime·memcopy },
-[ACPLX64] { runtime·c64hash, runtime·c64equal, runtime·memprint, runtime·memcopy },
-[ACPLX128] { runtime·c128hash, runtime·c128equal, runtime·memprint, runtime·memcopy },
-[AMEM0] { runtime·memhash, runtime·memequal0, runtime·memprint, runtime·memcopy0 },
-[AMEM8] { runtime·memhash, runtime·memequal8, runtime·memprint, runtime·memcopy8 },
-[AMEM16] { runtime·memhash, runtime·memequal16, runtime·memprint, runtime·memcopy16 },
-[AMEM32] { runtime·memhash, runtime·memequal32, runtime·memprint, runtime·memcopy32 },
-[AMEM64] { runtime·memhash, runtime·memequal64, runtime·memprint, runtime·memcopy64 },
-[AMEM128] { runtime·memhash, runtime·memequal128, runtime·memprint, runtime·memcopy128 },
-[ANOEQ0] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy0 },
-[ANOEQ8] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy8 },
-[ANOEQ16] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy16 },
-[ANOEQ32] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy32 },
-[ANOEQ64] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy64 },
-[ANOEQ128] { runtime·nohash, runtime·noequal, runtime·memprint, runtime·memcopy128 },
+[AMEM] { &memhashfunc, runtime·memequal, runtime·memprint, runtime·memcopy },
+[ANOEQ] { &nohashfunc, runtime·noequal, runtime·memprint, runtime·memcopy },
+[ASTRING] { &strhashfunc, runtime·strequal, runtime·strprint, runtime·strcopy },
+[AINTER] { &interhashfunc, runtime·interequal, runtime·interprint, runtime·intercopy },
+[ANILINTER] { &nilinterhashfunc, runtime·nilinterequal, runtime·nilinterprint, runtime·nilintercopy },
+[ASLICE] { &nohashfunc, runtime·noequal, runtime·memprint, runtime·algslicecopy },
+[AFLOAT32] { &f32hashfunc, runtime·f32equal, runtime·memprint, runtime·memcopy },
+[AFLOAT64] { &f64hashfunc, runtime·f64equal, runtime·memprint, runtime·memcopy },
+[ACPLX64] { &c64hashfunc, runtime·c64equal, runtime·memprint, runtime·memcopy },
+[ACPLX128] { &c128hashfunc, runtime·c128equal, runtime·memprint, runtime·memcopy },
+[AMEM0] { &memhashfunc, runtime·memequal0, runtime·memprint, runtime·memcopy0 },
+[AMEM8] { &memhashfunc, runtime·memequal8, runtime·memprint, runtime·memcopy8 },
+[AMEM16] { &memhashfunc, runtime·memequal16, runtime·memprint, runtime·memcopy16 },
+[AMEM32] { &memhashfunc, runtime·memequal32, runtime·memprint, runtime·memcopy32 },
+[AMEM64] { &memhashfunc, runtime·memequal64, runtime·memprint, runtime·memcopy64 },
+[AMEM128] { &memhashfunc, runtime·memequal128, runtime·memprint, runtime·memcopy128 },
+[ANOEQ0] { &nohashfunc, runtime·noequal, runtime·memprint, runtime·memcopy0 },
+[ANOEQ8] { &nohashfunc, runtime·noequal, runtime·memprint, runtime·memcopy8 },
+[ANOEQ16] { &nohashfunc, runtime·noequal, runtime·memprint, runtime·memcopy16 },
+[ANOEQ32] { &nohashfunc, runtime·noequal, runtime·memprint, runtime·memcopy32 },
+[ANOEQ64] { &nohashfunc, runtime·noequal, runtime·memprint, runtime·memcopy64 },
+[ANOEQ128] { &nohashfunc, runtime·noequal, runtime·memprint, runtime·memcopy128 },
};
// Runtime helpers.
@@ -483,15 +380,14 @@ runtime·hashinit(void)
(runtime·cpuid_ecx & (1 << 19)) != 0) { // sse4.1 (pinsr{d,q})
byte *rnd;
int32 n;
- use_aeshash = true;
- runtime·algarray[AMEM].hash = runtime·aeshash;
- runtime·algarray[AMEM8].hash = runtime·aeshash;
- runtime·algarray[AMEM16].hash = runtime·aeshash;
- runtime·algarray[AMEM32].hash = runtime·aeshash32;
- runtime·algarray[AMEM64].hash = runtime·aeshash64;
- runtime·algarray[AMEM128].hash = runtime·aeshash;
- runtime·algarray[ASTRING].hash = runtime·aeshashstr;
-
+ runtime·use_aeshash = true;
+ runtime·algarray[AMEM].hash = &aeshashfunc;
+ runtime·algarray[AMEM8].hash = &aeshashfunc;
+ runtime·algarray[AMEM16].hash = &aeshashfunc;
+ runtime·algarray[AMEM32].hash = &aeshash32func;
+ runtime·algarray[AMEM64].hash = &aeshash64func;
+ runtime·algarray[AMEM128].hash = &aeshashfunc;
+ runtime·algarray[ASTRING].hash = &aeshashstrfunc;
// Initialize with random data so hash collisions will be hard to engineer.
runtime·get_random_data(&rnd, &n);
if(n > HashRandomBytes)
@@ -525,28 +421,3 @@ runtime·equal(Type *t, ...)
func memclrBytes(s Slice) {
runtime·memclr(s.array, s.len);
}
-
-// Testing adapters for hash quality tests (see hash_test.go)
-func haveGoodHash() (res bool) {
- res = use_aeshash;
-}
-
-func stringHash(s String, seed uintptr) (res uintptr) {
- runtime·algarray[ASTRING].hash(&seed, sizeof(String), &s);
- res = seed;
-}
-
-func bytesHash(s Slice, seed uintptr) (res uintptr) {
- runtime·algarray[AMEM].hash(&seed, s.len, s.array);
- res = seed;
-}
-
-func int32Hash(i uint32, seed uintptr) (res uintptr) {
- runtime·algarray[AMEM32].hash(&seed, sizeof(uint32), &i);
- res = seed;
-}
-
-func int64Hash(i uint64, seed uintptr) (res uintptr) {
- runtime·algarray[AMEM64].hash(&seed, sizeof(uint64), &i);
- res = seed;
-}