Inline-Lua
view release on metacpan or search on metacpan
ffi/target/release/build/mlua-sys-6a99a2ae50f12319/out/luajit-build/build/src/lj_str.c view on Meta::CPAN
#if LUAJIT_SECURITY_STRHASH
uintptr_t u;
if (LJ_LIKELY(!s->hashalg)) { /* String hashed with primary hash. */
hash &= newmask;
u = gcrefu(newtab[hash]);
if (LJ_UNLIKELY(u & 1)) { /* Switch string to secondary hash. */
s->hash = hash = hash_dense(g->str.seed, s->hash, strdata(s), s->len);
s->hashalg = 1;
hash &= newmask;
u = gcrefu(newtab[hash]);
}
} else { /* String hashed with secondary hash. */
MSize shash = hash_sparse(g->str.seed, strdata(s), s->len);
u = gcrefu(newtab[shash & newmask]);
if (u & 1) {
hash &= newmask;
u = gcrefu(newtab[hash]);
} else { /* Revert string back to primary hash. */
s->hash = shash;
s->hashalg = 0;
hash = (shash & newmask);
}
}
/* NOBARRIER: The string table is a GC root. */
setgcrefp(o->gch.nextgc, (u & ~(uintptr_t)1));
setgcrefp(newtab[hash], ((uintptr_t)o | (u & 1)));
#else
hash &= newmask;
/* NOBARRIER: The string table is a GC root. */
setgcrefr(o->gch.nextgc, newtab[hash]);
setgcref(newtab[hash], o);
#endif
o = next;
}
}
/* Free old table and replace with new table. */
lj_str_freetab(g);
g->str.tab = newtab;
g->str.mask = newmask;
}
#if LUAJIT_SECURITY_STRHASH
/* Rehash and rechain all strings in a chain. */
static LJ_NOINLINE GCstr *lj_str_rehash_chain(lua_State *L, StrHash hashc,
const char *str, MSize len)
{
global_State *g = G(L);
int ow = g->gc.state == GCSsweepstring ? otherwhite(g) : 0; /* Sweeping? */
GCRef *strtab = g->str.tab;
MSize strmask = g->str.mask;
GCobj *o = gcref(strtab[hashc & strmask]);
setgcrefp(strtab[hashc & strmask], (void *)((uintptr_t)1));
g->str.second = 1;
while (o) {
uintptr_t u;
GCobj *next = gcnext(o);
GCstr *s = gco2str(o);
StrHash hash;
if (ow) { /* Must sweep while rechaining. */
if (((o->gch.marked ^ LJ_GC_WHITES) & ow)) { /* String alive? */
lj_assertG(!isdead(g, o) || (o->gch.marked & LJ_GC_FIXED),
"sweep of undead string");
makewhite(g, o);
} else { /* Free dead string. */
lj_assertG(isdead(g, o) || ow == LJ_GC_SFIXED,
"sweep of unlive string");
lj_str_free(g, s);
o = next;
continue;
}
}
hash = s->hash;
if (!s->hashalg) { /* Rehash with secondary hash. */
hash = hash_dense(g->str.seed, hash, strdata(s), s->len);
s->hash = hash;
s->hashalg = 1;
}
/* Rechain. */
hash &= strmask;
u = gcrefu(strtab[hash]);
setgcrefp(o->gch.nextgc, (u & ~(uintptr_t)1));
setgcrefp(strtab[hash], ((uintptr_t)o | (u & 1)));
o = next;
}
/* Try to insert the pending string again. */
return lj_str_new(L, str, len);
}
#endif
/* Reseed String ID from PRNG after random interval < 2^bits. */
#if LUAJIT_SECURITY_STRID == 1
#define STRID_RESEED_INTERVAL 8
#elif LUAJIT_SECURITY_STRID == 2
#define STRID_RESEED_INTERVAL 4
#elif LUAJIT_SECURITY_STRID >= 3
#define STRID_RESEED_INTERVAL 0
#endif
/* Allocate a new string and add to string interning table. */
static GCstr *lj_str_alloc(lua_State *L, const char *str, MSize len,
StrHash hash, int hashalg)
{
GCstr *s = lj_mem_newt(L, lj_str_size(len), GCstr);
global_State *g = G(L);
uintptr_t u;
newwhite(g, s);
s->gct = ~LJ_TSTR;
s->len = len;
s->hash = hash;
#ifndef STRID_RESEED_INTERVAL
s->sid = g->str.id++;
#elif STRID_RESEED_INTERVAL
if (!g->str.idreseed--) {
uint64_t r = lj_prng_u64(&g->prng);
g->str.id = (StrID)r;
g->str.idreseed = (uint8_t)(r >> (64 - STRID_RESEED_INTERVAL));
}
s->sid = g->str.id++;
#else
s->sid = (StrID)lj_prng_u64(&g->prng);
( run in 3.050 seconds using v1.01-cache-2.11-cpan-99c4e6809bf )