aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2008-06-23 19:07:44 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2008-06-23 19:07:44 -0300
commitc3525610fea8554e6ee4cb9bdd144d25764ddfad (patch)
tree5bafab732fff4b7b8d5ccb08857907e8ee842b96 /lgc.c
parent7ba62e29856458469ae42a7be83856a0ec81e539 (diff)
downloadlua-c3525610fea8554e6ee4cb9bdd144d25764ddfad.tar.gz
lua-c3525610fea8554e6ee4cb9bdd144d25764ddfad.tar.bz2
lua-c3525610fea8554e6ee4cb9bdd144d25764ddfad.zip
bug: when closing the state, 'luaC_separateudata' might mark
userdata in the wrong phase of collection, therefore avoiding their traversal
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/lgc.c b/lgc.c
index f38f08f9..0d0579d0 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.44 2008/02/19 18:55:09 roberto Exp roberto $ 2** $Id: lgc.c,v 2.45 2008/06/23 16:51:28 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -210,7 +210,6 @@ static void markbeingfnz (global_State *g) {
210 do { 210 do {
211 u = gch(u)->next; 211 u = gch(u)->next;
212 lua_assert(testbit(gch(u)->marked, SEPARATED)); 212 lua_assert(testbit(gch(u)->marked, SEPARATED));
213 lua_assert(!iswhite(u)); /* must be marked, if left from previous GC */
214 makewhite(g, u); 213 makewhite(g, u);
215 reallymarkobject(g, u); 214 reallymarkobject(g, u);
216 } while (u != g->tobefnz); 215 } while (u != g->tobefnz);
@@ -664,12 +663,10 @@ size_t luaC_separateudata (lua_State *L, int all) {
664 while ((curr = *p) != NULL) { 663 while ((curr = *p) != NULL) {
665 lua_assert(ttisuserdata(gch(curr)) && !isfinalized(gco2u(curr))); 664 lua_assert(ttisuserdata(gch(curr)) && !isfinalized(gco2u(curr)));
666 lua_assert(testbit(gch(curr)->marked, SEPARATED)); 665 lua_assert(testbit(gch(curr)->marked, SEPARATED));
667 if (all) makewhite(g, curr); /* if 'all', collect all objects */ 666 if (!(all || iswhite(curr))) /* not being collected? */
668 if (!iswhite(curr)) /* not being collected? */
669 p = &gch(curr)->next; /* don't bother with it */ 667 p = &gch(curr)->next; /* don't bother with it */
670 else { 668 else {
671 l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ 669 l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */
672 reallymarkobject(g, curr); /* won't be collected now */
673 deadmem += sizeudata(gco2u(curr)); 670 deadmem += sizeudata(gco2u(curr));
674 *p = gch(curr)->next; /* remove 'curr' from 'tmudata' list */ 671 *p = gch(curr)->next; /* remove 'curr' from 'tmudata' list */
675 /* link 'curr' at the end of 'tobefnz' list */ 672 /* link 'curr' at the end of 'tobefnz' list */
@@ -746,6 +743,7 @@ static void atomic (lua_State *L) {
746 traverselistofgrays(g, &g->grayagain); /* remark gray again */ 743 traverselistofgrays(g, &g->grayagain); /* remark gray again */
747 convergeephemerons(g); 744 convergeephemerons(g);
748 udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */ 745 udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
746 markbeingfnz(g); /* mark userdata that will be finalized */
749 udsize += propagateall(g); /* remark, to propagate `preserveness' */ 747 udsize += propagateall(g); /* remark, to propagate `preserveness' */
750 convergeephemerons(g); 748 convergeephemerons(g);
751 /* remove collected objects from weak tables */ 749 /* remove collected objects from weak tables */