aboutsummaryrefslogtreecommitdiff
path: root/lstate.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-09-21 10:31:03 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2020-10-12 12:29:09 -0300
commit5d8ce05b3f6fad79e37ed21c1076e47a322472c6 (patch)
tree7629a59887da63d44267e872bc8e33be6db36582 /lstate.c
parentf83de8e34e24e30acf277f60de62a33bd51d1ddd (diff)
downloadlua-5d8ce05b3f6fad79e37ed21c1076e47a322472c6.tar.gz
lua-5d8ce05b3f6fad79e37ed21c1076e47a322472c6.tar.bz2
lua-5d8ce05b3f6fad79e37ed21c1076e47a322472c6.zip
Back to a stackless implementation
A "with stack" implementation gains too little in performance to be worth all the noise from C-stack overflows. This commit is almost a sketch, to test performance. There are several pending stuff: - review control of C-stack overflow and error messages; - what to do with setcstacklimit; - review comments; - review unroll of Lua calls.
Diffstat (limited to 'lstate.c')
-rw-r--r--lstate.c43
1 files changed, 2 insertions, 41 deletions
diff --git a/lstate.c b/lstate.c
index 86b3761f..8cda3072 100644
--- a/lstate.c
+++ b/lstate.c
@@ -119,44 +119,9 @@ LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) {
119} 119}
120 120
121 121
122/*
123** Decrement count of "C calls" and check for overflows. In case of
124** a stack overflow, check appropriate error ("regular" overflow or
125** overflow while handling stack overflow). If 'nCcalls' is smaller
126** than CSTACKERR but larger than CSTACKMARK, it means it has just
127** entered the "overflow zone", so the function raises an overflow
128** error. If 'nCcalls' is smaller than CSTACKMARK (which means it is
129** already handling an overflow) but larger than CSTACKERRMARK, does
130** not report an error (to allow message handling to work). Otherwise,
131** report a stack overflow while handling a stack overflow (probably
132** caused by a repeating error in the message handling function).
133*/
134
135void luaE_enterCcall (lua_State *L) {
136 int ncalls = getCcalls(L);
137 L->nCcalls--;
138 if (ncalls <= CSTACKERR) { /* possible overflow? */
139 luaE_freeCI(L); /* release unused CIs */
140 ncalls = getCcalls(L); /* update call count */
141 if (ncalls <= CSTACKERR) { /* still overflow? */
142 if (ncalls <= CSTACKERRMARK) /* below error-handling zone? */
143 luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
144 else if (ncalls >= CSTACKMARK) {
145 /* not in error-handling zone; raise the error now */
146 L->nCcalls = (CSTACKMARK - 1); /* enter error-handling zone */
147 luaG_runerror(L, "C stack overflow");
148 }
149 /* else stack is in the error-handling zone;
150 allow message handler to work */
151 }
152 }
153}
154
155
156CallInfo *luaE_extendCI (lua_State *L) { 122CallInfo *luaE_extendCI (lua_State *L) {
157 CallInfo *ci; 123 CallInfo *ci;
158 lua_assert(L->ci->next == NULL); 124 lua_assert(L->ci->next == NULL);
159 luaE_enterCcall(L);
160 ci = luaM_new(L, CallInfo); 125 ci = luaM_new(L, CallInfo);
161 lua_assert(L->ci->next == NULL); 126 lua_assert(L->ci->next == NULL);
162 L->ci->next = ci; 127 L->ci->next = ci;
@@ -175,13 +140,11 @@ void luaE_freeCI (lua_State *L) {
175 CallInfo *ci = L->ci; 140 CallInfo *ci = L->ci;
176 CallInfo *next = ci->next; 141 CallInfo *next = ci->next;
177 ci->next = NULL; 142 ci->next = NULL;
178 L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */
179 while ((ci = next) != NULL) { 143 while ((ci = next) != NULL) {
180 next = ci->next; 144 next = ci->next;
181 luaM_free(L, ci); 145 luaM_free(L, ci);
182 L->nci--; 146 L->nci--;
183 } 147 }
184 L->nCcalls -= L->nci; /* adjust result */
185} 148}
186 149
187 150
@@ -194,7 +157,6 @@ void luaE_shrinkCI (lua_State *L) {
194 CallInfo *next; 157 CallInfo *next;
195 if (ci == NULL) 158 if (ci == NULL)
196 return; /* no extra elements */ 159 return; /* no extra elements */
197 L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */
198 while ((next = ci->next) != NULL) { /* two extra elements? */ 160 while ((next = ci->next) != NULL) { /* two extra elements? */
199 CallInfo *next2 = next->next; /* next's next */ 161 CallInfo *next2 = next->next; /* next's next */
200 ci->next = next2; /* remove next from the list */ 162 ci->next = next2; /* remove next from the list */
@@ -207,7 +169,6 @@ void luaE_shrinkCI (lua_State *L) {
207 ci = next2; /* continue */ 169 ci = next2; /* continue */
208 } 170 }
209 } 171 }
210 L->nCcalls -= L->nci; /* adjust result */
211} 172}
212 173
213 174
@@ -335,7 +296,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) {
335 setthvalue2s(L, L->top, L1); 296 setthvalue2s(L, L->top, L1);
336 api_incr_top(L); 297 api_incr_top(L);
337 preinit_thread(L1, g); 298 preinit_thread(L1, g);
338 L1->nCcalls = getCcalls(L); 299 L1->nCcalls = 0;
339 L1->hookmask = L->hookmask; 300 L1->hookmask = L->hookmask;
340 L1->basehookcount = L->basehookcount; 301 L1->basehookcount = L->basehookcount;
341 L1->hook = L->hook; 302 L1->hook = L->hook;
@@ -396,7 +357,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
396 preinit_thread(L, g); 357 preinit_thread(L, g);
397 g->allgc = obj2gco(L); /* by now, only object is the main thread */ 358 g->allgc = obj2gco(L); /* by now, only object is the main thread */
398 L->next = NULL; 359 L->next = NULL;
399 g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR; 360 g->Cstacklimit = L->nCcalls = 0;
400 incnny(L); /* main thread is always non yieldable */ 361 incnny(L); /* main thread is always non yieldable */
401 g->frealloc = f; 362 g->frealloc = f;
402 g->ud = ud; 363 g->ud = ud;