change in the relationship between totalbytes and GCdebt - luaM_realloc_

is too critical to update two counters
This commit is contained in:
Roberto Ierusalimschy
2010-12-20 17:40:07 -02:00
parent 737f119187
commit 551b076f1c
5 changed files with 35 additions and 26 deletions

8
lapi.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lapi.c,v 2.141 2010/11/26 14:32:31 roberto Exp roberto $ ** $Id: lapi.c,v 2.142 2010/12/20 18:17:46 roberto Exp roberto $
** Lua API ** Lua API
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -964,7 +964,7 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
break; break;
} }
case LUA_GCRESTART: { case LUA_GCRESTART: {
g->GCdebt = 0; luaE_setdebt(g, 0);
g->gcrunning = 1; g->gcrunning = 1;
break; break;
} }
@@ -975,11 +975,11 @@ LUA_API int lua_gc (lua_State *L, int what, int data) {
} }
case LUA_GCCOUNT: { case LUA_GCCOUNT: {
/* GC values are expressed in Kbytes: #bytes/2^10 */ /* GC values are expressed in Kbytes: #bytes/2^10 */
res = cast_int(g->totalbytes >> 10); res = cast_int(gettotalbytes(g) >> 10);
break; break;
} }
case LUA_GCCOUNTB: { case LUA_GCCOUNTB: {
res = cast_int(g->totalbytes & 0x3ff); res = cast_int(gettotalbytes(g) & 0x3ff);
break; break;
} }
case LUA_GCSTEP: { case LUA_GCSTEP: {

23
lgc.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lgc.c,v 2.105 2010/12/03 11:48:25 roberto Exp roberto $ ** $Id: lgc.c,v 2.106 2010/12/20 18:17:46 roberto Exp roberto $
** Garbage Collector ** Garbage Collector
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -51,7 +51,7 @@
** standard negative debt for GC; a reasonable "time" to wait before ** standard negative debt for GC; a reasonable "time" to wait before
** starting a new cycle ** starting a new cycle
*/ */
#define stddebt(g) (-cast(l_mem, g->totalbytes/100) * g->gcpause) #define stddebt(g) (-cast(l_mem, gettotalbytes(g)/100) * g->gcpause)
/* /*
@@ -634,6 +634,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
int ow = otherwhite(g); int ow = otherwhite(g);
int toclear, toset; /* bits to clear and to set in all live objects */ int toclear, toset; /* bits to clear and to set in all live objects */
int tostop; /* stop sweep when this is true */ int tostop; /* stop sweep when this is true */
l_mem debt = g->GCdebt; /* current debt */
if (isgenerational(g)) { /* generational mode? */ if (isgenerational(g)) { /* generational mode? */
toclear = ~0; /* clear nothing */ toclear = ~0; /* clear nothing */
toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */
@@ -656,13 +657,15 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */
if (testbits(marked, tostop)) { if (testbits(marked, tostop)) {
static GCObject *nullp = NULL; static GCObject *nullp = NULL;
return &nullp; /* stop sweeping this list */ p = &nullp; /* stop sweeping this list */
break;
} }
/* update marks */ /* update marks */
gch(curr)->marked = cast_byte((marked & toclear) | toset); gch(curr)->marked = cast_byte((marked & toclear) | toset);
p = &gch(curr)->next; /* go to next element */ p = &gch(curr)->next; /* go to next element */
} }
} }
luaE_setdebt(g, debt); /* sweeping should not change debt */
return p; return p;
} }
@@ -807,7 +810,7 @@ void luaC_changemode (lua_State *L, int mode) {
if (mode == KGC_GEN) { /* change to generational mode */ if (mode == KGC_GEN) { /* change to generational mode */
/* make sure gray lists are consistent */ /* make sure gray lists are consistent */
luaC_runtilstate(L, bitmask(GCSpropagate)); luaC_runtilstate(L, bitmask(GCSpropagate));
g->lastmajormem = g->totalbytes; g->lastmajormem = gettotalbytes(g);
g->gckind = KGC_GEN; g->gckind = KGC_GEN;
} }
else { /* change to incremental mode */ else { /* change to incremental mode */
@@ -958,15 +961,15 @@ static void generationalcollection (lua_State *L) {
global_State *g = G(L); global_State *g = G(L);
if (g->lastmajormem == 0) { /* signal for another major collection? */ if (g->lastmajormem == 0) { /* signal for another major collection? */
luaC_fullgc(L, 0); /* perform a full regular collection */ luaC_fullgc(L, 0); /* perform a full regular collection */
g->lastmajormem = g->totalbytes; /* update control */ g->lastmajormem = gettotalbytes(g); /* update control */
} }
else { else {
luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */ luaC_runtilstate(L, ~bitmask(GCSpause)); /* run complete cycle */
luaC_runtilstate(L, bitmask(GCSpause)); luaC_runtilstate(L, bitmask(GCSpause));
if (g->totalbytes > g->lastmajormem/100 * g->gcmajorinc) if (gettotalbytes(g) > g->lastmajormem/100 * g->gcmajorinc)
g->lastmajormem = 0; /* signal for a major collection */ g->lastmajormem = 0; /* signal for a major collection */
} }
g->GCdebt = stddebt(g); luaE_setdebt(g, stddebt(g));
} }
@@ -977,9 +980,9 @@ static void step (lua_State *L) {
lim -= singlestep(L); lim -= singlestep(L);
} while (lim > 0 && g->gcstate != GCSpause); } while (lim > 0 && g->gcstate != GCSpause);
if (g->gcstate != GCSpause) if (g->gcstate != GCSpause)
g->GCdebt -= GCSTEPSIZE; luaE_setdebt(g, g->GCdebt - GCSTEPSIZE);
else else
g->GCdebt = stddebt(g); luaE_setdebt(g, stddebt(g));
} }
@@ -1022,7 +1025,7 @@ void luaC_fullgc (lua_State *L, int isemergency) {
luaC_runtilstate(L, bitmask(GCSpropagate)); luaC_runtilstate(L, bitmask(GCSpropagate));
} }
g->gckind = origkind; g->gckind = origkind;
g->GCdebt = stddebt(g); luaE_setdebt(g, stddebt(g));
if (!isemergency) /* do not run finalizers during emergency GC */ if (!isemergency) /* do not run finalizers during emergency GC */
callallpendingfinalizers(L, 1); callallpendingfinalizers(L, 1);
} }

5
lmem.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lmem.c,v 1.79 2010/05/05 18:49:56 roberto Exp roberto $ ** $Id: lmem.c,v 1.80 2010/12/20 18:17:46 roberto Exp roberto $
** Interface to Memory Manager ** Interface to Memory Manager
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -94,8 +94,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
luaD_throw(L, LUA_ERRMEM); luaD_throw(L, LUA_ERRMEM);
} }
lua_assert((nsize == 0) == (newblock == NULL)); lua_assert((nsize == 0) == (newblock == NULL));
g->totalbytes = (g->totalbytes - realosize) + nsize; g->GCdebt = (g->GCdebt + nsize) - realosize;
g->GCdebt += nsize; /* give some credit to garbage collector */
#if defined(TRACEMEM) #if defined(TRACEMEM)
{ /* auxiliary patch to monitor garbage collection. { /* auxiliary patch to monitor garbage collection.
** To plot, gnuplot with following command: ** To plot, gnuplot with following command:

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lstate.c,v 2.87 2010/11/26 14:32:31 roberto Exp roberto $ ** $Id: lstate.c,v 2.88 2010/12/20 18:17:46 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -65,11 +65,14 @@ typedef struct LG {
#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) #define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
/* /*
** maximum number of nested calls made by error-handling function ** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
** invariant
*/ */
#define LUAI_EXTRACALLS 10 void luaE_setdebt (global_State *g, l_mem debt) {
g->totalbytes -= (debt - g->GCdebt);
g->GCdebt = debt;
}
CallInfo *luaE_extendCI (lua_State *L) { CallInfo *luaE_extendCI (lua_State *L) {
@@ -154,7 +157,6 @@ static void f_luaopen (lua_State *L, void *ud) {
/* pre-create memory-error message */ /* pre-create memory-error message */
g->memerrmsg = luaS_newliteral(L, MEMERRMSG); g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
luaS_fix(g->memerrmsg); /* it should never be collected */ luaS_fix(g->memerrmsg); /* it should never be collected */
g->GCdebt = 0;
g->gcrunning = 1; /* allow gc */ g->gcrunning = 1; /* allow gc */
} }
@@ -188,7 +190,7 @@ static void close_state (lua_State *L) {
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
luaZ_freebuffer(L, &g->buff); luaZ_freebuffer(L, &g->buff);
freestack(L); freestack(L);
lua_assert(g->totalbytes == sizeof(LG)); lua_assert(gettotalbytes(g) == sizeof(LG));
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0);
} }
@@ -258,6 +260,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->gray = g->grayagain = NULL; g->gray = g->grayagain = NULL;
g->weak = g->ephemeron = g->allweak = NULL; g->weak = g->ephemeron = g->allweak = NULL;
g->totalbytes = sizeof(LG); g->totalbytes = sizeof(LG);
g->GCdebt = 0;
g->gcpause = LUAI_GCPAUSE; g->gcpause = LUAI_GCPAUSE;
g->gcmajorinc = LUAI_GCMAJOR; g->gcmajorinc = LUAI_GCMAJOR;
g->gcstepmul = LUAI_GCMUL; g->gcstepmul = LUAI_GCMUL;

View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lstate.h,v 2.69 2010/11/26 14:32:31 roberto Exp roberto $ ** $Id: lstate.h,v 2.70 2010/12/20 18:17:46 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -114,8 +114,8 @@ typedef struct CallInfo {
typedef struct global_State { typedef struct global_State {
lua_Alloc frealloc; /* function to reallocate memory */ lua_Alloc frealloc; /* function to reallocate memory */
void *ud; /* auxiliary data to `frealloc' */ void *ud; /* auxiliary data to `frealloc' */
lu_mem totalbytes; /* number of bytes currently allocated */ lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */
l_mem GCdebt; /* when positive, run a GC step */ l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
lu_mem lastmajormem; /* memory in use after last major collection */ lu_mem lastmajormem; /* memory in use after last major collection */
stringtable strt; /* hash table for strings */ stringtable strt; /* hash table for strings */
TValue l_registry; TValue l_registry;
@@ -210,6 +210,10 @@ union GCObject {
#define obj2gco(v) (cast(GCObject *, (v))) #define obj2gco(v) (cast(GCObject *, (v)))
/* actual number of total bytes allocated */
#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt)
LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
LUAI_FUNC void luaE_freeCI (lua_State *L); LUAI_FUNC void luaE_freeCI (lua_State *L);