diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-05-30 11:25:52 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-05-30 11:25:52 -0300 |
commit | 34aa0c5bd7493b6e01983df28f04af46a3d99967 (patch) | |
tree | eb58cf48a015be8b9b9c0b3f8c1da14d39f8a065 /lmem.c | |
parent | 97e394ba1805fbe394a5704de660403901559e54 (diff) | |
download | lua-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.c | 44 |
1 files changed, 27 insertions, 17 deletions
@@ -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 | */ | ||
123 | static 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) { | |||
142 | void *luaM_saferealloc_ (lua_State *L, void *block, size_t osize, | 155 | void *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 | } |