diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2006-07-11 12:53:29 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2006-07-11 12:53:29 -0300 |
commit | 3ca9af51a4f060cf2178901a67a21f8269af3224 (patch) | |
tree | 4f1bb541280aa8b4960b16d0925eca60adb2b1a8 /lmem.c | |
parent | c7b89dd28097296bbc14d9b47b4cea72514b2b76 (diff) | |
download | lua-github-3ca9af51a4f060cf2178901a67a21f8269af3224.tar.gz |
emergency garbage collector (core forces a GC when allocation fails)
Diffstat (limited to 'lmem.c')
-rw-r--r-- | lmem.c | 25 |
1 files changed, 19 insertions, 6 deletions
@@ -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; } |