simpler macro 'luaC_condGC' + better 'step' in 'lua_gc' +

micro bug in 'luaC_checkfinalizer' (current sweep object could be
removed from 'allgc' list)
This commit is contained in:
Roberto Ierusalimschy 2012-05-21 10:18:10 -03:00
parent 2a66b34f72
commit 398811a313
3 changed files with 35 additions and 17 deletions

18
lapi.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lapi.c,v 2.159 2011/11/30 12:32:05 roberto Exp roberto $
** $Id: lapi.c,v 2.160 2012/05/11 19:22:33 roberto Exp roberto $
** Lua API
** See Copyright Notice in lua.h
*/
@ -1046,16 +1046,16 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
case LUA_GCSTEP: {
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);
if (g->gcstate == GCSpause) { /* end of cycle? */
res = 1; /* signal it */
break;
}
}
lu_mem debt = cast(lu_mem, data) * 1024; /* count in Kbytes */
if (g->gcrunning)
debt += g->GCdebt; /* include current debt */
luaE_setdebt(g, debt);
luaC_forcestep(L);
if (g->gcstate == GCSpause) /* end of cycle? */
res = 1; /* signal it */
}
break;
}

30
lgc.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lgc.c,v 2.122 2012/05/14 17:52:56 roberto Exp roberto $
** $Id: lgc.c,v 2.123 2012/05/20 20:36:44 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@ -863,11 +863,18 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
return; /* nothing to be done */
else { /* move 'o' to 'finobj' list */
GCObject **p;
for (p = &g->allgc; *p != o; p = &gch(*p)->next) ;
*p = gch(o)->next; /* remove 'o' from root list */
gch(o)->next = g->finobj; /* link it in list 'finobj' */
GCheader *ho = gch(o);
/* avoid removing current sweep object */
if (g->gcstate == GCSsweep && g->sweepgc == &ho->next) {
/* step to next object in the list */
g->sweepgc = (ho->next == NULL) ? NULL : &gch(ho->next)->next;
}
/* search for pointer pointing to 'o' */
for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }
*p = ho->next; /* remove 'o' from root list */
ho->next = g->finobj; /* link it in list 'finobj' */
g->finobj = o;
l_setbit(gch(o)->marked, SEPARATED); /* mark it as such */
l_setbit(ho->marked, SEPARATED); /* mark it as such */
resetoldbit(o); /* see MOVE OLD rule */
}
}
@ -1085,7 +1092,7 @@ static void step (lua_State *L) {
/*
** performs a basic GC step
*/
void luaC_step (lua_State *L) {
void luaC_forcestep (lua_State *L) {
global_State *g = G(L);
int i;
if (isgenerational(g)) generationalcollection(L);
@ -1096,6 +1103,17 @@ void luaC_step (lua_State *L) {
}
/*
** performs a basic GC step only if collector is running
*/
void luaC_step (lua_State *L) {
global_State *g = G(L);
if (g->gcrunning) luaC_forcestep(L);
else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */
}
/*
** performs a full GC cycle; if "isemergency", does not call
** finalizers (which could change stack positions)

4
lgc.h
View File

@ -1,5 +1,5 @@
/*
** $Id: lgc.h,v 2.53 2012/01/23 20:29:12 roberto Exp roberto $
** $Id: lgc.h,v 2.54 2012/05/11 19:22:33 roberto Exp roberto $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@ -104,7 +104,7 @@
#define luaC_condGC(L,c) \
{if (G(L)->GCdebt > 0 && G(L)->gcrunning) {c;}; condchangemem(L);}
{if (G(L)->GCdebt > 0) {c;}; condchangemem(L);}
#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);)