From 3ca9af51a4f060cf2178901a67a21f8269af3224 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 11 Jul 2006 12:53:29 -0300 Subject: emergency garbage collector (core forces a GC when allocation fails) --- lmem.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'lmem.c') diff --git a/lmem.c b/lmem.c index 1a3e25c4..fb383d3e 100644 --- a/lmem.c +++ b/lmem.c @@ -1,5 +1,5 @@ /* -** $Id: lmem.c,v 1.69 2005/02/23 17:30:22 roberto Exp roberto $ +** $Id: lmem.c,v 1.70 2005/12/26 13:35:47 roberto Exp roberto $ ** Interface to Memory Manager ** See Copyright Notice in lua.h */ @@ -14,6 +14,7 @@ #include "ldebug.h" #include "ldo.h" +#include "lgc.h" #include "lmem.h" #include "lobject.h" #include "lstate.h" @@ -74,13 +75,25 @@ void *luaM_toobig (lua_State *L) { ** generic allocation routine. */ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { + void *newblock; global_State *g = G(L); lua_assert((osize == 0) == (block == NULL)); - block = (*g->frealloc)(g->ud, block, osize, nsize); - if (block == NULL && nsize > 0) - luaD_throw(L, LUA_ERRMEM); - lua_assert((nsize == 0) == (block == NULL)); +#if defined(HARDMEMTESTS) + if (nsize > osize && g->GCthreshold != MAX_LUMEM) + luaC_fullgc(L, 1); /* force a GC whenever possible */ +#endif + newblock = (*g->frealloc)(g->ud, block, osize, nsize); + if (newblock == NULL && nsize > 0) { + lua_assert(nsize > osize); /* cannot fail when shrinking a block */ + if (g->GCthreshold != MAX_LUMEM) { + luaC_fullgc(L, 1); /* try to free some memory... */ + newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ + } + if (newblock == NULL) + luaD_throw(L, LUA_ERRMEM); + } + lua_assert((nsize == 0) == (newblock == NULL)); g->totalbytes = (g->totalbytes - osize) + nsize; - return block; + return newblock; } -- cgit v1.2.3-55-g6feb