diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-09-11 09:53:08 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-09-11 09:53:08 -0300 |
| commit | ae1d318822c2b531aa69ac0dfed1edc6470f6200 (patch) | |
| tree | 2a93331ab50067c4c68d9953b5a0c50903420314 | |
| parent | 203807397550ab35ad3a6f282b74b2bf40bc69c7 (diff) | |
| download | lua-ae1d318822c2b531aa69ac0dfed1edc6470f6200.tar.gz lua-ae1d318822c2b531aa69ac0dfed1edc6470f6200.tar.bz2 lua-ae1d318822c2b531aa69ac0dfed1edc6470f6200.zip | |
small bug: generational mode is always in 'propagate' mode only
outside the collector: during collection of course it must go to
other modes.
| -rw-r--r-- | lgc.c | 12 | ||||
| -rw-r--r-- | lgc.h | 19 |
2 files changed, 21 insertions, 10 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.134 2012/07/02 13:40:05 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.135 2012/07/04 15:52:38 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 | */ |
| @@ -146,7 +146,7 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { | |||
| 146 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); | 146 | lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); |
| 147 | lua_assert(g->gcstate != GCSpause); | 147 | lua_assert(g->gcstate != GCSpause); |
| 148 | lua_assert(gch(o)->tt != LUA_TTABLE); | 148 | lua_assert(gch(o)->tt != LUA_TTABLE); |
| 149 | if (keepinvariant(g)) /* must keep invariant? */ | 149 | if (keepinvariantout(g)) /* must keep invariant? */ |
| 150 | reallymarkobject(g, v); /* restore invariant */ | 150 | reallymarkobject(g, v); /* restore invariant */ |
| 151 | else { /* sweep phase */ | 151 | else { /* sweep phase */ |
| 152 | lua_assert(issweepphase(g)); | 152 | lua_assert(issweepphase(g)); |
| @@ -796,7 +796,7 @@ static GCObject *udata2finalize (global_State *g) { | |||
| 796 | g->allgc = o; | 796 | g->allgc = o; |
| 797 | resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ | 797 | resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ |
| 798 | lua_assert(!isold(o)); /* see MOVE OLD rule */ | 798 | lua_assert(!isold(o)); /* see MOVE OLD rule */ |
| 799 | if (!keepinvariant(g)) /* not keeping invariant? */ | 799 | if (!keepinvariantout(g)) /* not keeping invariant? */ |
| 800 | makewhite(g, o); /* "sweep" object */ | 800 | makewhite(g, o); /* "sweep" object */ |
| 801 | return o; | 801 | return o; |
| 802 | } | 802 | } |
| @@ -891,7 +891,7 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { | |||
| 891 | ho->next = g->finobj; /* link it in list 'finobj' */ | 891 | ho->next = g->finobj; /* link it in list 'finobj' */ |
| 892 | g->finobj = o; | 892 | g->finobj = o; |
| 893 | l_setbit(ho->marked, SEPARATED); /* mark it as such */ | 893 | l_setbit(ho->marked, SEPARATED); /* mark it as such */ |
| 894 | if (!keepinvariant(g)) /* not keeping invariant? */ | 894 | if (!keepinvariantout(g)) /* not keeping invariant? */ |
| 895 | makewhite(g, o); /* "sweep" object */ | 895 | makewhite(g, o); /* "sweep" object */ |
| 896 | else | 896 | else |
| 897 | resetoldbit(o); /* see MOVE OLD rule */ | 897 | resetoldbit(o); /* see MOVE OLD rule */ |
| @@ -985,7 +985,7 @@ void luaC_freeallobjects (lua_State *L) { | |||
| 985 | 985 | ||
| 986 | static l_mem atomic (lua_State *L) { | 986 | static l_mem atomic (lua_State *L) { |
| 987 | global_State *g = G(L); | 987 | global_State *g = G(L); |
| 988 | l_mem work = -g->GCmemtrav; /* start counting work */ | 988 | l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ |
| 989 | GCObject *origweak, *origall; | 989 | GCObject *origweak, *origall; |
| 990 | lua_assert(!iswhite(obj2gco(g->mainthread))); | 990 | lua_assert(!iswhite(obj2gco(g->mainthread))); |
| 991 | markobject(g, L); /* mark running thread */ | 991 | markobject(g, L); /* mark running thread */ |
| @@ -1118,6 +1118,7 @@ static void generationalcollection (lua_State *L) { | |||
| 1118 | 1118 | ||
| 1119 | } | 1119 | } |
| 1120 | luaE_setdebt(g, stddebt(g)); | 1120 | luaE_setdebt(g, stddebt(g)); |
| 1121 | lua_assert(g->gcstate == GCSpropagate); | ||
| 1121 | } | 1122 | } |
| 1122 | 1123 | ||
| 1123 | 1124 | ||
| @@ -1160,6 +1161,7 @@ void luaC_forcestep (lua_State *L) { | |||
| 1160 | */ | 1161 | */ |
| 1161 | void luaC_step (lua_State *L) { | 1162 | void luaC_step (lua_State *L) { |
| 1162 | global_State *g = G(L); | 1163 | global_State *g = G(L); |
| 1164 | /* lua_checkmemory(L); */ /* for internal debugging */ | ||
| 1163 | if (g->gcrunning) luaC_forcestep(L); | 1165 | if (g->gcrunning) luaC_forcestep(L); |
| 1164 | else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ | 1166 | else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ |
| 1165 | } | 1167 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.h,v 2.56 2012/05/23 15:43:14 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 2.57 2012/07/04 15:52:38 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 | */ |
| @@ -50,15 +50,24 @@ | |||
| 50 | #define isgenerational(g) ((g)->gckind == KGC_GEN) | 50 | #define isgenerational(g) ((g)->gckind == KGC_GEN) |
| 51 | 51 | ||
| 52 | /* | 52 | /* |
| 53 | ** macro to tell when main invariant (white objects cannot point to black | 53 | ** macros to tell when main invariant (white objects cannot point to black |
| 54 | ** ones) must be kept. During a non-generational collection, the sweep | 54 | ** ones) must be kept. During a non-generational collection, the sweep |
| 55 | ** phase may break the invariant, as objects turned white may point to | 55 | ** phase may break the invariant, as objects turned white may point to |
| 56 | ** still-black objects. The invariant is restored when sweep ends and | 56 | ** still-black objects. The invariant is restored when sweep ends and |
| 57 | ** all objects are white again. During a generational collection, the | 57 | ** all objects are white again. During a generational collection, the |
| 58 | ** invariant must be kept all times. (The state in generational mode | 58 | ** invariant must be kept all times. |
| 59 | ** is kept in 'propagate', so 'keepinvariant' is always true.) | ||
| 60 | */ | 59 | */ |
| 61 | #define keepinvariant(g) (g->gcstate <= GCSatomic) | 60 | |
| 61 | #define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) | ||
| 62 | |||
| 63 | |||
| 64 | /* | ||
| 65 | ** Outside the collector, the state in generational mode is kept in | ||
| 66 | ** 'propagate', so 'keepinvariant' is always true. | ||
| 67 | */ | ||
| 68 | #define keepinvariantout(g) \ | ||
| 69 | check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ | ||
| 70 | g->gcstate <= GCSatomic) | ||
| 62 | 71 | ||
| 63 | 72 | ||
| 64 | /* | 73 | /* |
