diff options
Diffstat (limited to 'libs/liblua/src/lmem.c')
-rw-r--r-- | libs/liblua/src/lmem.c | 33 |
1 files changed, 17 insertions, 16 deletions
diff --git a/libs/liblua/src/lmem.c b/libs/liblua/src/lmem.c index 9029d588c1..43739bffd1 100644 --- a/libs/liblua/src/lmem.c +++ b/libs/liblua/src/lmem.c @@ -24,12 +24,12 @@ #if defined(EMERGENCYGCTESTS) /* -** First allocation will fail whenever not building initial state. -** (This fail will trigger 'tryagain' and a full GC cycle at every -** allocation.) +** First allocation will fail whenever not building initial state +** and not shrinking a block. (This fail will trigger 'tryagain' and +** a full GC cycle at every allocation.) */ static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { - if (completestate(g) && ns > 0) /* frees never fail */ + if (ttisnil(&g->nilvalue) && ns > os) return NULL; /* fail */ else /* normal allocation */ return (*g->frealloc)(g->ud, block, os, ns); @@ -83,7 +83,7 @@ void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize, if (nelems + 1 <= size) /* does one extra element still fit? */ return block; /* nothing to be done */ if (size >= limit / 2) { /* cannot double it? */ - if (l_unlikely(size >= limit)) /* cannot grow even a little? */ + if (unlikely(size >= limit)) /* cannot grow even a little? */ luaG_runerror(L, "too many %s (limit is %d)", what, limit); size = limit; /* still have at least one free place */ } @@ -138,17 +138,15 @@ void luaM_free_ (lua_State *L, void *block, size_t osize) { /* -** In case of allocation fail, this function will do an emergency -** collection to free some memory and then try the allocation again. -** The GC should not be called while state is not fully built, as the -** collector is not yet fully initialized. Also, it should not be called -** when 'gcstopem' is true, because then the interpreter is in the -** middle of a collection step. +** In case of allocation fail, this function will call the GC to try +** to free some memory and then try the allocation again. +** (It should not be called when shrinking a block, because then the +** interpreter may be in the middle of a collection step.) */ static void *tryagain (lua_State *L, void *block, size_t osize, size_t nsize) { global_State *g = G(L); - if (completestate(g) && !g->gcstopem) { + if (ttisnil(&g->nilvalue)) { /* is state fully build? */ luaC_fullgc(L, 1); /* try to free some memory... */ return (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ } @@ -158,14 +156,17 @@ static void *tryagain (lua_State *L, void *block, /* ** Generic allocation routine. +** If allocation fails while shrinking a block, do not try again; the +** GC shrinks some blocks and it is not reentrant. */ 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)); newblock = firsttry(g, block, osize, nsize); - if (l_unlikely(newblock == NULL && nsize > 0)) { - newblock = tryagain(L, block, osize, nsize); + if (unlikely(newblock == NULL && nsize > 0)) { + if (nsize > osize) /* not shrinking a block? */ + newblock = tryagain(L, block, osize, nsize); if (newblock == NULL) /* still no memory? */ return NULL; /* do not update 'GCdebt' */ } @@ -178,7 +179,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { void *newblock = luaM_realloc_(L, block, osize, nsize); - if (l_unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ + if (unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */ luaM_error(L); return newblock; } @@ -190,7 +191,7 @@ void *luaM_malloc_ (lua_State *L, size_t size, int tag) { else { global_State *g = G(L); void *newblock = firsttry(g, NULL, tag, size); - if (l_unlikely(newblock == NULL)) { + if (unlikely(newblock == NULL)) { newblock = tryagain(L, NULL, tag, size); if (newblock == NULL) luaM_error(L); |