nasty GC bug: upvalue must be turned white when not keeping invariant,

but barrier was not being called when uv->v were already white.
This commit is contained in:
Roberto Ierusalimschy
2010-04-29 18:43:36 -03:00
parent 5d79c6684b
commit 23001d8607
3 changed files with 26 additions and 9 deletions

22
lgc.c
View File

@@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 2.80 2010/04/26 17:58:00 roberto Exp roberto $
** $Id: lgc.c,v 2.81 2010/04/29 17:32:40 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -146,6 +146,26 @@ void luaC_barrierback (lua_State *L, Table *t) {
}
/*
** check color (and invariants) for an upvalue that was closed,
** i.e., moved into the 'allgc' list
*/
void luaC_checkupvalcolor (global_State *g, UpVal *uv) {
GCObject *o = obj2gco(uv);
lua_assert(!isblack(o)); /* open upvalues are never black */
if (isgray(o)) {
if (keepinvariant(g)) {
gray2black(o); /* it is being visited now */
markvalue(g, uv->v);
}
else {
lua_assert(issweepphase(g));
makewhite(g, o);
}
}
}
/*
** create a new collectable object (with given type and size) and link
** it to '*list'. 'offset' tells how many bytes to allocate before the