From 1c70983df1118ba3ab10719032712f199a844381 Mon Sep 17 00:00:00 2001 From: fesily Date: Fri, 18 Aug 2023 16:19:15 +0800 Subject: [PATCH] add parser table hash patch --- src/lj_arch.h | 12 ++++++++---- src/lj_parse.c | 14 ++++++++++++++ src/lj_str.c | 6 +++++- src/lj_tab.c | 26 ++++++++++++++++++++++++++ src/lj_tab.h | 3 +++ 5 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/lj_arch.h b/src/lj_arch.h index 35671072..e5bb63d9 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h @@ -760,10 +760,10 @@ extern void *LJ_WIN_LOADLIBA(const char *path); #endif #ifdef LJ_DS - #ifdef LUAJIT_SECURITY_STRHASH - #undef LUAJIT_SECURITY_STRHASH - #endif -#define LUAJIT_SECURITY_STRHASH !LJ_DS +#undef LUAJIT_SECURITY_STRHASH +#undef LUAJIT_SECURITY_STRID +#define LUAJIT_SECURITY_STRHASH 0 +#define LUAJIT_SECURITY_STRID 0 #endif #ifndef LJ_DS_LOADBUFFER_PATCH @@ -778,4 +778,8 @@ extern void *LJ_WIN_LOADLIBA(const char *path); #define LUA_COMPAT_GFIND LJ_DS #endif +#ifndef LJ_DS_STR_HASH_PATCH +#define LJ_DS_STR_HASH_PATCH LJ_DS +#endif + #endif diff --git a/src/lj_parse.c b/src/lj_parse.c index 675fd228..963ed491 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -1730,6 +1730,10 @@ static void expr_table(LexState *ls, ExpDesc *e) bcreg_reserve(fs, 1); freg++; 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 != '}') { ExpDesc key, val; vcall = 0; @@ -1763,6 +1767,12 @@ static void expr_table(LexState *ls, ExpDesc *e) expr_kvalue(fs, &k, &key); v = lj_tab_set(fs->L, t, &k); 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. */ expr_kvalue(fs, v, &val); } 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) { lj_tab_resize(fs->L, t, narr, hsize2hbits(nhash)); } + if (t->hmask) { + // rebuild hash + lj_tab_rehash_bykeys(fs->L, t, tmp_t); + } #else if (needarr && t->asize < narr) lj_tab_reasize(fs->L, t, narr-1); diff --git a/src/lj_str.c b/src/lj_str.c index dbf555d5..5131ebb1 100644 --- a/src/lj_str.c +++ b/src/lj_str.c @@ -75,7 +75,7 @@ int lj_str_haspattern(GCstr *s) /* Keyed sparse ARX string hash. Constant time. */ 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. */ StrHash a, b, h = len ^ (StrHash)seed; 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->len = len; s->hash = hash; +#if LJ_DS_STR_HASH_PATCH + s->sid = hash; +#else #ifndef STRID_RESEED_INTERVAL s->sid = g->str.id++; #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++; #else s->sid = (StrID)lj_prng_u64(&g->prng); +#endif #endif s->reserved = 0; s->hashalg = (uint8_t)hashalg; diff --git a/src/lj_tab.c b/src/lj_tab.c index 568c0288..bc92bc16 100644 --- a/src/lj_tab.c +++ b/src/lj_tab.c @@ -374,6 +374,32 @@ void lj_tab_rehash(lua_State *L, GCtab *t) } #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) { lj_tab_resize(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0); diff --git a/src/lj_tab.h b/src/lj_tab.h index 611959f5..2015de78 100644 --- a/src/lj_tab.h +++ b/src/lj_tab.h @@ -64,6 +64,9 @@ LJ_FUNC void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t); #if LJ_HASFFI LJ_FUNC void lj_tab_rehash(lua_State *L, GCtab *t); #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_FUNCA void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize);