diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-06 14:06:56 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-06 14:06:56 -0300 |
commit | 634344d61fb4bd7ebd033d37b814a0083e55b5a2 (patch) | |
tree | 01794c51e00c7ec1faec1e08fe2963ee75b1a139 /lgc.c | |
parent | a2fa48a570b01b2a2cd37f01799f08f693fc5892 (diff) | |
download | lua-634344d61fb4bd7ebd033d37b814a0083e55b5a2.tar.gz lua-634344d61fb4bd7ebd033d37b814a0083e55b5a2.tar.bz2 lua-634344d61fb4bd7ebd033d37b814a0083e55b5a2.zip |
new API for weak mode
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 63 |
1 files changed, 26 insertions, 37 deletions
@@ -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 | ||
222 | static void traversetable (GCState *st, Table *h) { | 216 | static 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) { | |||
284 | static void cleartablekeys (GCState *st) { | 274 | static 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) { | |||
303 | static void cleartablevalues (GCState *st) { | 293 | static 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 | } |