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 | /* |