aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-11-17 17:50:05 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-11-17 17:50:05 -0200
commitab7d9bfd0c38f1dd8eda40ae3c1f1c686564a92d (patch)
treee7f5231cc02b89b2507ad846d5d547e35e9c4153 /lgc.c
parent921b1723e2fddde0382143b28b5be3b7128204b8 (diff)
downloadlua-ab7d9bfd0c38f1dd8eda40ae3c1f1c686564a92d.tar.gz
lua-ab7d9bfd0c38f1dd8eda40ae3c1f1c686564a92d.tar.bz2
lua-ab7d9bfd0c38f1dd8eda40ae3c1f1c686564a92d.zip
cleaner code for manipulation of `marked' field
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c70
1 files changed, 32 insertions, 38 deletions
diff --git a/lgc.c b/lgc.c
index 1ec12f1d..486e3fbc 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.176 2003/07/29 19:25:37 roberto Exp roberto $ 2** $Id: lgc.c,v 1.177 2003/08/27 21:01:44 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*/
@@ -29,45 +29,38 @@ typedef struct GCState {
29} GCState; 29} GCState;
30 30
31 31
32/*
33** some userful bit tricks
34*/
35#define setbit(x,b) ((x) |= (1<<(b)))
36#define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b))))
37#define testbit(x,b) ((x) & (1<<(b)))
38 32
39#define unmark(x) resetbit((x)->gch.marked, 0) 33#define unblack(x) resetbit((x)->gch.marked, BLACKBIT)
40#define ismarked(x) ((x)->gch.marked & ((1<<4)|1)) 34#define isblack(x) testbit((x)->gch.marked, BLACKBIT)
35#define blacken(x) setbit((x)->gch.marked, BLACKBIT)
41 36
42#define stringmark(s) setbit((s)->tsv.marked, 0) 37#define stringmark(s) setbit((s)->tsv.marked, BLACKBIT)
43 38
44 39
45#define isfinalized(u) (!testbit((u)->uv.marked, 1)) 40#define isfinalized(u) testbit((u)->uv.marked, FINALIZEDBIT)
46#define markfinalized(u) resetbit((u)->uv.marked, 1) 41#define markfinalized(u) setbit((u)->uv.marked, FINALIZEDBIT)
47 42
48 43
49#define KEYWEAKBIT 1 44#define KEYWEAK bitmask(KEYWEAKBIT)
50#define VALUEWEAKBIT 2 45#define VALUEWEAK bitmask(VALUEWEAKBIT)
51#define KEYWEAK (1<<KEYWEAKBIT)
52#define VALUEWEAK (1<<VALUEWEAKBIT)
53 46
54 47
55 48
56#define markobject(st,o) { checkconsistency(o); \ 49#define markobject(st,o) { checkconsistency(o); \
57 if (iscollectable(o) && !ismarked(gcvalue(o))) reallymarkobject(st,gcvalue(o)); } 50 if (iscollectable(o) && !isblack(gcvalue(o))) reallymarkobject(st,gcvalue(o)); }
58 51
59#define condmarkobject(st,o,c) { checkconsistency(o); \ 52#define condmarkobject(st,o,c) { checkconsistency(o); \
60 if (iscollectable(o) && !ismarked(gcvalue(o)) && (c)) \ 53 if (iscollectable(o) && !isblack(gcvalue(o)) && (c)) \
61 reallymarkobject(st,gcvalue(o)); } 54 reallymarkobject(st,gcvalue(o)); }
62 55
63#define markvalue(st,t) { if (!ismarked(valtogco(t))) \ 56#define markvalue(st,t) { if (!isblack(valtogco(t))) \
64 reallymarkobject(st, valtogco(t)); } 57 reallymarkobject(st, valtogco(t)); }
65 58
66 59
67 60
68static void reallymarkobject (GCState *st, GCObject *o) { 61static void reallymarkobject (GCState *st, GCObject *o) {
69 lua_assert(!ismarked(o)); 62 lua_assert(!isblack(o));
70 setbit(o->gch.marked, 0); /* mark object */ 63 blacken(o);
71 switch (o->gch.tt) { 64 switch (o->gch.tt) {
72 case LUA_TUSERDATA: { 65 case LUA_TUSERDATA: {
73 markvalue(st, gcotou(o)->uv.metatable); 66 markvalue(st, gcotou(o)->uv.metatable);
@@ -101,7 +94,7 @@ static void reallymarkobject (GCState *st, GCObject *o) {
101static void marktmu (GCState *st) { 94static void marktmu (GCState *st) {
102 GCObject *u; 95 GCObject *u;
103 for (u = st->g->tmudata; u; u = u->gch.next) { 96 for (u = st->g->tmudata; u; u = u->gch.next) {
104 unmark(u); /* may be marked, if left from previous GC */ 97 unblack(u); /* may be marked, if left from previous GC */
105 reallymarkobject(st, u); 98 reallymarkobject(st, u);
106 } 99 }
107} 100}
@@ -116,7 +109,7 @@ size_t luaC_separateudata (lua_State *L) {
116 GCObject **lastcollected = &collected; 109 GCObject **lastcollected = &collected;
117 while ((curr = *p) != NULL) { 110 while ((curr = *p) != NULL) {
118 lua_assert(curr->gch.tt == LUA_TUSERDATA); 111 lua_assert(curr->gch.tt == LUA_TUSERDATA);
119 if (ismarked(curr) || isfinalized(gcotou(curr))) 112 if (isblack(curr) || isfinalized(gcotou(curr)))
120 p = &curr->gch.next; /* don't bother with them */ 113 p = &curr->gch.next; /* don't bother with them */
121 114
122 else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) { 115 else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) {
@@ -216,9 +209,9 @@ static void traverseclosure (GCState *st, Closure *cl) {
216 markvalue(st, cl->l.p); 209 markvalue(st, cl->l.p);
217 for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */ 210 for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
218 UpVal *u = cl->l.upvals[i]; 211 UpVal *u = cl->l.upvals[i];
219 if (!u->marked) { 212 if (!isblack(valtogco(u))) {
213 blacken(valtogco(u));
220 markobject(st, &u->value); 214 markobject(st, &u->value);
221 u->marked = 1;
222 } 215 }
223 } 216 }
224 } 217 }
@@ -300,7 +293,7 @@ static int iscleared (const TObject *o, int iskey) {
300 stringmark(tsvalue(o)); /* strings are `values', so are never weak */ 293 stringmark(tsvalue(o)); /* strings are `values', so are never weak */
301 return 0; 294 return 0;
302 } 295 }
303 return !ismarked(gcvalue(o)) || 296 return !isblack(gcvalue(o)) ||
304 (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); 297 (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o))));
305} 298}
306 299
@@ -319,8 +312,9 @@ static void cleartable (GCObject *l) {
319 while (l) { 312 while (l) {
320 Table *h = gcotoh(l); 313 Table *h = gcotoh(l);
321 int i = h->sizearray; 314 int i = h->sizearray;
322 lua_assert(h->marked & (KEYWEAK | VALUEWEAK)); 315 lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
323 if (h->marked & VALUEWEAK) { 316 testbit(h->marked, KEYWEAKBIT));
317 if (testbit(h->marked, VALUEWEAKBIT)) {
324 while (i--) { 318 while (i--) {
325 TObject *o = &h->array[i]; 319 TObject *o = &h->array[i];
326 if (iscleared(o, 0)) /* value was collected? */ 320 if (iscleared(o, 0)) /* value was collected? */
@@ -363,12 +357,12 @@ static void freeobj (lua_State *L, GCObject *o) {
363} 357}
364 358
365 359
366static int sweeplist (lua_State *L, GCObject **p, int limit) { 360static int sweeplist (lua_State *L, GCObject **p, int mask) {
367 GCObject *curr; 361 GCObject *curr;
368 int count = 0; /* number of collected items */ 362 int count = 0; /* number of collected items */
369 while ((curr = *p) != NULL) { 363 while ((curr = *p) != NULL) {
370 if (curr->gch.marked > limit) { 364 if (curr->gch.marked & mask) {
371 unmark(curr); 365 unblack(curr);
372 p = &curr->gch.next; 366 p = &curr->gch.next;
373 } 367 }
374 else { 368 else {
@@ -381,10 +375,10 @@ static int sweeplist (lua_State *L, GCObject **p, int limit) {
381} 375}
382 376
383 377
384static void sweepstrings (lua_State *L, int all) { 378static void sweepstrings (lua_State *L, int mask) {
385 int i; 379 int i;
386 for (i=0; i<G(L)->strt.size; i++) { /* for each list */ 380 for (i=0; i<G(L)->strt.size; i++) { /* for each list */
387 G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], all); 381 G(L)->strt.nuse -= sweeplist(L, &G(L)->strt.hash[i], mask);
388 } 382 }
389} 383}
390 384
@@ -426,7 +420,7 @@ void luaC_callGCTM (lua_State *L) {
426 udata->uv.next = G(L)->rootudata; /* return it to `root' list */ 420 udata->uv.next = G(L)->rootudata; /* return it to `root' list */
427 G(L)->rootudata = o; 421 G(L)->rootudata = o;
428 setuvalue(L->top - 1, udata); /* keep a reference to it */ 422 setuvalue(L->top - 1, udata); /* keep a reference to it */
429 unmark(o); 423 unblack(o);
430 do1gcTM(L, udata); 424 do1gcTM(L, udata);
431 } 425 }
432 L->top--; 426 L->top--;
@@ -435,10 +429,10 @@ void luaC_callGCTM (lua_State *L) {
435 429
436 430
437void luaC_sweep (lua_State *L, int all) { 431void luaC_sweep (lua_State *L, int all) {
438 if (all) all = 256; /* larger than any mark */ 432 int mask = (all) ? 0 : (bitmask(BLACKBIT) | bitmask(FIXEDBIT));
439 sweeplist(L, &G(L)->rootudata, all); 433 sweeplist(L, &G(L)->rootudata, mask);
440 sweepstrings(L, all); 434 sweepstrings(L, mask);
441 sweeplist(L, &G(L)->rootgc, all); 435 sweeplist(L, &G(L)->rootgc, mask);
442} 436}
443 437
444 438