summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-03-04 10:31:21 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-03-04 10:31:21 -0300
commita80cada9142f9e967c710e37934067a708224161 (patch)
treeb6ecc44201408c9e9cf520f47f15413531c51161
parenta00013c8d0d268616e004715da499e88e03b534c (diff)
downloadlua-a80cada9142f9e967c710e37934067a708224161.tar.gz
lua-a80cada9142f9e967c710e37934067a708224161.tar.bz2
lua-a80cada9142f9e967c710e37934067a708224161.zip
new cache for interning strings
-rw-r--r--lgc.c16
-rw-r--r--llimits.h10
-rw-r--r--lstate.c10
-rw-r--r--lstate.h3
-rw-r--r--lstring.c34
-rw-r--r--lstring.h3
6 files changed, 61 insertions, 15 deletions
diff --git a/lgc.c b/lgc.c
index 1695ea74..db4259e0 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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*/
974static 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
970static l_mem atomic (lua_State *L) { 983static 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' */
diff --git a/llimits.h b/llimits.h
index 961ff53b..7ff282ca 100644
--- a/llimits.h
+++ b/llimits.h
@@ -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
diff --git a/lstate.c b/lstate.c
index d42f0e82..3a9b8e98 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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);
diff --git a/lstate.h b/lstate.h
index fb2e91b4..285dfd82 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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
diff --git a/lstring.c b/lstring.c
index 29e4630c..638f3dec 100644
--- a/lstring.c
+++ b/lstring.c
@@ -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*/
93void 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*/
168TString *luaS_new (lua_State *L, const char *str) { 188TString *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
diff --git a/lstring.h b/lstring.h
index 573daf9a..2b06afaf 100644
--- a/lstring.h
+++ b/lstring.h
@@ -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 @@
36LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); 36LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
37LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 37LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
38LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 38LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
39LUAI_FUNC void luaS_init (lua_State *L);
39LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); 40LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
40LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s); 41LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
41LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); 42LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);