aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-04-11 11:42:41 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2001-04-11 11:42:41 -0300
commit0e0e4a480e6d9b0125a96ca982a3e9571578a037 (patch)
tree21f13f032e9e337879168c74871d0d4bb2534248 /lgc.c
parent2a501882692afaa08ecc38af3052e9b4f60f6e85 (diff)
downloadlua-0e0e4a480e6d9b0125a96ca982a3e9571578a037.tar.gz
lua-0e0e4a480e6d9b0125a96ca982a3e9571578a037.tar.bz2
lua-0e0e4a480e6d9b0125a96ca982a3e9571578a037.zip
first implementation for weak tables
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c59
1 files changed, 44 insertions, 15 deletions
diff --git a/lgc.c b/lgc.c
index 3a665660..a7f96f8c 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.94 2001/03/07 18:09:25 roberto Exp roberto $ 2** $Id: lgc.c,v 1.95 2001/03/26 14:31:49 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*/
@@ -38,9 +38,6 @@ typedef struct GCState {
38 38
39 39
40 40
41static void markobject (GCState *st, TObject *o);
42
43
44/* mark a string; marks larger than 1 cannot be changed */ 41/* mark a string; marks larger than 1 cannot be changed */
45#define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;} 42#define strmark(s) {if ((s)->marked == 0) (s)->marked = 1;}
46 43
@@ -144,22 +141,30 @@ static void traverseclosure (GCState *st, Closure *f) {
144} 141}
145 142
146 143
144static void removekey (Node *n) {
145 if (ttype_key(n) != LUA_TNIL && ttype_key(n) != LUA_TNUMBER)
146 n->key_value.ts = NULL; /* dead key; remove it */
147}
148
149
147static void traversetable (GCState *st, Hash *h) { 150static void traversetable (GCState *st, Hash *h) {
148 int i; 151 int i;
152 int mode = h->weakmode;
153 if (mode == (LUA_WEAK_KEY | LUA_WEAK_VALUE))
154 return; /* avoid traversing if both keys and values are weak */
149 for (i=0; i<h->size; i++) { 155 for (i=0; i<h->size; i++) {
150 Node *n = node(h, i); 156 Node *n = node(h, i);
151 if (ttype(val(n)) == LUA_TNIL) { 157 if (ttype(val(n)) == LUA_TNIL)
152 if (ttype_key(n) != LUA_TNIL) 158 removekey(n);
153 n->key_value.ts = NULL; /* dead key; remove it */
154 }
155 else { 159 else {
156 lua_assert(ttype_key(n) != LUA_TNIL); 160 lua_assert(ttype_key(n) != LUA_TNIL);
157 if (ttype_key(n) != LUA_TNUMBER) { 161 if (ttype_key(n) != LUA_TNUMBER && !(mode & LUA_WEAK_KEY)) {
158 TObject o; 162 TObject k;
159 setkey2obj(&o, n); 163 setkey2obj(&k, n);
160 markobject(st, &o); 164 markobject(st, &k);
161 } 165 }
162 markobject(st, &n->val); 166 if (!(mode & LUA_WEAK_VALUE))
167 markobject(st, &n->val);
163 } 168 }
164 } 169 }
165} 170}
@@ -190,7 +195,6 @@ static void markall (lua_State *L) {
190 195
191 196
192static int hasmark (const TObject *o) { 197static int hasmark (const TObject *o) {
193 /* valid only for locked objects */
194 switch (ttype(o)) { 198 switch (ttype(o)) {
195 case LUA_TSTRING: case LUA_TUSERDATA: 199 case LUA_TSTRING: case LUA_TUSERDATA:
196 return tsvalue(o)->marked; 200 return tsvalue(o)->marked;
@@ -198,7 +202,7 @@ static int hasmark (const TObject *o) {
198 return ismarked(hvalue(o)); 202 return ismarked(hvalue(o));
199 case LUA_TFUNCTION: 203 case LUA_TFUNCTION:
200 return ismarked(clvalue(o)); 204 return ismarked(clvalue(o));
201 default: /* number */ 205 default: /* number, nil */
202 return 1; 206 return 1;
203 } 207 }
204} 208}
@@ -224,6 +228,30 @@ static void invalidaterefs (global_State *G) {
224} 228}
225 229
226 230
231static void invalidatetable (Hash *h) {
232 int i;
233 for (i=0; i<h->size; i++) {
234 Node *n = node(h, i);
235 TObject k;
236 if (ttype(val(n)) == LUA_TNIL) continue; /* empty node */
237 setkey2obj(&k, n);
238 if (!hasmark(val(n)) || !hasmark(&k)) {
239 setnilvalue(val(n)); /* remove value */
240 removekey(n);
241 }
242 }
243}
244
245
246static void invalidatetables (global_State *G) {
247 Hash *h;
248 for (h = G->roottable; h; h = h->next) {
249 if (ismarked(h) && h->weakmode)
250 invalidatetable(h);
251 }
252}
253
254
227 255
228static void collectproto (lua_State *L) { 256static void collectproto (lua_State *L) {
229 Proto **p = &G(L)->rootproto; 257 Proto **p = &G(L)->rootproto;
@@ -381,6 +409,7 @@ void luaC_collect (lua_State *L, int all) {
381void luaC_collectgarbage (lua_State *L) { 409void luaC_collectgarbage (lua_State *L) {
382 markall(L); 410 markall(L);
383 invalidaterefs(G(L)); /* check unlocked references */ 411 invalidaterefs(G(L)); /* check unlocked references */
412 invalidatetables(G(L));
384 luaC_collect(L, 0); 413 luaC_collect(L, 0);
385 checkMbuffer(L); 414 checkMbuffer(L);
386 G(L)->GCthreshold = 2*G(L)->nblocks; /* set new threshold */ 415 G(L)->GCthreshold = 2*G(L)->nblocks; /* set new threshold */