summaryrefslogtreecommitdiff
path: root/lmem.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2006-07-11 12:53:29 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2006-07-11 12:53:29 -0300
commit3ca9af51a4f060cf2178901a67a21f8269af3224 (patch)
tree4f1bb541280aa8b4960b16d0925eca60adb2b1a8 /lmem.c
parentc7b89dd28097296bbc14d9b47b4cea72514b2b76 (diff)
downloadlua-github-3ca9af51a4f060cf2178901a67a21f8269af3224.tar.gz
emergency garbage collector (core forces a GC when allocation fails)
Diffstat (limited to 'lmem.c')
-rw-r--r--lmem.c25
1 files changed, 19 insertions, 6 deletions
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;
}