new way to control GC speed

This commit is contained in:
Roberto Ierusalimschy
2010-04-29 14:35:10 -03:00
parent 5a7a0c72d8
commit 3410dcd375
2 changed files with 26 additions and 16 deletions

11
lmem.c
View File

@@ -1,5 +1,5 @@
/* /*
** $Id: lmem.c,v 1.74 2009/12/16 16:42:58 roberto Exp roberto $ ** $Id: lmem.c,v 1.75 2010/04/02 14:37:41 roberto Exp roberto $
** Interface to Memory Manager ** Interface to Memory Manager
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -79,13 +79,14 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
size_t realosize = (block) ? osize : 0; size_t realosize = (block) ? osize : 0;
lua_assert((realosize == 0) == (block == NULL)); lua_assert((realosize == 0) == (block == NULL));
#if defined(HARDMEMTESTS) #if defined(HARDMEMTESTS)
if (nsize > realosize && g->GCthreshold != MAX_LUMEM) if (nsize > realosize && !gcstopped(g))
luaC_fullgc(L, 1); /* force a GC whenever possible */ luaC_fullgc(L, 1); /* force a GC whenever possible */
#endif #endif
newblock = (*g->frealloc)(g->ud, block, osize, nsize); newblock = (*g->frealloc)(g->ud, block, osize, nsize);
if (newblock == NULL && nsize > 0) { if (newblock == NULL && nsize > 0) {
lua_assert(nsize > realosize); /* cannot fail when shrinking a block */ api_check(L, nsize > realosize,
if (g->GCthreshold != MAX_LUMEM) { "realloc cannot fail when shrinking a block");
if (!gcstopped(g)) {
luaC_fullgc(L, 1); /* try to free some memory... */ luaC_fullgc(L, 1); /* try to free some memory... */
newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
} }
@@ -94,6 +95,8 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
} }
lua_assert((nsize == 0) == (newblock == NULL)); lua_assert((nsize == 0) == (newblock == NULL));
g->totalbytes = (g->totalbytes - realosize) + nsize; g->totalbytes = (g->totalbytes - realosize) + nsize;
if (!gcstopped(g)) /* new object? */
g->GCdebt += nsize; /* give some credit to garbage collector */
#if defined(TRACEMEM) #if defined(TRACEMEM)
{ /* auxiliar patch to monitor garbage collection. { /* auxiliar 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.81 2010/04/19 16:34:46 roberto Exp roberto $ ** $Id: lstate.c,v 2.82 2010/04/19 17:40:13 roberto Exp roberto $
** Global State ** Global State
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@@ -90,7 +90,7 @@ void luaE_freeCI (lua_State *L) {
static void stack_init (lua_State *L1, lua_State *L) { static void stack_init (lua_State *L1, lua_State *L) {
int i; int i; CallInfo *ci;
/* initialize stack array */ /* initialize stack array */
L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
L1->stacksize = BASIC_STACK_SIZE; L1->stacksize = BASIC_STACK_SIZE;
@@ -99,17 +99,22 @@ static void stack_init (lua_State *L1, lua_State *L) {
L1->top = L1->stack; L1->top = L1->stack;
L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
/* initialize first ci */ /* initialize first ci */
L1->ci->func = L1->top; ci = &L1->base_ci;
ci->next = ci->previous = NULL;
ci->callstatus = 0;
ci->func = L1->top;
setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
L1->ci->top = L1->top + LUA_MINSTACK; ci->top = L1->top + LUA_MINSTACK;
L1->ci->callstatus = 0; L1->ci = ci;
} }
static void freestack (lua_State *L) { static void freestack (lua_State *L) {
L->ci = &L->base_ci; /* reset 'ci' list */ if (L->ci != NULL) { /* is there a 'ci' list? */
luaE_freeCI(L); L->ci = &L->base_ci; /* free the entire list */
luaM_freearray(L, L->stack, L->stacksize); luaE_freeCI(L);
}
luaM_freearray(L, L->stack, L->stacksize); /* free stack array */
} }
@@ -145,7 +150,7 @@ 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->GCthreshold = 4*g->totalbytes; g->GCdebt = 0;
} }
@@ -156,6 +161,7 @@ static void f_luaopen (lua_State *L, void *ud) {
static void preinit_state (lua_State *L, global_State *g) { static void preinit_state (lua_State *L, global_State *g) {
G(L) = g; G(L) = g;
L->stack = NULL; L->stack = NULL;
L->ci = NULL;
L->stacksize = 0; L->stacksize = 0;
L->errorJmp = NULL; L->errorJmp = NULL;
L->hook = NULL; L->hook = NULL;
@@ -166,8 +172,6 @@ static void preinit_state (lua_State *L, global_State *g) {
L->openupval = NULL; L->openupval = NULL;
L->nny = 1; L->nny = 1;
L->status = LUA_OK; L->status = LUA_OK;
L->base_ci.next = L->base_ci.previous = NULL;
L->ci = &L->base_ci;
L->errfunc = 0; L->errfunc = 0;
} }
@@ -233,7 +237,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->mainthread = L; g->mainthread = L;
g->uvhead.u.l.prev = &g->uvhead; g->uvhead.u.l.prev = &g->uvhead;
g->uvhead.u.l.next = &g->uvhead; g->uvhead.u.l.next = &g->uvhead;
g->GCthreshold = MAX_LUMEM; /* no GC while building state */ stopgc(g); /* no GC while building state */
g->lastmajormem = 0; g->lastmajormem = 0;
g->strt.size = 0; g->strt.size = 0;
g->strt.nuse = 0; g->strt.nuse = 0;
@@ -246,6 +250,9 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
g->allgc = NULL; g->allgc = NULL;
g->udgc = NULL; g->udgc = NULL;
g->tobefnz = NULL; g->tobefnz = NULL;
g->gray = NULL;
g->grayagain = NULL;
g->weak = g->ephemeron = g->allweak = NULL;
g->totalbytes = sizeof(LG); g->totalbytes = sizeof(LG);
g->gcpause = LUAI_GCPAUSE; g->gcpause = LUAI_GCPAUSE;
g->gcstepmul = LUAI_GCMUL; g->gcstepmul = LUAI_GCMUL;