diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-06-15 11:58:59 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-06-15 11:58:59 -0300 |
commit | d49b2887282b86a5e6f40a386511aa8040f3c7b0 (patch) | |
tree | 0d85ba5e27fb06723b3f49f4c10cb9e2e717d2ae | |
parent | 69e84805e48b0253007bd0daf481ce7955367d73 (diff) | |
download | lua-d49b2887282b86a5e6f40a386511aa8040f3c7b0.tar.gz lua-d49b2887282b86a5e6f40a386511aa8040f3c7b0.tar.bz2 lua-d49b2887282b86a5e6f40a386511aa8040f3c7b0.zip |
'luaE_shrinkCI' shouldn't remove first free CallInfo
Due to emergency collections, 'luaE_shrinkCI' can be called while Lua
is building a new CallInfo, which for a while is still a free CallInfo.
-rw-r--r-- | lstate.c | 22 |
1 files changed, 14 insertions, 8 deletions
@@ -186,20 +186,26 @@ void luaE_freeCI (lua_State *L) { | |||
186 | 186 | ||
187 | 187 | ||
188 | /* | 188 | /* |
189 | ** free half of the CallInfo structures not in use by a thread | 189 | ** free half of the CallInfo structures not in use by a thread, |
190 | ** keeping the first one. | ||
190 | */ | 191 | */ |
191 | void luaE_shrinkCI (lua_State *L) { | 192 | void luaE_shrinkCI (lua_State *L) { |
192 | CallInfo *ci = L->ci; | 193 | CallInfo *ci = L->ci->next; /* first free CallInfo */ |
193 | CallInfo *next; | 194 | CallInfo *next; |
194 | CallInfo *next2; /* next's next */ | 195 | if (ci == NULL) |
196 | return; /* no extra elements */ | ||
195 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ | 197 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ |
196 | /* while there are two nexts */ | 198 | while ((next = ci->next) != NULL) { /* two extra elements? */ |
197 | while ((next = ci->next) != NULL && (next2 = next->next) != NULL) { | 199 | CallInfo *next2 = next->next; /* next's next */ |
198 | ci->next = next2; /* remove next from the list */ | 200 | ci->next = next2; /* remove next from the list */ |
199 | next2->previous = ci; | ||
200 | luaM_free(L, next); /* free next */ | ||
201 | L->nci--; | 201 | L->nci--; |
202 | ci = next2; /* keep next's next */ | 202 | luaM_free(L, next); /* free next */ |
203 | if (next2 == NULL) | ||
204 | break; /* no more elements */ | ||
205 | else { | ||
206 | next2->previous = ci; | ||
207 | ci = next2; /* continue */ | ||
208 | } | ||
203 | } | 209 | } |
204 | L->nCcalls -= L->nci; /* adjust result */ | 210 | L->nCcalls -= L->nci; /* adjust result */ |
205 | } | 211 | } |