Просмотр исходного кода

Abstract out pointer hash to hashrot(). Tune hash constants.

Mike Pall 15 лет назад
Родитель
Сommit
d05873ee0a
4 измененных файлов с 32 добавлено и 32 удалено
  1. 7 10
      src/lj_asm.c
  2. 1 10
      src/lj_record.c
  3. 9 12
      src/lj_tab.c
  4. 15 0
      src/lj_tab.h

+ 7 - 10
src/lj_asm.c

@@ -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);
       }
     }
   }

+ 1 - 10
src/lj_record.c

@@ -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) {

+ 9 - 12
src/lj_tab.c

@@ -17,22 +17,19 @@
 /* -- 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)

+ 15 - 0
src/lj_tab.h

@@ -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);