From 868ff40339fc72b7bf3c916afcdc2a992398346c Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 29 Dec 2010 16:00:23 -0200 Subject: full collection does not restart collector + avoid changing GC state if an error happens in a step --- lapi.c | 10 +++------- lgc.c | 32 ++++++++++++++++++++------------ lgc.h | 3 ++- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/lapi.c b/lapi.c index 73cf1108..9b824577 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 2.142 2010/12/20 18:17:46 roberto Exp roberto $ +** $Id: lapi.c,v 2.143 2010/12/20 19:40:07 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -969,7 +969,6 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { break; } case LUA_GCCOLLECT: { - g->gcrunning = 1; /* restart collector if stopped ?? */ luaC_fullgc(L, 0); break; } @@ -983,22 +982,19 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { break; } case LUA_GCSTEP: { - int running = g->gcrunning; - g->gcrunning = 1; /* allow steps */ if (g->gckind == KGC_GEN) { /* generational mode? */ res = (g->lastmajormem == 0); /* 1 if will do major collection */ - luaC_step(L); /* do a single step */ + luaC_forcestep(L); /* do a single step */ } else { while (data-- >= 0) { - luaC_step(L); + luaC_forcestep(L); if (g->gcstate == GCSpause) { /* end of cycle? */ res = 1; /* signal it */ break; } } } - g->gcrunning = running; /* restore previous state */ break; } case LUA_GCSETPAUSE: { diff --git a/lgc.c b/lgc.c index 933b035b..55101120 100644 --- a/lgc.c +++ b/lgc.c @@ -1,5 +1,5 @@ /* -** $Id: lgc.c,v 2.106 2010/12/20 18:17:46 roberto Exp roberto $ +** $Id: lgc.c,v 2.107 2010/12/20 19:40:07 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -318,8 +318,7 @@ static void remarkupvals (global_State *g) { ** mark root set and reset all gray lists, to start a new ** incremental (or full) collection */ -static void markroot (lua_State *L) { - global_State *g = G(L); +static void markroot (global_State *g) { g->gray = g->grayagain = NULL; g->weak = g->allweak = g->ephemeron = NULL; markobject(g, g->mainthread); @@ -889,7 +888,7 @@ static l_mem singlestep (lua_State *L) { switch (g->gcstate) { case GCSpause: { if (!isgenerational(g)) - markroot(L); /* start a new collection */ + markroot(g); /* start a new collection */ /* in any case, root must be marked */ lua_assert(!iswhite(obj2gco(g->mainthread)) && !iswhite(gcvalue(&g->l_registry))); @@ -986,15 +985,24 @@ static void step (lua_State *L) { } -void luaC_step (lua_State *L) { +/* +** performs a basic GC step even if the collector is stopped +*/ +void luaC_forcestep (lua_State *L) { global_State *g = G(L); - if (g->gcrunning) { - int i; - if (isgenerational(g)) generationalcollection(L); - else step(L); - for (i = 0; i < GCFINALIZENUM && g->tobefnz; i++) - GCTM(L, 1); /* Call a few pending finalizers */ - } + int i; + if (isgenerational(g)) generationalcollection(L); + else step(L); + for (i = 0; i < GCFINALIZENUM && g->tobefnz; i++) + GCTM(L, 1); /* Call a few pending finalizers */ +} + + +/* +** performs a basic GC step only if collector is running +*/ +void luaC_step (lua_State *L) { + if (G(L)->gcrunning) luaC_forcestep(L); } diff --git a/lgc.h b/lgc.h index 8a430294..b0520f36 100644 --- a/lgc.h +++ b/lgc.h @@ -1,5 +1,5 @@ /* -** $Id: lgc.h,v 2.47 2010/12/17 12:02:29 roberto Exp roberto $ +** $Id: lgc.h,v 2.48 2010/12/20 18:17:46 roberto Exp roberto $ ** Garbage Collector ** See Copyright Notice in lua.h */ @@ -128,6 +128,7 @@ LUAI_FUNC void luaC_separateudata (lua_State *L, int all); LUAI_FUNC void luaC_freeallobjects (lua_State *L); LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_forcestep (lua_State *L); LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, -- cgit v1.2.3-55-g6feb