Skip to content

Commit

Permalink
Merge pull request snabbco#150 from lukego/reoptimize-string-intern
Browse files Browse the repository at this point in the history
lj_str.c: Remove special-case string interning fast-path
  • Loading branch information
lukego committed Jan 15, 2018
2 parents b53a438 + fcf86b8 commit 9de778c
Showing 1 changed file with 7 additions and 40 deletions.
47 changes: 7 additions & 40 deletions src/lj_str.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,6 @@ int32_t lj_str_cmp(GCstr *a, GCstr *b)
return (int32_t)(a->len - b->len);
}

/* Fast string data comparison. Caveat: unaligned access to 1st string! */
static LJ_AINLINE int str_fastcmp(const char *a, const char *b, MSize len)
{
MSize i = 0;
lua_assert(len > 0);
lua_assert((((uintptr_t)a+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4);
do { /* Note: innocuous access up to end of string + 3. */
uint32_t v = lj_getu32(a+i) ^ *(const uint32_t *)(b+i);
if (v) {
i -= len;
#if LJ_LE
return (int32_t)i >= -3 ? (v << (32+(i<<3))) : 1;
#else
return (int32_t)i >= -3 ? (v >> (32+(i<<3))) : 1;
#endif
}
i += 4;
} while (i < len);
return 0;
}

/* Find fixed string p inside string s. */
const char *lj_str_find(const char *s, const char *p, MSize slen, MSize plen)
{
Expand Down Expand Up @@ -149,26 +128,14 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
h ^= b; h -= lj_rol(b, 16);
/* Check if the string has already been interned. */
o = gcref(g->strhash[h & g->strmask]);
if (LJ_LIKELY((((uintptr_t)str+len-1) & (LJ_PAGESIZE-1)) <= LJ_PAGESIZE-4)) {
while (o != NULL) {
GCstr *sx = gco2str(o);
if (sx->len == len && str_fastcmp(str, strdata(sx), len) == 0) {
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
return sx; /* Return existing string. */
}
o = gcnext(o);
}
} else { /* Slow path: end of string is too close to a page boundary. */
while (o != NULL) {
GCstr *sx = gco2str(o);
if (sx->len == len && memcmp(str, strdata(sx), len) == 0) {
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
return sx; /* Return existing string. */
}
o = gcnext(o);
while (o != NULL) {
GCstr *sx = gco2str(o);
if (sx->len == len && memcmp(str, strdata(sx), len) == 0) {
/* Resurrect if dead. Can only happen with fixstring() (keywords). */
if (isdead(g, o)) flipwhite(o);
return sx; /* Return existing string. */
}
o = gcnext(o);
}
/* Nope, create a new string. */
s = lj_mem_newt(L, sizeof(GCstr)+len+1, GCstr);
Expand Down

0 comments on commit 9de778c

Please sign in to comment.