diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-18 14:58:15 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-07-18 14:58:15 -0300 |
commit | d36a31e6739bcd39c84f637344227af87cfd0ee5 (patch) | |
tree | 68b0049215b0b6cf2a8109e24cb154175bf02c4d /lmem.c | |
parent | 024a6071cac749504e0b26a915bda4f52c41a892 (diff) | |
download | lua-github-d36a31e6739bcd39c84f637344227af87cfd0ee5.tar.gz |
Reviving HARDMEMTESTS
This commit brings a new implementation for HARDMEMTESTS, which forces
an emergency GC whenever possible. It also fixes some issues detected
with this option:
- A small bug in lvm.c: a closure could be collected by an emergency
GC while being initialized.
- Some tests: a memory address can be immediatly reused after a GC;
for instance, two consecutive '{}' expressions can return exactly the
same address, if the first one is not anchored.
Diffstat (limited to 'lmem.c')
-rw-r--r-- | lmem.c | 23 |
1 files changed, 16 insertions, 7 deletions
@@ -23,14 +23,25 @@ #if defined(HARDMEMTESTS) -#define hardtest(L,os,s) /* force a GC whenever possible */ \ - if ((s) > (os) && (G(L))->gcrunning) luaC_fullgc(L, 1); +/* +** 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 alocation.) +*/ +static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { + if (ttisnil(&g->nilvalue) && ns > os) + return NULL; /* fail */ + else /* normal allocation */ + return (*g->frealloc)(g->ud, block, os, ns); +} #else -#define hardtest(L,os,s) ((void)0) +#define firsttry(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns)) #endif + + /* ** About the realloc function: ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); @@ -138,8 +149,7 @@ 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)); - hardtest(L, osize, nsize); - newblock = (*g->frealloc)(g->ud, block, osize, nsize); + newblock = firsttry(g, block, osize, nsize); if (unlikely(newblock == NULL && nsize > 0)) { if (nsize > osize) /* not shrinking a block? */ newblock = tryagain(L, block, osize, nsize); @@ -162,12 +172,11 @@ void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, void *luaM_malloc_ (lua_State *L, size_t size, int tag) { - hardtest(L, 0, size); if (size == 0) return NULL; /* that's all */ else { global_State *g = G(L); - void *newblock = (*g->frealloc)(g->ud, NULL, tag, size); + void *newblock = firsttry(g, NULL, tag, size); if (unlikely(newblock == NULL)) { newblock = tryagain(L, NULL, tag, size); if (newblock == NULL) |