mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 15:34:09 +00:00
use dump but fast function for whole string hashing
it fits into i386 registers, and consumes more than 2 bytes per cycle (on Haswell) + add check for hashsum equality in chain traversion.
This commit is contained in:
parent
ac42037db0
commit
ba922dbe0b
17
src/lj_str.c
17
src/lj_str.c
@ -130,7 +130,18 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
|
|||||||
lj_err_msg(L, LJ_ERR_STROV);
|
lj_err_msg(L, LJ_ERR_STROV);
|
||||||
g = G(L);
|
g = G(L);
|
||||||
/* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
|
/* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
|
||||||
if (len >= 4) { /* Caveat: unaligned access! */
|
if (len >= 12) { /* Caveat: unaligned access! */
|
||||||
|
MSize i = (len-1)/8;
|
||||||
|
const char *ss;
|
||||||
|
a = lj_getu32(str+len-8);
|
||||||
|
b = lj_getu32(str+len-4);
|
||||||
|
ss = str;
|
||||||
|
for (; i; i--, ss += 8) {
|
||||||
|
h = lj_rol(h ^ a, 17) + (b ^ 0xdeadbeef);
|
||||||
|
a = lj_rol(a, 13); a -= lj_getu32(ss);
|
||||||
|
b = lj_rol(b, 11); b -= lj_getu32(ss+4);
|
||||||
|
}
|
||||||
|
} else if (len >= 4) { /* Caveat: unaligned access! */
|
||||||
a = lj_getu32(str);
|
a = lj_getu32(str);
|
||||||
h ^= lj_getu32(str+len-4);
|
h ^= lj_getu32(str+len-4);
|
||||||
b = lj_getu32(str+(len>>1)-2);
|
b = lj_getu32(str+(len>>1)-2);
|
||||||
@ -152,7 +163,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
|
|||||||
if (LJ_LIKELY((((uintptr_t)str+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) {
|
if (LJ_LIKELY((((uintptr_t)str+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) {
|
||||||
while (o != NULL) {
|
while (o != NULL) {
|
||||||
GCstr *sx = gco2str(o);
|
GCstr *sx = gco2str(o);
|
||||||
if (sx->len == len && str_fastcmp(str, strdata(sx), len) == 0) {
|
if (sx->hash == h && sx->len == len && str_fastcmp(str, strdata(sx), len) == 0) {
|
||||||
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
|
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
|
||||||
if (isdead(g, o)) flipwhite(o);
|
if (isdead(g, o)) flipwhite(o);
|
||||||
return sx; /* Return existing string. */
|
return sx; /* Return existing string. */
|
||||||
@ -162,7 +173,7 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
|
|||||||
} else { /* Slow path: end of string is too close to a page boundary. */
|
} else { /* Slow path: end of string is too close to a page boundary. */
|
||||||
while (o != NULL) {
|
while (o != NULL) {
|
||||||
GCstr *sx = gco2str(o);
|
GCstr *sx = gco2str(o);
|
||||||
if (sx->len == len && memcmp(str, strdata(sx), len) == 0) {
|
if (sx->hash == h && sx->len == len && memcmp(str, strdata(sx), len) == 0) {
|
||||||
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
|
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
|
||||||
if (isdead(g, o)) flipwhite(o);
|
if (isdead(g, o)) flipwhite(o);
|
||||||
return sx; /* Return existing string. */
|
return sx; /* Return existing string. */
|
||||||
|
Loading…
Reference in New Issue
Block a user