From 0e54d2be365ec77cb455e0d0f3c5c6f9efa6e04c Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 15 Sep 2004 17:38:15 -0300 Subject: [PATCH] bug: barrier was wrong for generational phase --- lgc.c | 18 +++++++++++------- lgc.h | 6 +++++- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lgc.c b/lgc.c index 6beaa55b..1273d58d 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.10 2004/08/30 13:44:44 roberto Exp roberto $ +** $Id: lgc.c,v 2.11 2004/09/08 14:23:09 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -499,7 +499,7 @@ void luaC_freeall (lua_State *L) { /* mark root set */ static void markroot (lua_State *L) { global_State *g = G(L); - lua_assert(g->gray == NULL); + g->gray = NULL; g->grayagain = NULL; g->weak = NULL; markobject(g, g->mainthread); @@ -513,6 +513,7 @@ 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) { @@ -529,7 +530,8 @@ static void remarkupvals (global_State *g) { static void atomic (lua_State *L) { global_State *g = G(L); int aux; - lua_assert(g->gray == NULL); + /* remark objects cautch by write barrier */ + propagateall(g); /* remark occasional upvalues of (maybe) dead threads */ remarkupvals(g); /* remark weak tables */ @@ -669,10 +671,12 @@ void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { global_State *g = G(L); lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); lua_assert(g->gcgenerational || g->gcstate != GCSfinalize); - if (g->gcstate != GCSpropagate) /* sweeping phases? */ - black2gray(o); /* just mark as gray to avoid other barriers */ - else /* breaking invariant! */ - reallymarkobject(g, v); /* restore it */ + lua_assert(ttype(&o->gch) != LUA_TTABLE); + /* must keep invariant? */ + if (g->gcstate == GCSpropagate || g->gcgenerational) + reallymarkobject(g, v); /* restore invariant */ + else /* don't mind */ + makewhite(g, o); /* mark as white just to avoid other barriers */ } diff --git a/lgc.h b/lgc.h index b4097b05..f8a18782 100644 --- a/lgc.h +++ b/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.7 2004/08/24 20:12:06 roberto Exp roberto $ +** $Id: lgc.h,v 2.8 2004/08/30 13:44:44 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -86,6 +86,10 @@ { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ luaC_barrierf(L,obj2gco(p),obj2gco(o)); } +#define luaC_objbarriert(L,p,o) \ + { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrierback(L,obj2gco(p),obj2gco(o)); } + size_t luaC_separateudata (lua_State *L, int all); void luaC_callGCTM (lua_State *L); void luaC_freeall (lua_State *L);