From d8aa8dd97e14dfd724e997261d305f2045d1ca63 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 11 Sep 2013 09:47:48 -0300 Subject: [PATCH] objects in list 'tobefnz' have a GC life-cycle like all others (specifically they are cleaned during sweep phase) --- lgc.c | 21 ++++++++++++--------- lgc.h | 7 ++++--- ltests.c | 10 +++++----- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/lgc.c b/lgc.c index 26da16de..e9149167 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.158 2013/09/03 15:37:10 roberto Exp roberto $ +** $Id: lgc.c,v 2.159 2013/09/11 12:26:14 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -85,9 +85,11 @@ lua_longassert(!(iscollectable(o) && islocal(gcvalue(o)))); \ marklocalvalue(g,o); } +#define marklocalobject(g,t) \ + { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); } + #define markobject(g,t) \ - { lua_assert((t) == NULL || !islocal(obj2gco(t))); \ - if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); } + { lua_assert((t) == NULL || !islocal(obj2gco(t))); marklocalobject(g,t); } static void reallymarkobject (global_State *g, GCObject *o); @@ -291,10 +293,8 @@ static void markmt (global_State *g) { */ static void markbeingfnz (global_State *g) { GCObject *o; - for (o = g->tobefnz; o != NULL; o = gch(o)->next) { - makewhite(g, o); - reallymarkobject(g, o); - } + for (o = g->tobefnz; o != NULL; o = gch(o)->next) + marklocalobject(g, o); } @@ -781,7 +781,7 @@ static GCObject *udata2finalize (global_State *g) { l_setbit(gch(o)->marked, LOCALMARK); } resetbit(gch(o)->marked, FINALIZEDBIT); /* object is back in 'allgc' */ - if (!keepinvariant(g)) /* not keeping invariant? */ + if (issweepphase(g)) makewhite(g, o); /* "sweep" object */ return o; } @@ -896,7 +896,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { ho->next = *p; /* link it in a "fin" list */ *p = o; l_setbit(ho->marked, FINALIZEDBIT); /* mark it as such */ - if (!keepinvariant(g)) /* not keeping invariant? */ + if (issweepphase(g)) makewhite(g, o); /* "sweep" object */ } } @@ -1159,6 +1159,9 @@ static lu_mem singlestep (lua_State *L) { return sweepstep(L, g, GCSsweepall, &g->allgc); } case GCSsweepall: { + return sweepstep(L, g, GCSsweeptobefnz, &g->tobefnz); + } + case GCSsweeptobefnz: { return sweepstep(L, g, GCSsweepmainth, NULL); } case GCSsweepmainth: { /* sweep main thread */ diff --git a/lgc.h b/lgc.h index 6912d24a..f52c9ae7 100644 --- a/lgc.h +++ b/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.71 2013/09/03 15:37:10 roberto Exp roberto $ +** $Id: lgc.h,v 2.72 2013/09/11 12:26:14 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -42,8 +42,9 @@ #define GCSsweeplocfin 3 #define GCSsweepfin 4 #define GCSsweepall 5 -#define GCSsweepmainth 6 -#define GCSpause 7 +#define GCSsweeptobefnz 6 +#define GCSsweepmainth 7 +#define GCSpause 8 #define issweepphase(g) \ diff --git a/ltests.c b/ltests.c index 7e275a3b..1db957cc 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.155 2013/09/05 19:31:49 roberto Exp roberto $ +** $Id: ltests.c,v 2.156 2013/09/11 12:26:14 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -469,8 +469,8 @@ int lua_checkmemory (lua_State *L) { /* check 'tobefnz' list */ checkgray(g, g->tobefnz); for (o = g->tobefnz; o != NULL; o = gch(o)->next) { - lua_assert(!iswhite(o) || g->gcstate == GCSpause); - lua_assert(!isdead(g, o) && tofinalize(o)); + checkobject(g, o, 0); + lua_assert(tofinalize(o)); lua_assert(gch(o)->tt == LUA_TUSERDATA || gch(o)->tt == LUA_TTABLE); } return 0; @@ -650,8 +650,8 @@ static int gc_local (lua_State *L) { static int gc_state (lua_State *L) { static const char *statenames[] = {"propagate", "atomic", - "sweeplocal", "sweeplocfin", "sweepfin", "sweepall", "sweepmainth", - "pause", ""}; + "sweeplocal", "sweeplocfin", "sweepfin", "sweepall", "sweeptobefnz", + "sweepmainth", "pause", ""}; int option = luaL_checkoption(L, 1, "", statenames); if (option == GCSpause + 1) { lua_pushstring(L, statenames[G(L)->gcstate]);