]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Abstract out pointer hash to hashrot(). Tune hash constants.
authorMike Pall <mike>
Wed, 21 Jul 2010 19:42:40 +0000 (21:42 +0200)
committerMike Pall <mike>
Wed, 21 Jul 2010 20:06:38 +0000 (22:06 +0200)
src/lj_asm.c
src/lj_record.c
src/lj_tab.c
src/lj_tab.h

index 4070ccb392e3ea76741d5de0580c8270de29e261..56b39e32ed488744fb58b3bcba4c1fd771b80eae 100644 (file)
@@ -1572,7 +1572,7 @@ static void asm_aref(ASMState *as, IRIns *ir)
     emit_rr(as, XO_MOV, dest, as->mrm.base);
 }
 
-/* Must match with hashkey() and hashrot() in lj_tab.c. */
+/* Must match with hash*() in lj_tab.c. */
 static uint32_t ir_khash(IRIns *ir)
 {
   uint32_t lo, hi;
@@ -1587,12 +1587,9 @@ static uint32_t ir_khash(IRIns *ir)
   } else {
     lua_assert(irt_isgcv(ir->t));
     lo = u32ptr(ir_kgc(ir));
-    hi = lo - 0x04c11db7;
+    hi = lo + HASH_BIAS;
   }
-  lo ^= hi; hi = lj_rol(hi, 14);
-  lo -= hi; hi = lj_rol(hi, 5);
-  hi ^= lo; hi -= lj_rol(lo, 27);
-  return hi;
+  return hashrot(lo, hi);
 }
 
 /* Merge NE(HREF, niltv) check. */
@@ -1717,11 +1714,11 @@ static void asm_href(ASMState *as, IRIns *ir)
     } else {  /* Must match with hashrot() in lj_tab.c. */
       emit_rmro(as, XO_ARITH(XOg_AND), dest, tab, offsetof(GCtab, hmask));
       emit_rr(as, XO_ARITH(XOg_SUB), dest, tmp);
-      emit_shifti(as, XOg_ROL, tmp, 27);
+      emit_shifti(as, XOg_ROL, tmp, HASH_ROT3);
       emit_rr(as, XO_ARITH(XOg_XOR), dest, tmp);
-      emit_shifti(as, XOg_ROL, dest, 5);
+      emit_shifti(as, XOg_ROL, dest, HASH_ROT2);
       emit_rr(as, XO_ARITH(XOg_SUB), tmp, dest);
-      emit_shifti(as, XOg_ROL, dest, 14);
+      emit_shifti(as, XOg_ROL, dest, HASH_ROT1);
       emit_rr(as, XO_ARITH(XOg_XOR), tmp, dest);
       if (irt_isnum(kt)) {
        emit_rr(as, XO_ARITH(XOg_ADD), dest, dest);
@@ -1735,7 +1732,7 @@ static void asm_href(ASMState *as, IRIns *ir)
 #endif
       } else {
        emit_rr(as, XO_MOV, tmp, key);
-       emit_rmro(as, XO_LEA, dest, key, -0x04c11db7);
+       emit_rmro(as, XO_LEA, dest, key, HASH_BIAS);
       }
     }
   }
index 55daaae6315551af9fd9d0291747e97c009b9c89..9355cb38516043834ce8fcb6b03da2c309cfde33 100644 (file)
@@ -1051,15 +1051,6 @@ static TRef rec_idx(jit_State *J, RecordIndex *ix)
 
 /* -- Upvalue access ------------------------------------------------------ */
 
-/* Shrink disambiguation hash into an 8 bit value. */
-static uint32_t shrink_dhash(uint32_t lo, uint32_t hi)
-{
-  lo ^= hi; hi = lj_rol(hi, 14);
-  lo -= hi; hi = lj_rol(hi, 5);
-  hi ^= lo; hi -= lj_rol(lo, 27);
-  return (hi & 0xff);
-}
-
 /* Record upvalue load/store. */
 static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
 {
@@ -1068,7 +1059,7 @@ static TRef rec_upvalue(jit_State *J, uint32_t uv, TRef val)
   IRRef uref;
   int needbarrier = 0;
   /* Note: this effectively limits LJ_MAX_UPVAL to 127. */
-  uv = (uv << 8) | shrink_dhash(uvp->dhash, uvp->dhash-0x04c11db7);
+  uv = (uv << 8) | (hashrot(uvp->dhash, uvp->dhash + HASH_BIAS) & 0xff);
   if (!uvp->closed) {
     /* In current stack? */
     if (uvval(uvp) >= J->L->stack && uvval(uvp) < J->L->maxstack) {
index 006a87ffd52c08b5508004a1e101c94af9af7cba..d6175bbd746638a818c46f435149ffca5a760a3e 100644 (file)
 /* -- Object hashing ------------------------------------------------------ */
 
 /* Hash values are masked with the table hash mask and used as an index. */
-#define hashmask(t, x)         (&noderef(t->node)[(x) & t->hmask])
+static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash)
+{
+  Node *n = noderef(t->node);
+  return &n[hash & t->hmask];
+}
 
 /* String hashes are precomputed when they are interned. */
 #define hashstr(t, s)          hashmask(t, (s)->hash)
 
-#define hashnum(t, o)          hashrot(t, (o)->u32.lo, ((o)->u32.hi << 1))
-#define hashgcref(t, r)                hashrot(t, gcrefu(r), gcrefu(r)-0x04c11db7)
-
-/* Scramble the bits of numbers and pointers. */
-static LJ_AINLINE Node *hashrot(const GCtab *t, uint32_t lo, uint32_t hi)
-{
-  lo ^= hi; hi = lj_rol(hi, 14);
-  lo -= hi; hi = lj_rol(hi, 5);
-  hi ^= lo; hi -= lj_rol(lo, 27);
-  return hashmask(t, hi);
-}
+#define hashlohi(t, lo, hi)    hashmask((t), hashrot((lo), (hi)))
+#define hashnum(t, o)          hashlohi((t), (o)->u32.lo, ((o)->u32.hi << 1))
+#define hashptr(t, p)          hashlohi((t), u32ptr(p), u32ptr(p) + HASH_BIAS)
+#define hashgcref(t, r)                hashlohi((t), gcrefu(r), gcrefu(r) + HASH_BIAS)
 
 /* Hash an arbitrary key and return its anchor position in the hash table. */
 static Node *hashkey(const GCtab *t, cTValue *key)
index f8ace6c1b8b359edc3782fd961e1f1a101a0d354..d18c604ee5777a101906c55cb8198110677bfbc5 100644 (file)
@@ -8,6 +8,21 @@
 
 #include "lj_obj.h"
 
+/* Hash constants. Tuned using a brute force search. */
+#define HASH_BIAS      (-0x04c11db7)
+#define HASH_ROT1      14
+#define HASH_ROT2      5
+#define HASH_ROT3      13
+
+/* Scramble the bits of numbers and pointers. */
+static LJ_AINLINE uint32_t hashrot(uint32_t lo, uint32_t hi)
+{
+  lo ^= hi; hi = lj_rol(hi, HASH_ROT1);
+  lo -= hi; hi = lj_rol(hi, HASH_ROT2);
+  hi ^= lo; hi -= lj_rol(lo, HASH_ROT3);
+  return hi;
+}
+
 #define hsize2hbits(s) ((s) ? ((s)==1 ? 1 : 1+lj_fls((uint32_t)((s)-1))) : 0)
 
 LJ_FUNCA GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits);