cleaner way to remark open upvalues
This commit is contained in:
37
lgc.c
37
lgc.c
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
** $Id: lgc.c,v 2.20 2005/01/05 18:20:51 roberto Exp roberto $
|
||||
** $Id: lgc.c,v 2.21 2005/01/14 14:19:42 roberto Exp $
|
||||
** Garbage Collector
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
@@ -83,10 +83,9 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
||||
}
|
||||
case LUA_TUPVAL: {
|
||||
UpVal *uv = gco2uv(o);
|
||||
if (uv->v == &uv->value) { /* closed? */
|
||||
markvalue(g, uv->v);
|
||||
gray2black(o);
|
||||
}
|
||||
markvalue(g, uv->v);
|
||||
if (uv->v == &uv->u.value) /* closed? */
|
||||
gray2black(o); /* open upvalues are never black */
|
||||
return;
|
||||
}
|
||||
case LUA_TFUNCTION: {
|
||||
@@ -126,11 +125,11 @@ static void marktmu (global_State *g) {
|
||||
/* move `dead' udata that need finalization to list `tmudata' */
|
||||
size_t luaC_separateudata (lua_State *L, int all) {
|
||||
size_t deadmem = 0;
|
||||
GCObject **p = &G(L)->firstudata;
|
||||
GCObject **p = &G(L)->mainthread->next;
|
||||
GCObject *curr;
|
||||
GCObject *collected = NULL; /* to collect udata with gc event */
|
||||
GCObject **lastcollected = &collected;
|
||||
while ((curr = *p)->gch.tt == LUA_TUSERDATA) {
|
||||
while ((curr = *p) != NULL) {
|
||||
if (!(iswhite(curr) || all) || isfinalized(gco2u(curr)))
|
||||
p = &curr->gch.next; /* don't bother with them */
|
||||
else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) {
|
||||
@@ -146,7 +145,6 @@ size_t luaC_separateudata (lua_State *L, int all) {
|
||||
lastcollected = &curr->gch.next;
|
||||
}
|
||||
}
|
||||
lua_assert(curr == obj2gco(G(L)->mainthread));
|
||||
/* insert collected udata with gc event into `tmudata' list */
|
||||
*lastcollected = G(L)->tmudata;
|
||||
G(L)->tmudata = collected;
|
||||
@@ -380,7 +378,7 @@ static void freeobj (lua_State *L, GCObject *o) {
|
||||
switch (o->gch.tt) {
|
||||
case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
|
||||
case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
|
||||
case LUA_TUPVAL: luaM_free(L, gco2uv(o)); break;
|
||||
case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
|
||||
case LUA_TTABLE: luaH_free(L, gco2h(o)); break;
|
||||
case LUA_TTHREAD: {
|
||||
lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
|
||||
@@ -461,8 +459,8 @@ static void GCTM (lua_State *L) {
|
||||
Udata *udata = rawgco2u(o);
|
||||
const TValue *tm;
|
||||
g->tmudata = udata->uv.next; /* remove udata from `tmudata' */
|
||||
udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */
|
||||
g->firstudata->uv.next = o;
|
||||
udata->uv.next = g->mainthread->next; /* return it to `root' list */
|
||||
g->mainthread->next = o;
|
||||
makewhite(g, o);
|
||||
tm = fasttm(L, udata->uv.metatable, TM_GC);
|
||||
if (tm != NULL) {
|
||||
@@ -510,18 +508,11 @@ static void markroot (lua_State *L) {
|
||||
|
||||
|
||||
static void remarkupvals (global_State *g) {
|
||||
GCObject *o;
|
||||
for (o = obj2gco(g->mainthread); o; o = o->gch.next) {
|
||||
lua_assert(!isblack(o));
|
||||
if (iswhite(o)) {
|
||||
GCObject *curr;
|
||||
for (curr = gco2th(o)->openupval; curr != NULL; curr = curr->gch.next) {
|
||||
if (isgray(curr)) {
|
||||
UpVal *uv = gco2uv(curr);
|
||||
markvalue(g, uv->v);
|
||||
}
|
||||
}
|
||||
}
|
||||
UpVal *uv;
|
||||
for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {
|
||||
lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
|
||||
if (isgray(obj2gco(uv)))
|
||||
markvalue(g, uv->v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user