special case for long strings and x86_64

This commit is contained in:
Sokolov Yura aka funny_falcon 2016-04-28 19:17:00 +03:00
parent ba922dbe0b
commit c958b87d85

View File

@ -130,6 +130,27 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
lj_err_msg(L, LJ_ERR_STROV);
g = G(L);
/* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
#if LJ_ARCH_BITS == 64 && LJ_TARGET_UNALIGNED
if (LJ_UNLIKELY(len > 128)) {
MSize i = (len-1)/16;
const char *ss;
uint64_t h1 = *(uint64_t*)(str+len-8);
uint64_t h2 = *(uint64_t*)(str+len-16);
uint64_t h3 = len;
ss = str;
for (; i; i--, ss += 16) {
h3 = lj_rol(h3 ^ h1, 33) + (h2 ^ 0xdeadbeef);
h1 = lj_rol(h1, 23); h1 -= *(uint64_t*)ss;
h2 = lj_rol(h2, 21); h2 -= *(uint64_t*)(ss+8);
}
h1 -= lj_rol(h3, 19);
h2 -= lj_rol(h1, 19);
h3 -= lj_rol(h2, 19);
h = (uint32_t)h3 - (uint32_t)(h1 >> 32);
a = (uint32_t)h1 - (uint32_t)(h2 >> 32);
b = (uint32_t)h2 - (uint32_t)(h3 >> 32);
} else
#endif
if (len >= 12) { /* Caveat: unaligned access! */
MSize i = (len-1)/8;
const char *ss;