1
0
mirror of https://github.com/lua/lua.git synced 2025-01-28 06:03:00 +08:00

limit to 'gcstepmul' imposed by 'lua_gc' (+ some details in 'lgc.c')

This commit is contained in:
Roberto Ierusalimschy 2014-02-13 15:25:20 -02:00
parent de3b1c9b53
commit 90b0ac6495
2 changed files with 21 additions and 13 deletions

3
lapi.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lapi.c,v 2.193 2014/01/27 13:34:32 roberto Exp roberto $ ** $Id: lapi.c,v 2.194 2014/02/13 12:11:34 roberto Exp roberto $
** Lua API ** Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -1086,6 +1086,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
} }
case LUA_GCSETSTEPMUL: { case LUA_GCSETSTEPMUL: {
res = g->gcstepmul; res = g->gcstepmul;
if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */
g->gcstepmul = data; g->gcstepmul = data;
break; break;
} }

31
lgc.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lgc.c,v 2.171 2014/02/13 12:11:34 roberto Exp roberto $ ** $Id: lgc.c,v 2.172 2014/02/13 14:46:38 roberto Exp roberto $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -1060,9 +1060,9 @@ void luaC_runtilstate (lua_State *L, int statesmask) {
/* /*
** run a few finalizers ** run a few (up to 'g->gcfinnum') finalizers
*/ */
static int dosomefinalization (lua_State *L) { static int runafewfinalizers (lua_State *L) {
global_State *g = G(L); global_State *g = G(L);
unsigned int i; unsigned int i;
lua_assert(!g->tobefnz || g->gcfinnum > 0); lua_assert(!g->tobefnz || g->gcfinnum > 0);
@ -1074,20 +1074,27 @@ static int dosomefinalization (lua_State *L) {
} }
/*
** get GC debt and convert it from Kb to 'work units' (avoid zero debt
** and overflows)
*/
static l_mem getdebt (global_State *g) {
l_mem debt = g->GCdebt;
int stepmul = g->gcstepmul;
debt = (debt / STEPMULADJ) + 1;
debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
return debt;
}
/* /*
** performs a basic GC step ** performs a basic GC step
*/ */
void luaC_forcestep (lua_State *L) { void luaC_forcestep (lua_State *L) {
global_State *g = G(L); global_State *g = G(L);
l_mem debt = g->GCdebt; l_mem debt = getdebt(g);
int stepmul = g->gcstepmul;
if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */
/* convert debt from Kb to 'work units' (avoid zero debt and overflows) */
debt = (debt / STEPMULADJ) + 1;
debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
do { do {
if (g->gcstate == GCScallfin && g->tobefnz) { if (g->gcstate == GCScallfin && g->tobefnz) {
unsigned int n = dosomefinalization(L); unsigned int n = runafewfinalizers(L);
debt -= (n * GCFINALIZECOST); debt -= (n * GCFINALIZECOST);
} }
else { /* perform one single step */ else { /* perform one single step */
@ -1098,9 +1105,9 @@ void luaC_forcestep (lua_State *L) {
if (g->gcstate == GCSpause) if (g->gcstate == GCSpause)
setpause(g, g->GCestimate); /* pause until next cycle */ setpause(g, g->GCestimate); /* pause until next cycle */
else { else {
debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ debt = (debt / g->gcstepmul) * STEPMULADJ; /* convert 'work units' to Kb */
luaE_setdebt(g, debt); luaE_setdebt(g, debt);
dosomefinalization(L); runafewfinalizers(L);
} }
} }