From 623e388bb4c75eb07af3b7f83c736841d9fb76f0 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 7 Aug 2013 09:18:11 -0300 Subject: double-linked list of all upvalues elliminated and changed to a traversal of all non-marked threads --- lgc.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'lgc.c') diff --git a/lgc.c b/lgc.c index 8e73ff21..993af884 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.141 2013/04/26 18:26:49 roberto Exp roberto $ +** $Id: lgc.c,v 2.142 2013/08/05 16:58:28 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -258,7 +258,7 @@ static void reallymarkobject (global_State *g, GCObject *o) { case LUA_TUPVAL: { UpVal *uv = gco2uv(o); markvalue(g, uv->v); - if (uv->v != &uv->u.value) /* open? */ + if (uv->v != &uv->value) /* open? */ return; /* open upvalues remain gray */ size = sizeof(UpVal); break; @@ -317,14 +317,21 @@ static void markbeingfnz (global_State *g) { /* -** mark all values stored in marked open upvalues. (See comment in -** 'lstate.h'.) +** Mark all values stored in marked open upvalues from non-marked threads. +** (Values from marked threads were already marked when traversing the +** thread.) */ static void remarkupvals (global_State *g) { - UpVal *uv; - for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { - if (isgray(obj2gco(uv))) - markvalue(g, uv->v); + GCObject *thread = hvalue(&g->l_registry)->next; + for (; thread != NULL; thread = gch(thread)->next) { + lua_assert(!isblack(thread)); /* threads are never black */ + if (!isgray(thread)) { /* dead thread? */ + GCObject *uv = gco2th(thread)->openupval; + for (; uv != NULL; uv = gch(uv)->next) { + if (isgray(uv)) /* marked? */ + markvalue(g, gco2uv(uv)->v); /* remark upvalue's value */ + } + } } } @@ -669,7 +676,7 @@ static void freeobj (lua_State *L, GCObject *o) { luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); break; } - case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; + case LUA_TUPVAL: luaM_free(L, gco2uv(o)); break; case LUA_TTABLE: luaH_free(L, gco2t(o)); break; case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; -- cgit v1.2.3-55-g6feb