diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-16 11:45:55 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-08-16 11:45:55 -0300 |
commit | da19c436cc361401563eeda2cca3d161a6ddeef7 (patch) | |
tree | 9d2d7e3f6c00d88dc659d123c79d4157ffd36ffb /lgc.c | |
parent | 0039feb9dae27e25c0c719f49d954741fb2babf3 (diff) | |
download | lua-da19c436cc361401563eeda2cca3d161a6ddeef7.tar.gz lua-da19c436cc361401563eeda2cca3d161a6ddeef7.tar.bz2 lua-da19c436cc361401563eeda2cca3d161a6ddeef7.zip |
cleaning the stage for generational collection
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 62 |
1 files changed, 30 insertions, 32 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.144 2002/08/05 14:50:39 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.145 2002/08/06 17:06:56 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 | */ |
@@ -27,27 +27,26 @@ typedef struct GCState { | |||
27 | } GCState; | 27 | } GCState; |
28 | 28 | ||
29 | 29 | ||
30 | /* mark a string; marks larger than 1 cannot be changed */ | 30 | /* |
31 | #define strmark(s) {if ((s)->tsv.marked == 0) (s)->tsv.marked = 1;} | 31 | ** some userful bit tricks |
32 | */ | ||
33 | #define setbit(x,b) ((x) |= (1<<(b))) | ||
34 | #define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b)))) | ||
35 | #define testbit(x,b) ((x) & (1<<(b))) | ||
32 | 36 | ||
33 | 37 | ||
34 | /* unmarked tables are represented by pointing `mark' to themselves */ | 38 | #define strmark(s) setbit((s)->tsv.marked, 0) |
35 | #define ismarked(x) ((x)->mark != (x)) | 39 | #define strunmark(s) resetbit((s)->tsv.marked, 0) |
36 | 40 | ||
37 | 41 | ||
38 | 42 | ||
39 | /* mark tricks for userdata */ | 43 | /* mark tricks for userdata */ |
40 | #define isudmarked(u) (u->uv.len & 1) | 44 | #define isudmarked(u) testbit(u->uv.marked, 0) |
41 | #define markud(u) (u->uv.len |= 1) | 45 | #define markud(u) setbit(u->uv.marked, 0) |
42 | #define unmarkud(u) (u->uv.len &= (~(size_t)1)) | 46 | #define unmarkud(u) resetbit(u->uv.marked, 0) |
43 | |||
44 | #define isfinalized(u) (u->uv.len & 2) | ||
45 | #define markfinalized(u) (u->uv.len |= 2) | ||
46 | |||
47 | |||
48 | /* mark tricks for upvalues (assume that open upvalues are always marked) */ | ||
49 | #define isupvalmarked(uv) ((uv)->v != &(uv)->value) | ||
50 | 47 | ||
48 | #define isfinalized(u) testbit(u->uv.marked, 1) | ||
49 | #define markfinalized(u) setbit(u->uv.marked, 1) | ||
51 | 50 | ||
52 | 51 | ||
53 | #define ismarkable(o) (!((1 << ttype(o)) & \ | 52 | #define ismarkable(o) (!((1 << ttype(o)) & \ |
@@ -78,8 +77,9 @@ static void protomark (Proto *f) { | |||
78 | 77 | ||
79 | 78 | ||
80 | static void marktable (GCState *st, Table *h) { | 79 | static void marktable (GCState *st, Table *h) { |
81 | if (!ismarked(h)) { | 80 | if (!h->marked) { |
82 | h->mark = st->tmark; /* chain it for later traversal */ | 81 | h->marked = 1; |
82 | h->gclist = st->tmark; /* chain it for later traversal */ | ||
83 | st->tmark = h; | 83 | st->tmark = h; |
84 | } | 84 | } |
85 | } | 85 | } |
@@ -100,9 +100,9 @@ static void markclosure (GCState *st, Closure *cl) { | |||
100 | protomark(cl->l.p); | 100 | protomark(cl->l.p); |
101 | for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ | 101 | for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ |
102 | UpVal *u = cl->l.upvals[i]; | 102 | UpVal *u = cl->l.upvals[i]; |
103 | if (!isupvalmarked(u)) { | 103 | if (!u->marked) { |
104 | markobject(st, &u->value); | 104 | markobject(st, &u->value); |
105 | u->v = NULL; /* mark it! */ | 105 | u->marked = 1; |
106 | } | 106 | } |
107 | } | 107 | } |
108 | } | 108 | } |
@@ -222,7 +222,7 @@ static void traversetable (GCState *st, Table *h) { | |||
222 | if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */ | 222 | if (h->mode & (WEAKKEY | WEAKVALUE)) { /* weak table? */ |
223 | weakkey = h->mode & WEAKKEY; | 223 | weakkey = h->mode & WEAKKEY; |
224 | weakvalue = h->mode & WEAKVALUE; | 224 | weakvalue = h->mode & WEAKVALUE; |
225 | h->mark = st->toclear; /* must be cleared after GC, ... */ | 225 | h->gclist = st->toclear; /* must be cleared after GC, ... */ |
226 | st->toclear = h; /* ... so put in the appropriate list */ | 226 | st->toclear = h; /* ... so put in the appropriate list */ |
227 | } | 227 | } |
228 | if (!weakvalue) { | 228 | if (!weakvalue) { |
@@ -245,7 +245,7 @@ static void traversetable (GCState *st, Table *h) { | |||
245 | static void propagatemarks (GCState *st) { | 245 | static void propagatemarks (GCState *st) { |
246 | while (st->tmark) { /* traverse marked tables */ | 246 | while (st->tmark) { /* traverse marked tables */ |
247 | Table *h = st->tmark; /* get first table from list */ | 247 | Table *h = st->tmark; /* get first table from list */ |
248 | st->tmark = h->mark; /* remove it from list */ | 248 | st->tmark = h->gclist; /* remove it from list */ |
249 | traversetable(st, h); | 249 | traversetable(st, h); |
250 | } | 250 | } |
251 | } | 251 | } |
@@ -256,7 +256,7 @@ static int hasmark (const TObject *o) { | |||
256 | case LUA_TUSERDATA: | 256 | case LUA_TUSERDATA: |
257 | return isudmarked(uvalue(o)); | 257 | return isudmarked(uvalue(o)); |
258 | case LUA_TTABLE: | 258 | case LUA_TTABLE: |
259 | return ismarked(hvalue(o)); | 259 | return hvalue(o)->marked; |
260 | case LUA_TFUNCTION: | 260 | case LUA_TFUNCTION: |
261 | return clvalue(o)->c.marked; | 261 | return clvalue(o)->c.marked; |
262 | case LUA_TSTRING: | 262 | case LUA_TSTRING: |
@@ -273,7 +273,7 @@ static int hasmark (const TObject *o) { | |||
273 | */ | 273 | */ |
274 | static void cleartablekeys (GCState *st) { | 274 | static void cleartablekeys (GCState *st) { |
275 | Table *h; | 275 | Table *h; |
276 | for (h = st->toclear; h; h = h->mark) { | 276 | for (h = st->toclear; h; h = h->gclist) { |
277 | lua_assert(h->mode & (WEAKKEY | WEAKVALUE)); | 277 | lua_assert(h->mode & (WEAKKEY | WEAKVALUE)); |
278 | if ((h->mode & WEAKKEY)) { /* table may have collected keys? */ | 278 | if ((h->mode & WEAKKEY)) { /* table may have collected keys? */ |
279 | int i = sizenode(h); | 279 | int i = sizenode(h); |
@@ -292,7 +292,7 @@ static void cleartablekeys (GCState *st) { | |||
292 | */ | 292 | */ |
293 | static void cleartablevalues (GCState *st) { | 293 | static void cleartablevalues (GCState *st) { |
294 | Table *h; | 294 | Table *h; |
295 | for (h = st->toclear; h; h = h->mark) { | 295 | for (h = st->toclear; h; h = h->gclist) { |
296 | if ((h->mode & WEAKVALUE)) { /* table may have collected values? */ | 296 | if ((h->mode & WEAKVALUE)) { /* table may have collected values? */ |
297 | int i = sizearray(h); | 297 | int i = sizearray(h); |
298 | while (i--) { | 298 | while (i--) { |
@@ -347,9 +347,8 @@ static void collectupval (lua_State *L) { | |||
347 | UpVal **v = &G(L)->rootupval; | 347 | UpVal **v = &G(L)->rootupval; |
348 | UpVal *curr; | 348 | UpVal *curr; |
349 | while ((curr = *v) != NULL) { | 349 | while ((curr = *v) != NULL) { |
350 | if (isupvalmarked(curr)) { | 350 | if (curr->marked) { |
351 | lua_assert(curr->v == NULL); | 351 | curr->marked = 0; /* unmark */ |
352 | curr->v = &curr->value; /* unmark */ | ||
353 | v = &curr->next; /* next */ | 352 | v = &curr->next; /* next */ |
354 | } | 353 | } |
355 | else { | 354 | else { |
@@ -364,8 +363,8 @@ static void collecttable (lua_State *L) { | |||
364 | Table **p = &G(L)->roottable; | 363 | Table **p = &G(L)->roottable; |
365 | Table *curr; | 364 | Table *curr; |
366 | while ((curr = *p) != NULL) { | 365 | while ((curr = *p) != NULL) { |
367 | if (ismarked(curr)) { | 366 | if (curr->marked) { |
368 | curr->mark = curr; /* unmark */ | 367 | curr->marked = 0; |
369 | p = &curr->next; | 368 | p = &curr->next; |
370 | } | 369 | } |
371 | else { | 370 | else { |
@@ -387,7 +386,7 @@ static void collectudata (lua_State *L) { | |||
387 | } | 386 | } |
388 | else { | 387 | else { |
389 | *p = curr->uv.next; | 388 | *p = curr->uv.next; |
390 | luaM_free(L, curr, sizeudata(curr->uv.len & (~(size_t)3))); | 389 | luaM_free(L, curr, sizeudata(curr->uv.len)); |
391 | } | 390 | } |
392 | } | 391 | } |
393 | } | 392 | } |
@@ -400,8 +399,7 @@ static void collectstrings (lua_State *L, int all) { | |||
400 | TString *curr; | 399 | TString *curr; |
401 | while ((curr = *p) != NULL) { | 400 | while ((curr = *p) != NULL) { |
402 | if (curr->tsv.marked && !all) { /* preserve? */ | 401 | if (curr->tsv.marked && !all) { /* preserve? */ |
403 | if (curr->tsv.marked < FIXMARK) /* does not change FIXMARKs */ | 402 | strunmark(curr); |
404 | curr->tsv.marked = 0; | ||
405 | p = &curr->tsv.nexthash; | 403 | p = &curr->tsv.nexthash; |
406 | } | 404 | } |
407 | else { /* collect */ | 405 | else { /* collect */ |