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-d36a31e6739bcd39c84f637344227af87cfd0ee5.tar.gz lua-d36a31e6739bcd39c84f637344227af87cfd0ee5.tar.bz2 lua-d36a31e6739bcd39c84f637344227af87cfd0ee5.zip |
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 @@ | |||
23 | 23 | ||
24 | 24 | ||
25 | #if defined(HARDMEMTESTS) | 25 | #if defined(HARDMEMTESTS) |
26 | #define hardtest(L,os,s) /* force a GC whenever possible */ \ | 26 | /* |
27 | if ((s) > (os) && (G(L))->gcrunning) luaC_fullgc(L, 1); | 27 | ** First allocation will fail whenever not building initial state |
28 | ** and not shrinking a block. (This fail will trigger 'tryagain' and | ||
29 | ** a full GC cycle at every alocation.) | ||
30 | */ | ||
31 | static void *firsttry (global_State *g, void *block, size_t os, size_t ns) { | ||
32 | if (ttisnil(&g->nilvalue) && ns > os) | ||
33 | return NULL; /* fail */ | ||
34 | else /* normal allocation */ | ||
35 | return (*g->frealloc)(g->ud, block, os, ns); | ||
36 | } | ||
28 | #else | 37 | #else |
29 | #define hardtest(L,os,s) ((void)0) | 38 | #define firsttry(g,block,os,ns) ((*g->frealloc)(g->ud, block, os, ns)) |
30 | #endif | 39 | #endif |
31 | 40 | ||
32 | 41 | ||
33 | 42 | ||
43 | |||
44 | |||
34 | /* | 45 | /* |
35 | ** About the realloc function: | 46 | ** About the realloc function: |
36 | ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); | 47 | ** 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) { | |||
138 | void *newblock; | 149 | void *newblock; |
139 | global_State *g = G(L); | 150 | global_State *g = G(L); |
140 | lua_assert((osize == 0) == (block == NULL)); | 151 | lua_assert((osize == 0) == (block == NULL)); |
141 | hardtest(L, osize, nsize); | 152 | newblock = firsttry(g, block, osize, nsize); |
142 | newblock = (*g->frealloc)(g->ud, block, osize, nsize); | ||
143 | if (unlikely(newblock == NULL && nsize > 0)) { | 153 | if (unlikely(newblock == NULL && nsize > 0)) { |
144 | if (nsize > osize) /* not shrinking a block? */ | 154 | if (nsize > osize) /* not shrinking a block? */ |
145 | newblock = tryagain(L, block, osize, nsize); | 155 | newblock = tryagain(L, block, osize, nsize); |
@@ -162,12 +172,11 @@ void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, | |||
162 | 172 | ||
163 | 173 | ||
164 | void *luaM_malloc_ (lua_State *L, size_t size, int tag) { | 174 | void *luaM_malloc_ (lua_State *L, size_t size, int tag) { |
165 | hardtest(L, 0, size); | ||
166 | if (size == 0) | 175 | if (size == 0) |
167 | return NULL; /* that's all */ | 176 | return NULL; /* that's all */ |
168 | else { | 177 | else { |
169 | global_State *g = G(L); | 178 | global_State *g = G(L); |
170 | void *newblock = (*g->frealloc)(g->ud, NULL, tag, size); | 179 | void *newblock = firsttry(g, NULL, tag, size); |
171 | if (unlikely(newblock == NULL)) { | 180 | if (unlikely(newblock == NULL)) { |
172 | newblock = tryagain(L, NULL, tag, size); | 181 | newblock = tryagain(L, NULL, tag, size); |
173 | if (newblock == NULL) | 182 | if (newblock == NULL) |