diff options
author | Mike Pall <mike> | 2010-07-21 22:53:27 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-07-21 22:53:27 +0200 |
commit | 420124372b7643410a1cdd6f80b9cc8aa6ec1302 (patch) | |
tree | 6048404974755391eec68a445258639d8d41425e /src | |
parent | d05873ee0ae63ee47710a2c9843d032010cc296f (diff) | |
download | luajit-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.c | 1 | ||||
-rw-r--r-- | src/lj_obj.h | 3 | ||||
-rw-r--r-- | src/lj_state.c | 2 | ||||
-rw-r--r-- | src/lj_str.c | 26 |
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)) { |