diff -bur LuaJIT-2.1.0-beta3-orig/src/lj_str.c LuaJIT-2.1.0-beta3/src/lj_str.c --- LuaJIT-2.1.0-beta3-orig/src/lj_str.c 2017-05-01 21:05:00.000000000 +0200 +++ LuaJIT-2.1.0-beta3/src/lj_str.c 2017-06-19 18:20:09.668443066 +0200 @@ -118,6 +118,16 @@ g->strhash = newhash; } +/* +** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to +** compute its hash +*/ +#if !defined(LUAI_HASHLIMIT) +#define LUAI_HASHLIMIT 5 +#endif + +#define cast(t, exp) ((t)(exp)) +int luajittex_choose_hash_function = 0 ; /* Intern a string and return string object. */ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx) { @@ -126,9 +136,22 @@ GCobj *o; MSize len = (MSize)lenx; MSize a, b, h = len; + size_t step ; + size_t l1 ; if (lenx >= LJ_MAX_STR) lj_err_msg(L, LJ_ERR_STROV); g = G(L); + + if (len==0) + return &g->strempty; + if (luajittex_choose_hash_function==0) { + /* Lua 5.1.5 hash function */ + /* for 5.2 max methods we also need to patch the vm eq */ + step = (len>>LUAI_HASHLIMIT)+1; /* if string is too long, don't hash all its chars */ + for (l1=len; l1>=step; l1-=step) /* compute hash */ + h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); + } else { + /* LuaJIT 2.0.2 hash function */ /* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */ if (len >= 4) { /* Caveat: unaligned access! */ a = lj_getu32(str); @@ -142,11 +165,15 @@ b = *(const uint8_t *)(str+(len>>1)); h ^= b; h -= lj_rol(b, 14); } else { + /* Already done, kept for reference */ return &g->strempty; } a ^= h; a -= lj_rol(h, 11); b ^= a; b -= lj_rol(a, 25); h ^= b; h -= lj_rol(b, 16); + } + + /* Check if the string has already been interned. */ o = gcref(g->strhash[h & g->strmask]); if (LJ_LIKELY((((uintptr_t)str+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) {