diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-07-04 12:52:38 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-07-04 12:52:38 -0300 |
commit | e4f609d0ee1cbbd357bec00c43effc659971bc7a (patch) | |
tree | 4be588031fdb7f63efafb86d42c37e53ab23fa26 /lgc.c | |
parent | 5ac56a94dd318aa3db031a31bdc03efb45386b9f (diff) | |
download | lua-e4f609d0ee1cbbd357bec00c43effc659971bc7a.tar.gz lua-e4f609d0ee1cbbd357bec00c43effc659971bc7a.tar.bz2 lua-e4f609d0ee1cbbd357bec00c43effc659971bc7a.zip |
collector in generational mode must be in 'propagate' state when
not running a collection
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 30 |
1 files changed, 13 insertions, 17 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.133 2012/05/31 21:28:59 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.134 2012/07/02 13:40:05 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 | */ |
@@ -144,7 +144,7 @@ static int iscleared (global_State *g, const TValue *o) { | |||
144 | void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { | 144 | void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { |
145 | global_State *g = G(L); | 145 | global_State *g = G(L); |
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(isgenerational(g) || 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 (keepinvariant(g)) /* must keep invariant? */ |
150 | reallymarkobject(g, v); /* restore invariant */ | 150 | reallymarkobject(g, v); /* restore invariant */ |
@@ -343,7 +343,7 @@ static void remarkupvals (global_State *g) { | |||
343 | ** mark root set and reset all gray lists, to start a new | 343 | ** mark root set and reset all gray lists, to start a new |
344 | ** incremental (or full) collection | 344 | ** incremental (or full) collection |
345 | */ | 345 | */ |
346 | static void startcollection (global_State *g) { | 346 | static void restartcollection (global_State *g) { |
347 | g->gray = g->grayagain = NULL; | 347 | g->gray = g->grayagain = NULL; |
348 | g->weak = g->allweak = g->ephemeron = NULL; | 348 | g->weak = g->allweak = g->ephemeron = NULL; |
349 | markobject(g, g->mainthread); | 349 | markobject(g, g->mainthread); |
@@ -855,7 +855,7 @@ static void separatetobefnz (lua_State *L, int all) { | |||
855 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ | 855 | while ((curr = *p) != NULL) { /* traverse all finalizable objects */ |
856 | lua_assert(!isfinalized(curr)); | 856 | lua_assert(!isfinalized(curr)); |
857 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); | 857 | lua_assert(testbit(gch(curr)->marked, SEPARATED)); |
858 | if (!(all || iswhite(curr))) /* not being collected? */ | 858 | if (!(iswhite(curr) || all)) /* not being collected? */ |
859 | p = &gch(curr)->next; /* don't bother with it */ | 859 | p = &gch(curr)->next; /* don't bother with it */ |
860 | else { | 860 | else { |
861 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ | 861 | l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ |
@@ -1029,11 +1029,8 @@ static lu_mem singlestep (lua_State *L) { | |||
1029 | switch (g->gcstate) { | 1029 | switch (g->gcstate) { |
1030 | case GCSpause: { | 1030 | case GCSpause: { |
1031 | g->GCmemtrav = 0; /* start to count memory traversed */ | 1031 | g->GCmemtrav = 0; /* start to count memory traversed */ |
1032 | if (!isgenerational(g)) | 1032 | lua_assert(!isgenerational(g)); |
1033 | startcollection(g); | 1033 | restartcollection(g); |
1034 | /* in any case, root must be marked at this point */ | ||
1035 | lua_assert(!iswhite(obj2gco(g->mainthread)) | ||
1036 | && !iswhite(gcvalue(&g->l_registry))); | ||
1037 | g->gcstate = GCSpropagate; | 1034 | g->gcstate = GCSpropagate; |
1038 | return g->GCmemtrav; | 1035 | return g->GCmemtrav; |
1039 | } | 1036 | } |
@@ -1105,14 +1102,15 @@ void luaC_runtilstate (lua_State *L, int statesmask) { | |||
1105 | 1102 | ||
1106 | static void generationalcollection (lua_State *L) { | 1103 | static void generationalcollection (lua_State *L) { |
1107 | global_State *g = G(L); | 1104 | global_State *g = G(L); |
1105 | lua_assert(g->gcstate == GCSpropagate); | ||
1108 | if (g->GCestimate == 0) { /* signal for another major collection? */ | 1106 | if (g->GCestimate == 0) { /* signal for another major collection? */ |
1109 | luaC_fullgc(L, 0); /* perform a full regular collection */ | 1107 | luaC_fullgc(L, 0); /* perform a full regular collection */ |
1110 | g->GCestimate = gettotalbytes(g); /* update control */ | 1108 | g->GCestimate = gettotalbytes(g); /* update control */ |
1111 | } | 1109 | } |
1112 | else { | 1110 | else { |
1113 | lu_mem estimate = g->GCestimate; | 1111 | lu_mem estimate = g->GCestimate; |
1114 | luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */ | 1112 | luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */ |
1115 | luaC_runtilstate(L, bitmask(GCSpause)); | 1113 | g->gcstate = GCSpropagate; /* skip restart */ |
1116 | if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc) | 1114 | if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc) |
1117 | g->GCestimate = 0; /* signal for a major collection */ | 1115 | g->GCestimate = 0; /* signal for a major collection */ |
1118 | else | 1116 | else |
@@ -1175,7 +1173,6 @@ void luaC_step (lua_State *L) { | |||
1175 | void luaC_fullgc (lua_State *L, int isemergency) { | 1173 | void luaC_fullgc (lua_State *L, int isemergency) { |
1176 | global_State *g = G(L); | 1174 | global_State *g = G(L); |
1177 | int origkind = g->gckind; | 1175 | int origkind = g->gckind; |
1178 | int someblack = keepinvariant(g); | ||
1179 | lua_assert(origkind != KGC_EMERGENCY); | 1176 | lua_assert(origkind != KGC_EMERGENCY); |
1180 | if (isemergency) /* do not run finalizers during emergency GC */ | 1177 | if (isemergency) /* do not run finalizers during emergency GC */ |
1181 | g->gckind = KGC_EMERGENCY; | 1178 | g->gckind = KGC_EMERGENCY; |
@@ -1183,18 +1180,17 @@ void luaC_fullgc (lua_State *L, int isemergency) { | |||
1183 | g->gckind = KGC_NORMAL; | 1180 | g->gckind = KGC_NORMAL; |
1184 | callallpendingfinalizers(L, 1); | 1181 | callallpendingfinalizers(L, 1); |
1185 | } | 1182 | } |
1186 | if (someblack) { /* may there be some black objects? */ | 1183 | if (keepinvariant(g)) { /* may there be some black objects? */ |
1187 | /* must sweep all objects to turn them back to white | 1184 | /* must sweep all objects to turn them back to white |
1188 | (as white has not changed, nothing will be collected) */ | 1185 | (as white has not changed, nothing will be collected) */ |
1189 | entersweep(L); | 1186 | entersweep(L); |
1190 | } | 1187 | } |
1191 | /* finish any pending sweep phase to start a new cycle */ | 1188 | /* finish any pending sweep phase to start a new cycle */ |
1192 | luaC_runtilstate(L, bitmask(GCSpause)); | 1189 | luaC_runtilstate(L, bitmask(GCSpause)); |
1193 | /* run entire collector */ | 1190 | luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ |
1194 | luaC_runtilstate(L, ~bitmask(GCSpause)); | 1191 | luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ |
1195 | luaC_runtilstate(L, bitmask(GCSpause)); | ||
1196 | if (origkind == KGC_GEN) { /* generational mode? */ | 1192 | if (origkind == KGC_GEN) { /* generational mode? */ |
1197 | /* generational mode must always start in propagate phase */ | 1193 | /* generational mode must be kept in propagate phase */ |
1198 | luaC_runtilstate(L, bitmask(GCSpropagate)); | 1194 | luaC_runtilstate(L, bitmask(GCSpropagate)); |
1199 | } | 1195 | } |
1200 | g->gckind = origkind; | 1196 | g->gckind = origkind; |