From ae1d318822c2b531aa69ac0dfed1edc6470f6200 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 11 Sep 2012 09:53:08 -0300 Subject: [PATCH] small bug: generational mode is always in 'propagate' mode only outside the collector: during collection of course it must go to other modes. --- lgc.c | 12 +++++++----- lgc.h | 19 ++++++++++++++----- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/lgc.c b/lgc.c index 8b559cb6..e76de73a 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.134 2012/07/02 13:40:05 roberto Exp roberto $ +** $Id: lgc.c,v 2.135 2012/07/04 15:52:38 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -146,7 +146,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); lua_assert(g->gcstate != GCSpause); lua_assert(gch(o)->tt != LUA_TTABLE); - if (keepinvariant(g)) /* must keep invariant? */ + if (keepinvariantout(g)) /* must keep invariant? */ reallymarkobject(g, v); /* restore invariant */ else { /* sweep phase */ lua_assert(issweepphase(g)); @@ -796,7 +796,7 @@ static GCObject *udata2finalize (global_State *g) { g->allgc = o; resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ lua_assert(!isold(o)); /* see MOVE OLD rule */ - if (!keepinvariant(g)) /* not keeping invariant? */ + if (!keepinvariantout(g)) /* not keeping invariant? */ makewhite(g, o); /* "sweep" object */ return o; } @@ -891,7 +891,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { ho->next = g->finobj; /* link it in list 'finobj' */ g->finobj = o; l_setbit(ho->marked, SEPARATED); /* mark it as such */ - if (!keepinvariant(g)) /* not keeping invariant? */ + if (!keepinvariantout(g)) /* not keeping invariant? */ makewhite(g, o); /* "sweep" object */ else resetoldbit(o); /* see MOVE OLD rule */ @@ -985,7 +985,7 @@ void luaC_freeallobjects (lua_State *L) { static l_mem atomic (lua_State *L) { global_State *g = G(L); - l_mem work = -g->GCmemtrav; /* start counting work */ + l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ GCObject *origweak, *origall; lua_assert(!iswhite(obj2gco(g->mainthread))); markobject(g, L); /* mark running thread */ @@ -1118,6 +1118,7 @@ static void generationalcollection (lua_State *L) { } luaE_setdebt(g, stddebt(g)); + lua_assert(g->gcstate == GCSpropagate); } @@ -1160,6 +1161,7 @@ void luaC_forcestep (lua_State *L) { */ void luaC_step (lua_State *L) { global_State *g = G(L); + /* lua_checkmemory(L); */ /* for internal debugging */ if (g->gcrunning) luaC_forcestep(L); else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ } diff --git a/lgc.h b/lgc.h index 569aefae..08899d9b 100644 --- a/lgc.h +++ b/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.56 2012/05/23 15:43:14 roberto Exp roberto $ +** $Id: lgc.h,v 2.57 2012/07/04 15:52:38 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -50,15 +50,24 @@ #define isgenerational(g) ((g)->gckind == KGC_GEN) /* -** macro to tell when main invariant (white objects cannot point to black +** macros to tell when main invariant (white objects cannot point to black ** ones) must be kept. During a non-generational collection, the sweep ** phase may break the invariant, as objects turned white may point to ** still-black objects. The invariant is restored when sweep ends and ** all objects are white again. During a generational collection, the -** invariant must be kept all times. (The state in generational mode -** is kept in 'propagate', so 'keepinvariant' is always true.) +** invariant must be kept all times. */ -#define keepinvariant(g) (g->gcstate <= GCSatomic) + +#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) + + +/* +** Outside the collector, the state in generational mode is kept in +** 'propagate', so 'keepinvariant' is always true. +*/ +#define keepinvariantout(g) \ + check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ + g->gcstate <= GCSatomic) /*