aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-12-10 10:13:36 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2003-12-10 10:13:36 -0200
commit47fc57a2529c83376883f36954082cfe80ae588f (patch)
treec2e57e2f9f7d78279144bfd9cbd04a3b1b131f12 /lgc.c
parent4d5fe1f54bc00850f77a7c42f9e95d0ff3f1ab5b (diff)
downloadlua-47fc57a2529c83376883f36954082cfe80ae588f.tar.gz
lua-47fc57a2529c83376883f36954082cfe80ae588f.tar.bz2
lua-47fc57a2529c83376883f36954082cfe80ae588f.zip
`TObject' renamed to `TValue' + other name changes and better assertions
for incremental garbage collection
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c104
1 files changed, 52 insertions, 52 deletions
diff --git a/lgc.c b/lgc.c
index 8cb8620f..147593b0 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 1.186 2003/12/04 18:52:23 roberto Exp roberto $ 2** $Id: lgc.c,v 1.187 2003/12/09 16:56:11 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*/
@@ -22,7 +22,7 @@
22#include "ltm.h" 22#include "ltm.h"
23 23
24 24
25#define GCSTEPSIZE (20*sizeof(TObject)) 25#define GCSTEPSIZE (20*sizeof(TValue))
26 26
27 27
28#define gray2black(x) setbit((x)->gch.marked, BLACKBIT) 28#define gray2black(x) setbit((x)->gch.marked, BLACKBIT)
@@ -39,8 +39,8 @@
39#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) 39#define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT)
40 40
41 41
42#define isfinalized(u) testbit((u)->uv.marked, FINALIZEDBIT) 42#define isfinalized(u) testbit((u)->marked, FINALIZEDBIT)
43#define markfinalized(u) setbit((u)->uv.marked, FINALIZEDBIT) 43#define markfinalized(u) setbit((u)->marked, FINALIZEDBIT)
44 44
45 45
46#define KEYWEAK bitmask(KEYWEAKBIT) 46#define KEYWEAK bitmask(KEYWEAKBIT)
@@ -55,8 +55,8 @@
55 if (iscollectable(o) && iswhite(gcvalue(o)) && (c)) \ 55 if (iscollectable(o) && iswhite(gcvalue(o)) && (c)) \
56 reallymarkobject(g,gcvalue(o)); } 56 reallymarkobject(g,gcvalue(o)); }
57 57
58#define markobject(g,t) { if (iswhite(valtogco(t))) \ 58#define markobject(g,t) { if (iswhite(obj2gco(t))) \
59 reallymarkobject(g, valtogco(t)); } 59 reallymarkobject(g, obj2gco(t)); }
60 60
61 61
62 62
@@ -66,34 +66,34 @@
66static size_t objsize (GCObject *o) { 66static size_t objsize (GCObject *o) {
67 switch (o->gch.tt) { 67 switch (o->gch.tt) {
68 case LUA_TSTRING: { 68 case LUA_TSTRING: {
69 TString *ts = gcotots(o); 69 TString *ts = rawgco2ts(o);
70 return sizestring(ts->tsv.len); 70 return sizestring(ts->tsv.len);
71 } 71 }
72 case LUA_TUSERDATA: { 72 case LUA_TUSERDATA: {
73 Udata *u = gcotou(o); 73 Udata *u = rawgco2u(o);
74 return sizeudata(u->uv.len); 74 return sizeudata(u->uv.len);
75 } 75 }
76 case LUA_TTABLE: { 76 case LUA_TTABLE: {
77 Table *h = gcotoh(o); 77 Table *h = gco2h(o);
78 return sizeof(Table) + sizeof(TObject) * h->sizearray + 78 return sizeof(Table) + sizeof(TValue) * h->sizearray +
79 sizeof(Node) * sizenode(h); 79 sizeof(Node) * sizenode(h);
80 } 80 }
81 case LUA_TUPVAL: 81 case LUA_TUPVAL:
82 return sizeof(UpVal); 82 return sizeof(UpVal);
83 case LUA_TFUNCTION: { 83 case LUA_TFUNCTION: {
84 Closure *cl = gcotocl(o); 84 Closure *cl = gco2cl(o);
85 return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) : 85 return (cl->c.isC) ? sizeCclosure(cl->c.nupvalues) :
86 sizeLclosure(cl->l.nupvalues); 86 sizeLclosure(cl->l.nupvalues);
87 } 87 }
88 case LUA_TTHREAD: { 88 case LUA_TTHREAD: {
89 lua_State *th = gcototh(o); 89 lua_State *th = gco2th(o);
90 return sizeof(lua_State) + sizeof(TObject) * th->stacksize + 90 return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
91 sizeof(CallInfo) * th->size_ci; 91 sizeof(CallInfo) * th->size_ci;
92 } 92 }
93 case LUA_TPROTO: { 93 case LUA_TPROTO: {
94 Proto *p = gcotop(o); 94 Proto *p = gco2p(o);
95 return sizeof(Proto) + sizeof(Instruction) * p->sizecode + 95 return sizeof(Proto) + sizeof(Instruction) * p->sizecode +
96 sizeof(Proto *) * p->sizep + sizeof(TObject) * p->sizek + 96 sizeof(Proto *) * p->sizep + sizeof(TValue) * p->sizek +
97 sizeof(int) * p->sizelineinfo + sizeof(LocVar) * p->sizelocvars + 97 sizeof(int) * p->sizelineinfo + sizeof(LocVar) * p->sizelocvars +
98 sizeof(TString *) * p->sizeupvalues; 98 sizeof(TString *) * p->sizeupvalues;
99 } 99 }
@@ -112,29 +112,29 @@ static void reallymarkobject (global_State *g, GCObject *o) {
112 return; 112 return;
113 } 113 }
114 case LUA_TUSERDATA: { 114 case LUA_TUSERDATA: {
115 Table *mt = gcotou(o)->uv.metatable; 115 Table *mt = gco2u(o)->metatable;
116 gray2black(o); /* udata are never gray */ 116 gray2black(o); /* udata are never gray */
117 if (mt) markobject(g, mt); 117 if (mt) markobject(g, mt);
118 return; 118 return;
119 } 119 }
120 case LUA_TFUNCTION: { 120 case LUA_TFUNCTION: {
121 gcotocl(o)->c.gclist = g->gray; 121 gco2cl(o)->c.gclist = g->gray;
122 break; 122 break;
123 } 123 }
124 case LUA_TTABLE: { 124 case LUA_TTABLE: {
125 gcotoh(o)->gclist = g->gray; 125 gco2h(o)->gclist = g->gray;
126 break; 126 break;
127 } 127 }
128 case LUA_TTHREAD: { 128 case LUA_TTHREAD: {
129 gcototh(o)->gclist = g->gray; 129 gco2th(o)->gclist = g->gray;
130 break; 130 break;
131 } 131 }
132 case LUA_TPROTO: { 132 case LUA_TPROTO: {
133 gcotop(o)->gclist = g->gray; 133 gco2p(o)->gclist = g->gray;
134 break; 134 break;
135 } 135 }
136 case LUA_TUPVAL: { 136 case LUA_TUPVAL: {
137 gcotouv(o)->gclist = g->gray; 137 gco2uv(o)->gclist = g->gray;
138 break; 138 break;
139 } 139 }
140 default: lua_assert(0); 140 default: lua_assert(0);
@@ -161,15 +161,15 @@ size_t luaC_separateudata (lua_State *L) {
161 GCObject **lastcollected = &collected; 161 GCObject **lastcollected = &collected;
162 while ((curr = *p) != NULL) { 162 while ((curr = *p) != NULL) {
163 lua_assert(curr->gch.tt == LUA_TUSERDATA); 163 lua_assert(curr->gch.tt == LUA_TUSERDATA);
164 if (!iswhite(curr) || isfinalized(gcotou(curr))) 164 if (!iswhite(curr) || isfinalized(gco2u(curr)))
165 p = &curr->gch.next; /* don't bother with them */ 165 p = &curr->gch.next; /* don't bother with them */
166 else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) { 166 else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
167 markfinalized(gcotou(curr)); /* don't need finalization */ 167 markfinalized(gco2u(curr)); /* don't need finalization */
168 p = &curr->gch.next; 168 p = &curr->gch.next;
169 } 169 }
170 else { /* must call its gc method */ 170 else { /* must call its gc method */
171 deadmem += sizeudata(gcotou(curr)->uv.len); 171 deadmem += sizeudata(gco2u(curr)->len);
172 markfinalized(gcotou(curr)); 172 markfinalized(gco2u(curr));
173 *p = curr->gch.next; 173 *p = curr->gch.next;
174 curr->gch.next = NULL; /* link `curr' at the end of `collected' list */ 174 curr->gch.next = NULL; /* link `curr' at the end of `collected' list */
175 *lastcollected = curr; 175 *lastcollected = curr;
@@ -187,7 +187,7 @@ static void traversetable (global_State *g, Table *h) {
187 int i; 187 int i;
188 int weakkey = 0; 188 int weakkey = 0;
189 int weakvalue = 0; 189 int weakvalue = 0;
190 const TObject *mode; 190 const TValue *mode;
191 if (h->metatable) 191 if (h->metatable)
192 markobject(g, h->metatable); 192 markobject(g, h->metatable);
193 lua_assert(h->lsizenode || h->node == g->dummynode); 193 lua_assert(h->lsizenode || h->node == g->dummynode);
@@ -200,7 +200,7 @@ static void traversetable (global_State *g, Table *h) {
200 h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) | 200 h->marked |= cast(lu_byte, (weakkey << KEYWEAKBIT) |
201 (weakvalue << VALUEWEAKBIT)); 201 (weakvalue << VALUEWEAKBIT));
202 h->gclist = g->weak; /* must be cleared after GC, ... */ 202 h->gclist = g->weak; /* must be cleared after GC, ... */
203 g->weak = valtogco(h); /* ... so put in the appropriate list */ 203 g->weak = obj2gco(h); /* ... so put in the appropriate list */
204 } 204 }
205 } 205 }
206 if (weakkey && weakvalue) return; 206 if (weakkey && weakvalue) return;
@@ -230,7 +230,7 @@ static void traverseproto (global_State *g, Proto *f) {
230 if (f->source) stringmark(f->source); 230 if (f->source) stringmark(f->source);
231 for (i=0; i<f->sizek; i++) { /* mark literal strings */ 231 for (i=0; i<f->sizek; i++) { /* mark literal strings */
232 if (ttisstring(f->k+i)) 232 if (ttisstring(f->k+i))
233 stringmark(tsvalue(f->k+i)); 233 stringmark(rawtsvalue(f->k+i));
234 } 234 }
235 for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */ 235 for (i=0; i<f->sizeupvalues; i++) { /* mark upvalue names */
236 if (f->upvalues[i]) 236 if (f->upvalues[i])
@@ -306,19 +306,19 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
306 gray2black(o); 306 gray2black(o);
307 switch (o->gch.tt) { 307 switch (o->gch.tt) {
308 case LUA_TTABLE: { 308 case LUA_TTABLE: {
309 Table *h = gcotoh(o); 309 Table *h = gco2h(o);
310 g->gray = h->gclist; 310 g->gray = h->gclist;
311 traversetable(g, h); 311 traversetable(g, h);
312 break; 312 break;
313 } 313 }
314 case LUA_TFUNCTION: { 314 case LUA_TFUNCTION: {
315 Closure *cl = gcotocl(o); 315 Closure *cl = gco2cl(o);
316 g->gray = cl->c.gclist; 316 g->gray = cl->c.gclist;
317 traverseclosure(g, cl); 317 traverseclosure(g, cl);
318 break; 318 break;
319 } 319 }
320 case LUA_TTHREAD: { 320 case LUA_TTHREAD: {
321 lua_State *th = gcototh(o); 321 lua_State *th = gco2th(o);
322 g->gray = th->gclist; 322 g->gray = th->gclist;
323 th->gclist = g->grayagain; 323 th->gclist = g->grayagain;
324 g->grayagain = o; 324 g->grayagain = o;
@@ -327,13 +327,13 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
327 break; 327 break;
328 } 328 }
329 case LUA_TPROTO: { 329 case LUA_TPROTO: {
330 Proto *p = gcotop(o); 330 Proto *p = gco2p(o);
331 g->gray = p->gclist; 331 g->gray = p->gclist;
332 traverseproto(g, p); 332 traverseproto(g, p);
333 break; 333 break;
334 } 334 }
335 case LUA_TUPVAL: { 335 case LUA_TUPVAL: {
336 UpVal *uv = gcotouv(o); 336 UpVal *uv = gco2uv(o);
337 g->gray = uv->gclist; 337 g->gray = uv->gclist;
338 if (uv->v != &uv->value) { /* open? */ 338 if (uv->v != &uv->value) { /* open? */
339 uv->gclist = g->grayagain; 339 uv->gclist = g->grayagain;
@@ -360,10 +360,10 @@ static l_mem propagatemarks (global_State *g, l_mem lim) {
360** other objects: if really collected, cannot keep them; for userdata 360** other objects: if really collected, cannot keep them; for userdata
361** being finalized, keep them in keys, but not in values 361** being finalized, keep them in keys, but not in values
362*/ 362*/
363static int iscleared (const TObject *o, int iskey) { 363static int iscleared (const TValue *o, int iskey) {
364 if (!iscollectable(o)) return 0; 364 if (!iscollectable(o)) return 0;
365 if (ttisstring(o)) { 365 if (ttisstring(o)) {
366 stringmark(tsvalue(o)); /* strings are `values', so are never weak */ 366 stringmark(rawtsvalue(o)); /* strings are `values', so are never weak */
367 return 0; 367 return 0;
368 } 368 }
369 return iswhite(gcvalue(o)) || 369 return iswhite(gcvalue(o)) ||
@@ -383,13 +383,13 @@ static void removekey (Node *n) {
383*/ 383*/
384static void cleartable (GCObject *l) { 384static void cleartable (GCObject *l) {
385 while (l) { 385 while (l) {
386 Table *h = gcotoh(l); 386 Table *h = gco2h(l);
387 int i = h->sizearray; 387 int i = h->sizearray;
388 lua_assert(testbit(h->marked, VALUEWEAKBIT) || 388 lua_assert(testbit(h->marked, VALUEWEAKBIT) ||
389 testbit(h->marked, KEYWEAKBIT)); 389 testbit(h->marked, KEYWEAKBIT));
390 if (testbit(h->marked, VALUEWEAKBIT)) { 390 if (testbit(h->marked, VALUEWEAKBIT)) {
391 while (i--) { 391 while (i--) {
392 TObject *o = &h->array[i]; 392 TValue *o = &h->array[i];
393 if (iscleared(o, 0)) /* value was collected? */ 393 if (iscleared(o, 0)) /* value was collected? */
394 setnilvalue(o); /* remove value */ 394 setnilvalue(o); /* remove value */
395 } 395 }
@@ -408,21 +408,21 @@ static void cleartable (GCObject *l) {
408 408
409static void freeobj (lua_State *L, GCObject *o) { 409static void freeobj (lua_State *L, GCObject *o) {
410 switch (o->gch.tt) { 410 switch (o->gch.tt) {
411 case LUA_TPROTO: luaF_freeproto(L, gcotop(o)); break; 411 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
412 case LUA_TFUNCTION: luaF_freeclosure(L, gcotocl(o)); break; 412 case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
413 case LUA_TUPVAL: luaM_freelem(L, gcotouv(o)); break; 413 case LUA_TUPVAL: luaM_freelem(L, gco2uv(o)); break;
414 case LUA_TTABLE: luaH_free(L, gcotoh(o)); break; 414 case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
415 case LUA_TTHREAD: { 415 case LUA_TTHREAD: {
416 lua_assert(gcototh(o) != L && gcototh(o) != G(L)->mainthread); 416 lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
417 luaE_freethread(L, gcototh(o)); 417 luaE_freethread(L, gco2th(o));
418 break; 418 break;
419 } 419 }
420 case LUA_TSTRING: { 420 case LUA_TSTRING: {
421 luaM_free(L, o, sizestring(gcotots(o)->tsv.len)); 421 luaM_free(L, o, sizestring(gco2ts(o)->len));
422 break; 422 break;
423 } 423 }
424 case LUA_TUSERDATA: { 424 case LUA_TUSERDATA: {
425 luaM_free(L, o, sizeudata(gcotou(o)->uv.len)); 425 luaM_free(L, o, sizeudata(gco2u(o)->len));
426 break; 426 break;
427 } 427 }
428 default: lua_assert(0); 428 default: lua_assert(0);
@@ -463,7 +463,7 @@ static l_mem sweepstrings (lua_State *L, int all, l_mem lim) {
463 GCObject **p = &G(L)->strt.hash[i]; 463 GCObject **p = &G(L)->strt.hash[i];
464 while ((curr = *p) != NULL) { 464 while ((curr = *p) != NULL) {
465 int mark = curr->gch.marked; 465 int mark = curr->gch.marked;
466 lu_mem size = sizestring(gcotots(curr)->tsv.len); 466 lu_mem size = sizestring(gco2ts(curr)->len);
467 if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) { 467 if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) {
468 makewhite(g, curr); 468 makewhite(g, curr);
469 lua_assert(iswhite(curr) && !isdead(g, curr)); 469 lua_assert(iswhite(curr) && !isdead(g, curr));
@@ -503,8 +503,8 @@ static void GCTM (lua_State *L) {
503 g->gcstate = GCSroot; /* will restart GC */ 503 g->gcstate = GCSroot; /* will restart GC */
504 else { 504 else {
505 GCObject *o = g->tmudata; 505 GCObject *o = g->tmudata;
506 Udata *udata = gcotou(o); 506 Udata *udata = rawgco2u(o);
507 const TObject *tm; 507 const TValue *tm;
508 g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ 508 g->tmudata = udata->uv.next; /* remove udata from `tmudata' */
509 udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */ 509 udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */
510 g->firstudata->uv.next = o; 510 g->firstudata->uv.next = o;
@@ -513,8 +513,8 @@ static void GCTM (lua_State *L) {
513 if (tm != NULL) { 513 if (tm != NULL) {
514 lu_byte oldah = L->allowhook; 514 lu_byte oldah = L->allowhook;
515 L->allowhook = 0; /* stop debug hooks during GC tag method */ 515 L->allowhook = 0; /* stop debug hooks during GC tag method */
516 setobj2s(L->top, tm); 516 setobj2s(L, L->top, tm);
517 setuvalue(L->top+1, udata); 517 setuvalue(L, L->top+1, udata);
518 L->top += 2; 518 L->top += 2;
519 luaD_call(L, L->top - 2, 0); 519 luaD_call(L, L->top - 2, 0);
520 L->allowhook = oldah; /* restore hooks */ 520 L->allowhook = oldah; /* restore hooks */
@@ -545,7 +545,7 @@ static void markroot (lua_State *L) {
545 global_State *g = G(L); 545 global_State *g = G(L);
546 lua_assert(g->gray == NULL); 546 lua_assert(g->gray == NULL);
547 g->weak = NULL; 547 g->weak = NULL;
548 makewhite(g, valtogco(g->mainthread)); 548 makewhite(g, obj2gco(g->mainthread));
549 markobject(g, g->mainthread); 549 markobject(g, g->mainthread);
550 markvalue(g, registry(L)); 550 markvalue(g, registry(L));
551 markobject(g, L); /* mark running thread */ 551 markobject(g, L); /* mark running thread */