diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-03-04 10:31:21 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-03-04 10:31:21 -0300 |
| commit | a80cada9142f9e967c710e37934067a708224161 (patch) | |
| tree | b6ecc44201408c9e9cf520f47f15413531c51161 | |
| parent | a00013c8d0d268616e004715da499e88e03b534c (diff) | |
| download | lua-a80cada9142f9e967c710e37934067a708224161.tar.gz lua-a80cada9142f9e967c710e37934067a708224161.tar.bz2 lua-a80cada9142f9e967c710e37934067a708224161.zip | |
new cache for interning strings
| -rw-r--r-- | lgc.c | 16 | ||||
| -rw-r--r-- | llimits.h | 10 | ||||
| -rw-r--r-- | lstate.c | 10 | ||||
| -rw-r--r-- | lstate.h | 3 | ||||
| -rw-r--r-- | lstring.c | 34 | ||||
| -rw-r--r-- | lstring.h | 3 |
6 files changed, 61 insertions, 15 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.201 2014/12/20 13:58:15 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.202 2015/01/16 16:54:37 roberto Exp roberto $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -967,6 +967,19 @@ void luaC_freeallobjects (lua_State *L) { | |||
| 967 | } | 967 | } |
| 968 | 968 | ||
| 969 | 969 | ||
| 970 | /* | ||
| 971 | ** Clear API string cache. (Entries cannot be empty, so fill them with | ||
| 972 | ** a non-collectable string.) | ||
| 973 | */ | ||
| 974 | static void clearapihash (global_State *g) { | ||
| 975 | int i; | ||
| 976 | for (i = 0; i < STRCACHE_SIZE; i++) { | ||
| 977 | if (iswhite(g->strcache[i])) /* will entry be collected? */ | ||
| 978 | g->strcache[i] = g->memerrmsg; /* replace it with something fixed */ | ||
| 979 | } | ||
| 980 | } | ||
| 981 | |||
| 982 | |||
| 970 | static l_mem atomic (lua_State *L) { | 983 | static l_mem atomic (lua_State *L) { |
| 971 | global_State *g = G(L); | 984 | global_State *g = G(L); |
| 972 | l_mem work; | 985 | l_mem work; |
| @@ -1007,6 +1020,7 @@ static l_mem atomic (lua_State *L) { | |||
| 1007 | /* clear values from resurrected weak tables */ | 1020 | /* clear values from resurrected weak tables */ |
| 1008 | clearvalues(g, g->weak, origweak); | 1021 | clearvalues(g, g->weak, origweak); |
| 1009 | clearvalues(g, g->allweak, origall); | 1022 | clearvalues(g, g->allweak, origall); |
| 1023 | clearapihash(g); | ||
| 1010 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ | 1024 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ |
| 1011 | work += g->GCmemtrav; /* complete counting */ | 1025 | work += g->GCmemtrav; /* complete counting */ |
| 1012 | return work; /* estimate of memory marked by 'atomic' */ | 1026 | return work; /* estimate of memory marked by 'atomic' */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: llimits.h,v 1.131 2015/02/09 15:41:56 roberto Exp roberto $ | 2 | ** $Id: llimits.h,v 1.132 2015/03/03 19:53:13 roberto Exp roberto $ |
| 3 | ** Limits, basic types, and some other 'installation-dependent' definitions | 3 | ** Limits, basic types, and some other 'installation-dependent' definitions |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -187,6 +187,14 @@ typedef unsigned long Instruction; | |||
| 187 | #endif | 187 | #endif |
| 188 | 188 | ||
| 189 | 189 | ||
| 190 | /* | ||
| 191 | ** Size of cache for strings in the API (better be a prime) | ||
| 192 | */ | ||
| 193 | #if !defined(STRCACHE_SIZE) | ||
| 194 | #define STRCACHE_SIZE 127 | ||
| 195 | #endif | ||
| 196 | |||
| 197 | |||
| 190 | /* minimum size for string buffer */ | 198 | /* minimum size for string buffer */ |
| 191 | #if !defined(LUA_MINBUFFER) | 199 | #if !defined(LUA_MINBUFFER) |
| 192 | #define LUA_MINBUFFER 32 | 200 | #define LUA_MINBUFFER 32 |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.126 2014/11/02 19:19:04 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.127 2014/11/02 19:33:33 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -37,9 +37,6 @@ | |||
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | 39 | ||
| 40 | #define MEMERRMSG "not enough memory" | ||
| 41 | |||
| 42 | |||
| 43 | /* | 40 | /* |
| 44 | ** a macro to help the creation of a unique random seed when a state is | 41 | ** a macro to help the creation of a unique random seed when a state is |
| 45 | ** created; the seed is used to randomize hashes. | 42 | ** created; the seed is used to randomize hashes. |
| @@ -200,12 +197,9 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
| 200 | UNUSED(ud); | 197 | UNUSED(ud); |
| 201 | stack_init(L, L); /* init stack */ | 198 | stack_init(L, L); /* init stack */ |
| 202 | init_registry(L, g); | 199 | init_registry(L, g); |
| 203 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ | 200 | luaS_init(L); |
| 204 | luaT_init(L); | 201 | luaT_init(L); |
| 205 | luaX_init(L); | 202 | luaX_init(L); |
| 206 | /* pre-create memory-error message */ | ||
| 207 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); | ||
| 208 | luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ | ||
| 209 | g->gcrunning = 1; /* allow gc */ | 203 | g->gcrunning = 1; /* allow gc */ |
| 210 | g->version = lua_version(NULL); | 204 | g->version = lua_version(NULL); |
| 211 | luai_userstateopen(L); | 205 | luai_userstateopen(L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.118 2014/10/25 11:50:46 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.119 2014/10/30 18:53:28 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -140,6 +140,7 @@ typedef struct global_State { | |||
| 140 | TString *memerrmsg; /* memory-error message */ | 140 | TString *memerrmsg; /* memory-error message */ |
| 141 | TString *tmname[TM_N]; /* array with tag-method names */ | 141 | TString *tmname[TM_N]; /* array with tag-method names */ |
| 142 | struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ | 142 | struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ |
| 143 | TString *strcache[STRCACHE_SIZE]; /* cache for strings in API */ | ||
| 143 | } global_State; | 144 | } global_State; |
| 144 | 145 | ||
| 145 | 146 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 2.45 2014/11/02 19:19:04 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 2.46 2015/01/16 16:54:37 roberto Exp roberto $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -22,6 +22,8 @@ | |||
| 22 | #include "lstring.h" | 22 | #include "lstring.h" |
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | #define MEMERRMSG "not enough memory" | ||
| 26 | |||
| 25 | 27 | ||
| 26 | /* | 28 | /* |
| 27 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to | 29 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to |
| @@ -85,6 +87,21 @@ void luaS_resize (lua_State *L, int newsize) { | |||
| 85 | } | 87 | } |
| 86 | 88 | ||
| 87 | 89 | ||
| 90 | /* | ||
| 91 | ** Initialize the string table and the string cache | ||
| 92 | */ | ||
| 93 | void luaS_init (lua_State *L) { | ||
| 94 | global_State *g = G(L); | ||
| 95 | int i; | ||
| 96 | luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ | ||
| 97 | /* pre-create memory-error message */ | ||
| 98 | g->memerrmsg = luaS_newliteral(L, MEMERRMSG); | ||
| 99 | luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */ | ||
| 100 | for (i = 0; i < STRCACHE_SIZE; i++) | ||
| 101 | g->strcache[i] = g->memerrmsg; /* fill cache with valid strings */ | ||
| 102 | } | ||
| 103 | |||
| 104 | |||
| 88 | 105 | ||
| 89 | /* | 106 | /* |
| 90 | ** creates a new string object | 107 | ** creates a new string object |
| @@ -163,10 +180,21 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
| 163 | 180 | ||
| 164 | 181 | ||
| 165 | /* | 182 | /* |
| 166 | ** new zero-terminated string | 183 | ** Create or reuse a zero-terminated string, first checking in the |
| 184 | ** cache (using the string address as a key). The cache can contain | ||
| 185 | ** only zero-terminated strings, so it is safe to use 'strcmp' to | ||
| 186 | ** check hits. | ||
| 167 | */ | 187 | */ |
| 168 | TString *luaS_new (lua_State *L, const char *str) { | 188 | TString *luaS_new (lua_State *L, const char *str) { |
| 169 | return luaS_newlstr(L, str, strlen(str)); | 189 | unsigned int i = point2uint(str) % STRCACHE_SIZE; /* hash */ |
| 190 | TString **p = &G(L)->strcache[i]; | ||
| 191 | if (strcmp(str, getstr(*p)) == 0) /* hit? */ | ||
| 192 | return *p; /* that it is */ | ||
| 193 | else { /* normal route */ | ||
| 194 | TString *s = luaS_newlstr(L, str, strlen(str)); | ||
| 195 | *p = s; | ||
| 196 | return s; | ||
| 197 | } | ||
| 170 | } | 198 | } |
| 171 | 199 | ||
| 172 | 200 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.h,v 1.56 2014/07/18 14:46:47 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.57 2015/01/16 16:54:37 roberto Exp roberto $ |
| 3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -36,6 +36,7 @@ | |||
| 36 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); | 36 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); |
| 37 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); | 37 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); |
| 38 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); | 38 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
| 39 | LUAI_FUNC void luaS_init (lua_State *L); | ||
| 39 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); | 40 | LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); |
| 40 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); | 41 | LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); |
| 41 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); | 42 | LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); |
