aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-01-18 15:18:09 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2005-01-18 15:18:09 -0200
commit334ba8132bd0471ffe2a9964b577d3ae89ec490a (patch)
tree3e0dde3bca4f1f51dad42d8c85ad9cb624aab1fa /lgc.c
parentac71a0891d8571816ce32b5c2c1fd97942decf71 (diff)
downloadlua-334ba8132bd0471ffe2a9964b577d3ae89ec490a.tar.gz
lua-334ba8132bd0471ffe2a9964b577d3ae89ec490a.tar.bz2
lua-334ba8132bd0471ffe2a9964b577d3ae89ec490a.zip
cleaner way to remark open upvalues
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c37
1 files changed, 14 insertions, 23 deletions
diff --git a/lgc.c b/lgc.c
index af16e882..d40b174c 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.20 2005/01/05 18:20:51 roberto Exp roberto $ 2** $Id: lgc.c,v 2.21 2005/01/14 14:19:42 roberto Exp $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -83,10 +83,9 @@ static void reallymarkobject (global_State *g, GCObject *o) {
83 } 83 }
84 case LUA_TUPVAL: { 84 case LUA_TUPVAL: {
85 UpVal *uv = gco2uv(o); 85 UpVal *uv = gco2uv(o);
86 if (uv->v == &uv->value) { /* closed? */ 86 markvalue(g, uv->v);
87 markvalue(g, uv->v); 87 if (uv->v == &uv->u.value) /* closed? */
88 gray2black(o); 88 gray2black(o); /* open upvalues are never black */
89 }
90 return; 89 return;
91 } 90 }
92 case LUA_TFUNCTION: { 91 case LUA_TFUNCTION: {
@@ -126,11 +125,11 @@ static void marktmu (global_State *g) {
126/* move `dead' udata that need finalization to list `tmudata' */ 125/* move `dead' udata that need finalization to list `tmudata' */
127size_t luaC_separateudata (lua_State *L, int all) { 126size_t luaC_separateudata (lua_State *L, int all) {
128 size_t deadmem = 0; 127 size_t deadmem = 0;
129 GCObject **p = &G(L)->firstudata; 128 GCObject **p = &G(L)->mainthread->next;
130 GCObject *curr; 129 GCObject *curr;
131 GCObject *collected = NULL; /* to collect udata with gc event */ 130 GCObject *collected = NULL; /* to collect udata with gc event */
132 GCObject **lastcollected = &collected; 131 GCObject **lastcollected = &collected;
133 while ((curr = *p)->gch.tt == LUA_TUSERDATA) { 132 while ((curr = *p) != NULL) {
134 if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) 133 if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
135 p = &curr->gch.next; /* don't bother with them */ 134 p = &curr->gch.next; /* don't bother with them */
136 else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { 135 else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
@@ -146,7 +145,6 @@ size_t luaC_separateudata (lua_State *L, int all) {
146 lastcollected = &curr->gch.next; 145 lastcollected = &curr->gch.next;
147 } 146 }
148 } 147 }
149 lua_assert(curr == obj2gco(G(L)->mainthread));
150 /* insert collected udata with gc event into `tmudata' list */ 148 /* insert collected udata with gc event into `tmudata' list */
151 *lastcollected = G(L)->tmudata; 149 *lastcollected = G(L)->tmudata;
152 G(L)->tmudata = collected; 150 G(L)->tmudata = collected;
@@ -380,7 +378,7 @@ static void freeobj (lua_State *L, GCObject *o) {
380 switch (o->gch.tt) { 378 switch (o->gch.tt) {
381 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; 379 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
382 case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; 380 case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
383 case LUA_TUPVAL: luaM_free(L, gco2uv(o)); break; 381 case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
384 case LUA_TTABLE: luaH_free(L, gco2h(o)); break; 382 case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
385 case LUA_TTHREAD: { 383 case LUA_TTHREAD: {
386 lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); 384 lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
@@ -461,8 +459,8 @@ static void GCTM (lua_State *L) {
461 Udata *udata = rawgco2u(o); 459 Udata *udata = rawgco2u(o);
462 const TValue *tm; 460 const TValue *tm;
463 g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ 461 g->tmudata = udata->uv.next; /* remove udata from `tmudata' */
464 udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */ 462 udata->uv.next = g->mainthread->next; /* return it to `root' list */
465 g->firstudata->uv.next = o; 463 g->mainthread->next = o;
466 makewhite(g, o); 464 makewhite(g, o);
467 tm = fasttm(L, udata->uv.metatable, TM_GC); 465 tm = fasttm(L, udata->uv.metatable, TM_GC);
468 if (tm != NULL) { 466 if (tm != NULL) {
@@ -510,18 +508,11 @@ static void markroot (lua_State *L) {
510 508
511 509
512static void remarkupvals (global_State *g) { 510static void remarkupvals (global_State *g) {
513 GCObject *o; 511 UpVal *uv;
514 for (o = obj2gco(g->mainthread); o; o = o->gch.next) { 512 for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
515 lua_assert(!isblack(o)); 513 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
516 if (iswhite(o)) { 514 if (isgray(obj2gco(uv)))
517 GCObject *curr; 515 markvalue(g, uv->v);
518 for (curr = gco2th(o)->openupval; curr != NULL; curr = curr->gch.next) {
519 if (isgray(curr)) {
520 UpVal *uv = gco2uv(curr);
521 markvalue(g, uv->v);
522 }
523 }
524 }
525 } 516 }
526} 517}
527 518