From 1c1a98e872ad09b12fe2085031f0045f993ca5f0 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 10 May 2010 15:23:45 -0300 Subject: corrected some places where an old object could end up in front of a new one + minimal documentation about this problem --- lfunc.c | 8 +++++--- lgc.c | 9 ++++----- lgc.h | 5 ++++- lstring.c | 3 ++- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/lfunc.c b/lfunc.c index 4e72fcad..6c8dda4b 100644 --- a/lfunc.c +++ b/lfunc.c @@ -1,5 +1,5 @@ /* -** $Id: lfunc.c,v 2.22 2010/04/29 17:34:35 roberto Exp roberto $ +** $Id: lfunc.c,v 2.23 2010/04/29 21:43:36 roberto Exp roberto $ ** Auxiliary functions to manipulate prototypes and closures ** See Copyright Notice in lua.h */ @@ -52,12 +52,14 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { UpVal *p; UpVal *uv; while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { + GCObject *o = obj2gco(p); lua_assert(p->v != &p->u.value); if (p->v == level) { /* found a corresponding upvalue? */ - if (isdead(g, obj2gco(p))) /* is it dead? */ - changewhite(obj2gco(p)); /* ressurrect it */ + if (isdead(g, o)) /* is it dead? */ + changewhite(o); /* ressurrect it */ return p; } + resetoldbit(o); /* may create a newer upval after this one */ pp = &p->next; } /* not found: create a new one */ diff --git a/lgc.c b/lgc.c index 97f8bd4c..2ad6ca77 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.92 2010/05/07 18:43:24 roberto Exp roberto $ +** $Id: lgc.c,v 2.93 2010/05/10 16:46:49 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -164,7 +164,7 @@ void luaC_checkupvalcolor (global_State *g, UpVal *uv) { lua_assert(!isblack(o)); /* open upvalues are never black */ if (isgray(o)) { if (keepinvariant(g)) { - resetoldbit(o); + resetoldbit(o); /* see MOVE OLD rule */ gray2black(o); /* it is being visited now */ markvalue(g, uv->v); } @@ -670,6 +670,7 @@ static Udata *udata2finalize (global_State *g) { u->uv.next = g->allgc; /* return it to 'allgc' list */ g->allgc = o; resetbit(u->uv.marked, SEPARATED); /* mark that it is not in 'tobefnz' */ + resetoldbit(o); /* see MOVE OLD rule */ if (!keepinvariant(g)) /* not keeping invariant? */ makewhite(g, o); /* "sweep" object */ return u; @@ -729,7 +730,6 @@ void luaC_separateudata (lua_State *L, int all) { p = &gch(curr)->next; /* don't bother with it */ else { l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ - resetoldbit(curr); /* may be old when 'all' is true */ *p = gch(curr)->next; /* remove 'curr' from 'udgc' list */ gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ *lastnext = curr; @@ -756,7 +756,7 @@ void luaC_checkfinalizer (lua_State *L, Udata *u) { u->uv.next = g->udgc; /* link it in list 'udgc' */ g->udgc = obj2gco(u); l_setbit(u->uv.marked, SEPARATED); /* mark it as such */ - resetoldbit(obj2gco(u)); + resetoldbit(obj2gco(u)); /* see MOVE OLD rule */ } } @@ -854,7 +854,6 @@ static void atomic (lua_State *L) { static l_mem singlestep (lua_State *L) { global_State *g = G(L); - /*lua_checkmemory(L);*/ switch (g->gcstate) { case GCSpause: { if (!isgenerational(g)) diff --git a/lgc.h b/lgc.h index 938a1d49..ae45c80d 100644 --- a/lgc.h +++ b/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.39 2010/05/07 18:43:51 roberto Exp roberto $ +** $Id: lgc.h,v 2.40 2010/05/10 16:46:49 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -91,6 +91,9 @@ (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) #define isold(x) testbit((x)->gch.marked, OLDBIT) + +/* MOVE OLD rule: whenever an object is moved to the beginning of + a GC list, its old bit must be cleared */ #define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) #define otherwhite(g) (g->currentwhite ^ WHITEBITS) diff --git a/lstring.c b/lstring.c index dcc40fdd..4144cb18 100644 --- a/lstring.c +++ b/lstring.c @@ -1,5 +1,5 @@ /* -** $Id: lstring.c,v 2.16 2009/12/16 16:42:58 roberto Exp roberto $ +** $Id: lstring.c,v 2.17 2010/04/03 20:24:18 roberto Exp roberto $ ** String table (keeps all strings handled by Lua) ** See Copyright Notice in lua.h */ @@ -37,6 +37,7 @@ void luaS_resize (lua_State *L, int newsize) { unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ gch(p)->next = tb->hash[h]; /* chain it */ tb->hash[h] = p; + resetoldbit(p); /* see MOVE OLD rule */ p = next; } } -- cgit v1.2.3-55-g6feb