summaryrefslogtreecommitdiff
path: root/lmem.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-18 14:58:15 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-18 14:58:15 -0300
commitd36a31e6739bcd39c84f637344227af87cfd0ee5 (patch)
tree68b0049215b0b6cf2a8109e24cb154175bf02c4d /lmem.c
parent024a6071cac749504e0b26a915bda4f52c41a892 (diff)
downloadlua-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.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/lmem.c b/lmem.c
index 53f8dcb9..0186a86b 100644
--- a/lmem.c
+++ b/lmem.c
@@ -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)