diff -urN lua-5.1.4-orig/src/lobject.h lua-5.1.4/src/lobject.h --- lua-5.1.4-orig/src/lobject.h 2008-08-06 22:29:48 +0900 +++ lua-5.1.4/src/lobject.h 2010-06-14 04:38:48 +0900 @@ -201,7 +201,9 @@ struct { CommonHeader; lu_byte reserved; +#ifndef LUA_OMIT_STRING_HASH unsigned int hash; +#endif size_t len; } tsv; } TString; diff -urN lua-5.1.4-orig/src/lstring.c lua-5.1.4/src/lstring.c --- lua-5.1.4-orig/src/lstring.c 2007-12-27 22:02:25 +0900 +++ lua-5.1.4/src/lstring.c 2010-06-14 04:45:53 +0900 @@ -19,6 +19,19 @@ +static unsigned int hashstr (const char *str, size_t l) { + unsigned int h = cast(unsigned int, l); /* seed */ + size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ + size_t l1; + for (l1=l; l1>=step; l1-=step) /* compute hash */ + h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); + return h; +} + +unsigned int luaS_hashstr (const TString *ts) { + return hashstr(getstr(ts), ts->tsv.len); +} + void luaS_resize (lua_State *L, int newsize) { GCObject **newhash; stringtable *tb; @@ -33,7 +46,12 @@ GCObject *p = tb->hash[i]; while (p) { /* for each node in the list */ GCObject *next = p->gch.next; /* save next */ +#ifndef LUA_OMIT_STRING_HASH unsigned int h = gco2ts(p)->hash; +#else /* have to recompute it */ + TString *ts = rawgco2ts(p); + unsigned int h = hashstr(getstr(ts), ts->tsv.len); +#endif int h1 = lmod(h, newsize); /* new position */ lua_assert(cast_int(h%newsize) == lmod(h, newsize)); p->gch.next = newhash[h1]; /* chain it */ @@ -55,7 +73,9 @@ luaM_toobig(L); ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString))); ts->tsv.len = l; +#ifndef LUA_OMIT_STRING_HASH ts->tsv.hash = h; +#endif ts->tsv.marked = luaC_white(G(L)); ts->tsv.tt = LUA_TSTRING; ts->tsv.reserved = 0; @@ -74,11 +94,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { GCObject *o; - unsigned int h = cast(unsigned int, l); /* seed */ - size_t step = (l>>5)+1; /* if string is too long, don't hash all its chars */ - size_t l1; - for (l1=l; l1>=step; l1-=step) /* compute hash */ - h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1])); + unsigned int h = hashstr(str, l); for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; o != NULL; o = o->gch.next) { diff -urN lua-5.1.4-orig/src/lstring.h lua-5.1.4/src/lstring.h --- lua-5.1.4-orig/src/lstring.h 2007-12-27 22:02:25 +0900 +++ lua-5.1.4/src/lstring.h 2010-06-14 04:46:21 +0900 @@ -23,6 +23,7 @@ #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) +LUAI_FUNC unsigned int luaS_hashstr (const TString *ts); LUAI_FUNC void luaS_resize (lua_State *L, int newsize); LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); diff -urN lua-5.1.4-orig/src/ltable.c lua-5.1.4/src/ltable.c --- lua-5.1.4-orig/src/ltable.c 2007-12-29 00:32:23 +0900 +++ lua-5.1.4/src/ltable.c 2010-06-14 04:46:47 +0900 @@ -49,7 +49,13 @@ #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) +#ifndef LUA_OMIT_STRING_HASH #define hashstr(t,str) hashpow2(t, (str)->tsv.hash) +#else /* have to recompute it */ +#include "lstring.h" +#define hashstr(t,str) hashpow2(t, luaS_hashstr((str))) +#endif + #define hashboolean(t,p) hashpow2(t, p) diff -urN lua-5.1.4-orig/src/luaconf.h lua-5.1.4/src/luaconf.h --- lua-5.1.4-orig/src/luaconf.h 2008-02-12 01:25:08 +0900 +++ lua-5.1.4/src/luaconf.h 2010-06-14 04:38:48 +0900 @@ -758,6 +758,21 @@ */ +/* +@@ LUA_OMIT_STRING_HASH controls whether string hashes are stored +** along with string objects or not. If defined, the hashes will +** be omitted from the string object structures, saving 4 bytes of +** memory per string, but the hashes of all strings stored in a +** string table must then be recomputed each time the table is +** expanded or traversed. CHANGE it (define it) if saving the +** 4 bytes per string is more important than the execution time +** cost of rehashing. +** +** NOTE that this will not have any effect on memory usage if the +** alignment of LUAI_USER_ALIGNMENT_T is greater than 4. +*/ +/* #define LUA_OMIT_STRING_HASH */ + #endif