diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-09-21 10:31:03 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-10-12 12:29:09 -0300 |
commit | 5d8ce05b3f6fad79e37ed21c1076e47a322472c6 (patch) | |
tree | 7629a59887da63d44267e872bc8e33be6db36582 /lstate.c | |
parent | f83de8e34e24e30acf277f60de62a33bd51d1ddd (diff) | |
download | lua-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.c | 43 |
1 files changed, 2 insertions, 41 deletions
@@ -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 | |||
135 | void 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 | |||
156 | CallInfo *luaE_extendCI (lua_State *L) { | 122 | CallInfo *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; |