aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-08-06 14:06:56 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-08-06 14:06:56 -0300
commit634344d61fb4bd7ebd033d37b814a0083e55b5a2 (patch)
tree01794c51e00c7ec1faec1e08fe2963ee75b1a139 /lgc.c
parenta2fa48a570b01b2a2cd37f01799f08f693fc5892 (diff)
downloadlua-634344d61fb4bd7ebd033d37b814a0083e55b5a2.tar.gz
lua-634344d61fb4bd7ebd033d37b814a0083e55b5a2.tar.bz2
lua-634344d61fb4bd7ebd033d37b814a0083e55b5a2.zip
new API for weak mode
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c63
1 files changed, 26 insertions, 37 deletions
diff --git a/lgc.c b/lgc.c
index 3b2c3fa4..7dde65c3 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.143 2002/07/17 16:25:13 roberto Exp $ 2** $Id: lgc.c,v 1.144 2002/08/05 14:50:39 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*/
@@ -35,12 +35,6 @@ typedef struct GCState {
35#define ismarked(x) ((x)->mark != (x)) 35#define ismarked(x) ((x)->mark != (x))
36 36
37 37
38/* `Table.flag' bits to indicate whether table is key-weak and/or value-weak */
39#define KEYWEAKBIT (TM_MODE+1) /* ORDER TM */
40#define VALUEWEAKBIT (TM_MODE+2)
41#define KEYWEAK (1<<KEYWEAKBIT)
42#define VALUEWEAK (1<<VALUEWEAKBIT)
43
44 38
45/* mark tricks for userdata */ 39/* mark tricks for userdata */
46#define isudmarked(u) (u->uv.len & 1) 40#define isudmarked(u) (u->uv.len & 1)
@@ -221,19 +215,15 @@ static void removekey (Node *n) {
221 215
222static void traversetable (GCState *st, Table *h) { 216static void traversetable (GCState *st, Table *h) {
223 int i; 217 int i;
224 const TObject *mode;
225 int weakkey = 0; 218 int weakkey = 0;
226 int weakvalue = 0; 219 int weakvalue = 0;
227 marktable(st, h->metatable); 220 marktable(st, h->metatable);
228 lua_assert(h->lsizenode || h->node == G(st->L)->dummynode); 221 lua_assert(h->lsizenode || h->node == G(st->L)->dummynode);
229 mode = fasttm(st->L, h->metatable, TM_MODE); 222 if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */
230 if (mode && ttisstring(mode)) { /* weak table? */ 223 weakkey = h->mode & WEAKKEY;
224 weakvalue = h->mode & WEAKVALUE;
231 h->mark = st->toclear; /* must be cleared after GC, ... */ 225 h->mark = st->toclear; /* must be cleared after GC, ... */
232 st->toclear = h; /* ...put in the appropriate list */ 226 st->toclear = h; /* ... so put in the appropriate list */
233 weakkey = (strchr(svalue(mode), 'k') != NULL);
234 weakvalue = (strchr(svalue(mode), 'v') != NULL);
235 h->flags &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
236 h->flags |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT);
237 } 227 }
238 if (!weakvalue) { 228 if (!weakvalue) {
239 i = sizearray(h); 229 i = sizearray(h);
@@ -284,14 +274,14 @@ static int hasmark (const TObject *o) {
284static void cleartablekeys (GCState *st) { 274static void cleartablekeys (GCState *st) {
285 Table *h; 275 Table *h;
286 for (h = st->toclear; h; h = h->mark) { 276 for (h = st->toclear; h; h = h->mark) {
287 int i; 277 lua_assert(h->mode & (WEAKKEY | WEAKVALUE));
288 if (!(h->flags & KEYWEAK)) continue; 278 if ((h->mode & WEAKKEY)) { /* table may have collected keys? */
289 lua_assert(strchr(svalue(fasttm(st->L, h->metatable, TM_MODE)), 'k')); 279 int i = sizenode(h);
290 i = sizenode(h); 280 while (i--) {
291 while (i--) { 281 Node *n = node(h, i);
292 Node *n = node(h, i); 282 if (!hasmark(key(n))) /* key was collected? */
293 if (!hasmark(key(n))) 283 removekey(n); /* remove entry from table */
294 removekey(n); /* ... and key */ 284 }
295 } 285 }
296 } 286 }
297} 287}
@@ -303,20 +293,19 @@ static void cleartablekeys (GCState *st) {
303static void cleartablevalues (GCState *st) { 293static void cleartablevalues (GCState *st) {
304 Table *h; 294 Table *h;
305 for (h = st->toclear; h; h = h->mark) { 295 for (h = st->toclear; h; h = h->mark) {
306 int i; 296 if ((h->mode & WEAKVALUE)) { /* table may have collected values? */
307 if (!(h->flags & VALUEWEAK)) continue; 297 int i = sizearray(h);
308 lua_assert(strchr(svalue(fasttm(st->L, h->metatable, TM_MODE)), 'v')); 298 while (i--) {
309 i = sizearray(h); 299 TObject *o = &h->array[i];
310 while (i--) { 300 if (!hasmark(o)) /* value was collected? */
311 TObject *o = &h->array[i]; 301 setnilvalue(o); /* remove value */
312 if (!hasmark(o)) 302 }
313 setnilvalue(o); /* remove value */ 303 i = sizenode(h);
314 } 304 while (i--) {
315 i = sizenode(h); 305 Node *n = node(h, i);
316 while (i--) { 306 if (!hasmark(val(n))) /* value was collected? */
317 Node *n = node(h, i); 307 removekey(n); /* remove entry from table */
318 if (!hasmark(val(n))) 308 }
319 removekey(n); /* ... and key */
320 } 309 }
321 } 310 }
322} 311}