add parser table hash patch

This commit is contained in:
fesily 2023-08-18 16:19:15 +08:00
parent 0cdeb1213d
commit 1c70983df1
5 changed files with 56 additions and 5 deletions

View File

@ -760,10 +760,10 @@ extern void *LJ_WIN_LOADLIBA(const char *path);
#endif #endif
#ifdef LJ_DS #ifdef LJ_DS
#ifdef LUAJIT_SECURITY_STRHASH
#undef LUAJIT_SECURITY_STRHASH #undef LUAJIT_SECURITY_STRHASH
#endif #undef LUAJIT_SECURITY_STRID
#define LUAJIT_SECURITY_STRHASH !LJ_DS #define LUAJIT_SECURITY_STRHASH 0
#define LUAJIT_SECURITY_STRID 0
#endif #endif
#ifndef LJ_DS_LOADBUFFER_PATCH #ifndef LJ_DS_LOADBUFFER_PATCH
@ -778,4 +778,8 @@ extern void *LJ_WIN_LOADLIBA(const char *path);
#define LUA_COMPAT_GFIND LJ_DS #define LUA_COMPAT_GFIND LJ_DS
#endif #endif
#ifndef LJ_DS_STR_HASH_PATCH
#define LJ_DS_STR_HASH_PATCH LJ_DS
#endif
#endif #endif

View File

@ -1730,6 +1730,10 @@ static void expr_table(LexState *ls, ExpDesc *e)
bcreg_reserve(fs, 1); bcreg_reserve(fs, 1);
freg++; freg++;
lex_check(ls, '{'); lex_check(ls, '{');
#if LJ_DS_PARSER_TABLE_PATCH
GCtab* tmp_t = lj_tab_new(fs->L, 0, 0);
int tmp_indx = 0;
#endif
while (ls->tok != '}') { while (ls->tok != '}') {
ExpDesc key, val; ExpDesc key, val;
vcall = 0; vcall = 0;
@ -1763,6 +1767,12 @@ static void expr_table(LexState *ls, ExpDesc *e)
expr_kvalue(fs, &k, &key); expr_kvalue(fs, &k, &key);
v = lj_tab_set(fs->L, t, &k); v = lj_tab_set(fs->L, t, &k);
lj_gc_anybarriert(fs->L, t); lj_gc_anybarriert(fs->L, t);
#if LJ_DS_PARSER_TABLE_PATCH
TValue* tmp_v = lj_tab_setint(fs->L, tmp_t, tmp_indx);
tmp_indx++;
lj_gc_anybarriert(fs->L, tmp_t);
copyTV(fs->L, tmp_v, &k);
#endif
if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */ if (expr_isk_nojump(&val)) { /* Add const key/value to template table. */
expr_kvalue(fs, v, &val); expr_kvalue(fs, v, &val);
} else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */ } else { /* Otherwise create dummy string key (avoids lj_tab_newkey). */
@ -1811,6 +1821,10 @@ static void expr_table(LexState *ls, ExpDesc *e)
if ((needarr && t->asize != narr) || hsize2hmask(nhash) != t->hmask) { if ((needarr && t->asize != narr) || hsize2hmask(nhash) != t->hmask) {
lj_tab_resize(fs->L, t, narr, hsize2hbits(nhash)); lj_tab_resize(fs->L, t, narr, hsize2hbits(nhash));
} }
if (t->hmask) {
// rebuild hash
lj_tab_rehash_bykeys(fs->L, t, tmp_t);
}
#else #else
if (needarr && t->asize < narr) if (needarr && t->asize < narr)
lj_tab_reasize(fs->L, t, narr-1); lj_tab_reasize(fs->L, t, narr-1);

View File

@ -75,7 +75,7 @@ int lj_str_haspattern(GCstr *s)
/* Keyed sparse ARX string hash. Constant time. */ /* Keyed sparse ARX string hash. Constant time. */
static StrHash hash_sparse(uint64_t seed, const char *str, MSize len) static StrHash hash_sparse(uint64_t seed, const char *str, MSize len)
{ {
#if 0 #if !LJ_DS_STR_HASH_PATCH
/* Constants taken from lookup3 hash by Bob Jenkins. */ /* Constants taken from lookup3 hash by Bob Jenkins. */
StrHash a, b, h = len ^ (StrHash)seed; StrHash a, b, h = len ^ (StrHash)seed;
if (len >= 4) { /* Caveat: unaligned access! */ if (len >= 4) { /* Caveat: unaligned access! */
@ -291,6 +291,9 @@ static GCstr *lj_str_alloc(lua_State *L, const char *str, MSize len,
s->gct = ~LJ_TSTR; s->gct = ~LJ_TSTR;
s->len = len; s->len = len;
s->hash = hash; s->hash = hash;
#if LJ_DS_STR_HASH_PATCH
s->sid = hash;
#else
#ifndef STRID_RESEED_INTERVAL #ifndef STRID_RESEED_INTERVAL
s->sid = g->str.id++; s->sid = g->str.id++;
#elif STRID_RESEED_INTERVAL #elif STRID_RESEED_INTERVAL
@ -302,6 +305,7 @@ static GCstr *lj_str_alloc(lua_State *L, const char *str, MSize len,
s->sid = g->str.id++; s->sid = g->str.id++;
#else #else
s->sid = (StrID)lj_prng_u64(&g->prng); s->sid = (StrID)lj_prng_u64(&g->prng);
#endif
#endif #endif
s->reserved = 0; s->reserved = 0;
s->hashalg = (uint8_t)hashalg; s->hashalg = (uint8_t)hashalg;

View File

@ -374,6 +374,32 @@ void lj_tab_rehash(lua_State *L, GCtab *t)
} }
#endif #endif
#if LJ_DS_PARSER_TABLE_PATCH
void lj_tab_rehash_bykeys(lua_State *L, GCtab *t, GCtab *kt)
{
Node *oldnode = noderef(t->node);
uint32_t oldhmask = t->hmask;
GCtab *tmp = lj_tab_new(L, t->asize, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0);
for (size_t i = 0; i < kt->asize; i++)
{
TValue* k = arrayslot(kt, i);
if (tvisnil(k))
break;
cTValue* val = lj_tab_get(L, t, k);
TValue* tmp_v = lj_tab_set(L, tmp, k);
copyTV(L, tmp_v, val);
}
global_State *g = G(L);
Node* nilNode = &g->nilnode;
setmref(t->node, noderef(tmp->node));
setmref(t->freetop, noderef(tmp->freetop));
setmref(tmp->node, nilNode);
setmref(tmp->freetop, nilNode);
tmp->hmask = 0;
lj_mem_freevec(g, oldnode, oldhmask+1, Node);
}
#endif
void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize) void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize)
{ {
lj_tab_resize(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0); lj_tab_resize(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0);

View File

@ -64,6 +64,9 @@ LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t);
#if LJ_HASFFI #if LJ_HASFFI
LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t); LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t);
#endif #endif
#if LJ_DS_PARSER_TABLE_PATCH
LJ_FUNC void lj_tab_rehash_bykeys(lua_State *L, GCtab *t, GCtab *kt);
#endif
LJ_FUNC void lj_tab_resize(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits); LJ_FUNC void lj_tab_resize(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits);
LJ_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize); LJ_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize);