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 | ||
