diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-01-18 15:18:09 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-01-18 15:18:09 -0200 |
commit | 334ba8132bd0471ffe2a9964b577d3ae89ec490a (patch) | |
tree | 3e0dde3bca4f1f51dad42d8c85ad9cb624aab1fa /lgc.c | |
parent | ac71a0891d8571816ce32b5c2c1fd97942decf71 (diff) | |
download | lua-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.c | 37 |
1 files changed, 14 insertions, 23 deletions
@@ -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' */ |
127 | size_t luaC_separateudata (lua_State *L, int all) { | 126 | size_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 | ||
512 | static void remarkupvals (global_State *g) { | 510 | static 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 | ||