aboutsummaryrefslogtreecommitdiff
path: root/lmem.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-05-30 11:25:52 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-05-30 11:25:52 -0300
commit34aa0c5bd7493b6e01983df28f04af46a3d99967 (patch)
treeeb58cf48a015be8b9b9c0b3f8c1da14d39f8a065 /lmem.c
parent97e394ba1805fbe394a5704de660403901559e54 (diff)
downloadlua-34aa0c5bd7493b6e01983df28f04af46a3d99967.tar.gz
lua-34aa0c5bd7493b6e01983df28f04af46a3d99967.tar.bz2
lua-34aa0c5bd7493b6e01983df28f04af46a3d99967.zip
new macros 'likely'/'unlikely' with hints for jump predictions
(used only in errors for now)
Diffstat (limited to 'lmem.c')
-rw-r--r--lmem.c44
1 files changed, 27 insertions, 17 deletions
diff --git a/lmem.c b/lmem.c
index 2c1757f5..5c73acd5 100644
--- a/lmem.c
+++ b/lmem.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lmem.c,v 1.95 2017/12/11 12:27:48 roberto Exp roberto $ 2** $Id: lmem.c,v 1.96 2018/01/28 15:13:26 roberto Exp roberto $
3** Interface to Memory Manager 3** Interface to Memory Manager
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -60,7 +60,7 @@ void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize,
60 if (nelems + 1 <= size) /* does one extra element still fit? */ 60 if (nelems + 1 <= size) /* does one extra element still fit? */
61 return block; /* nothing to be done */ 61 return block; /* nothing to be done */
62 if (size >= limit / 2) { /* cannot double it? */ 62 if (size >= limit / 2) { /* cannot double it? */
63 if (size >= limit) /* cannot grow even a little? */ 63 if (unlikely(size >= limit)) /* cannot grow even a little? */
64 luaG_runerror(L, "too many %s (limit is %d)", what, limit); 64 luaG_runerror(L, "too many %s (limit is %d)", what, limit);
65 size = limit; /* still have at least one free place */ 65 size = limit; /* still have at least one free place */
66 } 66 }
@@ -73,7 +73,7 @@ void *luaM_growaux_ (lua_State *L, void *block, int nelems, int *psize,
73 /* 'limit' ensures that multiplication will not overflow */ 73 /* 'limit' ensures that multiplication will not overflow */
74 newblock = luaM_realloc_(L, block, cast_sizet(*psize) * size_elems, 74 newblock = luaM_realloc_(L, block, cast_sizet(*psize) * size_elems,
75 cast_sizet(size) * size_elems); 75 cast_sizet(size) * size_elems);
76 if (newblock == NULL) 76 if (unlikely(newblock == NULL))
77 luaM_error(L); 77 luaM_error(L);
78 *psize = size; /* update only when everything else is OK */ 78 *psize = size; /* update only when everything else is OK */
79 return newblock; 79 return newblock;
@@ -88,7 +88,7 @@ void *luaM_shrinkvector_ (lua_State *L, void *block, int *size,
88 size_t newsize = cast_sizet(final_n * size_elem); 88 size_t newsize = cast_sizet(final_n * size_elem);
89 lua_assert(newsize <= oldsize); 89 lua_assert(newsize <= oldsize);
90 newblock = (*g->frealloc)(g->ud, block, oldsize, newsize); 90 newblock = (*g->frealloc)(g->ud, block, oldsize, newsize);
91 if (newblock == NULL && final_n > 0) /* allocation failed? */ 91 if (unlikely(newblock == NULL && final_n > 0)) /* allocation failed? */
92 luaM_error(L); 92 luaM_error(L);
93 else { 93 else {
94 g->GCdebt += newsize - oldsize; 94 g->GCdebt += newsize - oldsize;
@@ -114,6 +114,22 @@ void luaM_free_ (lua_State *L, void *block, size_t osize) {
114} 114}
115 115
116 116
117/*
118** In case of allocation fail, this function will call the GC to try
119** to free some memory and then try the allocation again.
120** (It should not be called when shrinking a block, because then the
121** interpreter may be in the middle of a collection step.)
122*/
123static void *tryagain (lua_State *L, void *block,
124 size_t osize, size_t nsize) {
125 global_State *g = G(L);
126 if (g->version) { /* is state fully build? */
127 luaC_fullgc(L, 1); /* try to free some memory... */
128 return (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
129 }
130 else return NULL; /* cannot free any memory without a full state */
131}
132
117 133
118/* 134/*
119** generic allocation routine. 135** generic allocation routine.
@@ -124,13 +140,10 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
124 lua_assert((osize == 0) == (block == NULL)); 140 lua_assert((osize == 0) == (block == NULL));
125 hardtest(L, osize, nsize); 141 hardtest(L, osize, nsize);
126 newblock = (*g->frealloc)(g->ud, block, osize, nsize); 142 newblock = (*g->frealloc)(g->ud, block, osize, nsize);
127 if (newblock == NULL && nsize > 0) { 143 if (unlikely(newblock == NULL && nsize > 0)) {
128 /* Is state fully built? Not shrinking a block? */ 144 if (nsize > osize) /* not shrinking a block? */
129 if (g->version && nsize > osize) { 145 newblock = tryagain(L, block, osize, nsize);
130 luaC_fullgc(L, 1); /* try to free some memory... */ 146 if (newblock == NULL) /* still no memory? */
131 newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */
132 }
133 if (newblock == NULL)
134 return NULL; 147 return NULL;
135 } 148 }
136 lua_assert((nsize == 0) == (newblock == NULL)); 149 lua_assert((nsize == 0) == (newblock == NULL));
@@ -142,7 +155,7 @@ void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) {
142void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, 155void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize,
143 size_t nsize) { 156 size_t nsize) {
144 void *newblock = luaM_realloc_(L, block, osize, nsize); 157 void *newblock = luaM_realloc_(L, block, osize, nsize);
145 if (newblock == NULL && nsize > 0) /* allocation failed? */ 158 if (unlikely(newblock == NULL && nsize > 0)) /* allocation failed? */
146 luaM_error(L); 159 luaM_error(L);
147 return newblock; 160 return newblock;
148} 161}
@@ -155,11 +168,8 @@ void *luaM_malloc_ (lua_State *L, size_t size, int tag) {
155 else { 168 else {
156 global_State *g = G(L); 169 global_State *g = G(L);
157 void *newblock = (*g->frealloc)(g->ud, NULL, tag, size); 170 void *newblock = (*g->frealloc)(g->ud, NULL, tag, size);
158 if (newblock == NULL) { 171 if (unlikely(newblock == NULL)) {
159 if (g->version) { /* is state fully built? */ 172 newblock = tryagain(L, NULL, tag, size);
160 luaC_fullgc(L, 1); /* try to free some memory... */
161 newblock = (*g->frealloc)(g->ud, NULL, tag, size); /* try again */
162 }
163 if (newblock == NULL) 173 if (newblock == NULL)
164 luaM_error(L); 174 luaM_error(L);
165 } 175 }