summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-06-15 11:58:59 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-06-15 11:58:59 -0300
commitd49b2887282b86a5e6f40a386511aa8040f3c7b0 (patch)
tree0d85ba5e27fb06723b3f49f4c10cb9e2e717d2ae
parent69e84805e48b0253007bd0daf481ce7955367d73 (diff)
downloadlua-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.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/lstate.c b/lstate.c
index 42a48436..d2e924d5 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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*/
191void luaE_shrinkCI (lua_State *L) { 192void 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}