aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-07-21 22:53:27 +0200
committerMike Pall <mike>2010-07-21 22:53:27 +0200
commit420124372b7643410a1cdd6f80b9cc8aa6ec1302 (patch)
tree6048404974755391eec68a445258639d8d41425e /src
parentd05873ee0ae63ee47710a2c9843d032010cc296f (diff)
downloadluajit-420124372b7643410a1cdd6f80b9cc8aa6ec1302.tar.gz
luajit-420124372b7643410a1cdd6f80b9cc8aa6ec1302.tar.bz2
luajit-420124372b7643410a1cdd6f80b9cc8aa6ec1302.zip
Switch to fast string hash.
Diffstat (limited to 'src')
-rw-r--r--src/lj_gc.c1
-rw-r--r--src/lj_obj.h3
-rw-r--r--src/lj_state.c2
-rw-r--r--src/lj_str.c26
4 files changed, 25 insertions, 7 deletions
diff --git a/src/lj_gc.c b/src/lj_gc.c
index 0f0ca82e..8147cb55 100644
--- a/src/lj_gc.c
+++ b/src/lj_gc.c
@@ -540,6 +540,7 @@ static void atomic(global_State *g, lua_State *L)
540 540
541 /* Prepare for sweep phase. */ 541 /* Prepare for sweep phase. */
542 g->gc.currentwhite = cast_byte(otherwhite(g)); /* Flip current white. */ 542 g->gc.currentwhite = cast_byte(otherwhite(g)); /* Flip current white. */
543 g->strempty.marked = g->gc.currentwhite;
543 setmref(g->gc.sweep, &g->gc.root); 544 setmref(g->gc.sweep, &g->gc.root);
544 g->gc.estimate = g->gc.total - (MSize)udsize; /* Initial estimate. */ 545 g->gc.estimate = g->gc.total - (MSize)udsize; /* Initial estimate. */
545} 546}
diff --git a/src/lj_obj.h b/src/lj_obj.h
index f29ecb0b..762e58ce 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -473,10 +473,11 @@ typedef struct global_State {
473 GCState gc; /* Garbage collector. */ 473 GCState gc; /* Garbage collector. */
474 SBuf tmpbuf; /* Temporary buffer for string concatenation. */ 474 SBuf tmpbuf; /* Temporary buffer for string concatenation. */
475 Node nilnode; /* Fallback 1-element hash part (nil key and value). */ 475 Node nilnode; /* Fallback 1-element hash part (nil key and value). */
476 GCstr strempty; /* Empty string. */
477 uint8_t stremptyz; /* Zero terminator of empty string. */
476 uint8_t hookmask; /* Hook mask. */ 478 uint8_t hookmask; /* Hook mask. */
477 uint8_t dispatchmode; /* Dispatch mode. */ 479 uint8_t dispatchmode; /* Dispatch mode. */
478 uint8_t vmevmask; /* VM event mask. */ 480 uint8_t vmevmask; /* VM event mask. */
479 uint8_t unused1;
480 GCRef mainthref; /* Link to main thread. */ 481 GCRef mainthref; /* Link to main thread. */
481 TValue registrytv; /* Anchor for registry. */ 482 TValue registrytv; /* Anchor for registry. */
482 TValue tmptv; /* Temporary TValue. */ 483 TValue tmptv; /* Temporary TValue. */
diff --git a/src/lj_state.c b/src/lj_state.c
index e90359ef..87f2cfe9 100644
--- a/src/lj_state.c
+++ b/src/lj_state.c
@@ -191,6 +191,8 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
191 L->dummy_ffid = FF_C; 191 L->dummy_ffid = FF_C;
192 setmref(L->glref, g); 192 setmref(L->glref, g);
193 g->gc.currentwhite = LJ_GC_WHITE0 | LJ_GC_FIXED; 193 g->gc.currentwhite = LJ_GC_WHITE0 | LJ_GC_FIXED;
194 g->strempty.marked = LJ_GC_WHITE0;
195 g->strempty.gct = ~LJ_TSTR;
194 g->allocf = f; 196 g->allocf = f;
195 g->allocd = ud; 197 g->allocd = ud;
196 setgcref(g->mainthref, obj2gco(L)); 198 setgcref(g->mainthref, obj2gco(L));
diff --git a/src/lj_str.c b/src/lj_str.c
index 4a9477dd..5ba55bdd 100644
--- a/src/lj_str.c
+++ b/src/lj_str.c
@@ -76,15 +76,29 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx)
76 GCstr *s; 76 GCstr *s;
77 GCobj *o; 77 GCobj *o;
78 MSize len = (MSize)lenx; 78 MSize len = (MSize)lenx;
79 MSize h = len; 79 MSize a, b, h = len;
80 MSize step = (len>>5)+1; /* Partial hash. */
81 MSize l1;
82 if (lenx >= LJ_MAX_STR) 80 if (lenx >= LJ_MAX_STR)
83 lj_err_msg(L, LJ_ERR_STROV); 81 lj_err_msg(L, LJ_ERR_STROV);
84 for (l1 = len; l1 >= step; l1 -= step) /* Compute string hash. */
85 h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
86 /* Check if the string has already been interned. */
87 g = G(L); 82 g = G(L);
83 /* Compute string hash. Constants taken from lookup3 hash by Bob Jenkins. */
84 if (len >= 4) { /* Caveat: unaligned access! */
85 a = *(const uint32_t *)str;
86 h ^= *(const uint32_t *)(str+len-4);
87 b = *(const uint32_t *)(str+(len>>1)-2);
88 h ^= b; h -= lj_rol(b, 14);
89 b += *(const uint32_t *)(str+(len>>2)-1);
90 } else if (len > 0) {
91 a = *(const uint8_t *)str;
92 h ^= *(const uint8_t *)(str+len-1);
93 b = *(const uint8_t *)(str+(len>>1));
94 h ^= b; h -= lj_rol(b, 14);
95 } else {
96 return &g->strempty;
97 }
98 a ^= h; a -= lj_rol(h, 11);
99 b ^= a; b -= lj_rol(a, 25);
100 h ^= b; h -= lj_rol(b, 16);
101 /* Check if the string has already been interned. */
88 for (o = gcref(g->strhash[h & g->strmask]); o != NULL; o = gcnext(o)) { 102 for (o = gcref(g->strhash[h & g->strmask]); o != NULL; o = gcnext(o)) {
89 GCstr *tso = gco2str(o); 103 GCstr *tso = gco2str(o);
90 if (tso->len == len && (memcmp(str, strdata(tso), len) == 0)) { 104 if (tso->len == len && (memcmp(str, strdata(tso), len) == 0)) {