diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-10-21 16:40:47 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-10-21 16:40:47 -0200 |
commit | 5bdee4f81057698cf7da2bb5da814984170abf8c (patch) | |
tree | 254f8575ed2b1bc4973887caab35404cc7d0cd44 | |
parent | 48098c42ff69154811f234c1446b4fcbf2f15e94 (diff) | |
download | lua-5bdee4f81057698cf7da2bb5da814984170abf8c.tar.gz lua-5bdee4f81057698cf7da2bb5da814984170abf8c.tar.bz2 lua-5bdee4f81057698cf7da2bb5da814984170abf8c.zip |
small changes to allow 'precall' to spend time preserving 'func'
only when needed (that is, when stack actually changes)
-rw-r--r-- | ldo.c | 40 | ||||
-rw-r--r-- | ldo.h | 17 | ||||
-rw-r--r-- | llimits.h | 13 |
3 files changed, 42 insertions, 28 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 2.139 2015/06/18 14:19:52 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 2.140 2015/09/08 15:41:05 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -221,11 +221,11 @@ void luaD_shrinkstack (lua_State *L) { | |||
221 | luaE_freeCI(L); /* free all CIs (list grew because of an error) */ | 221 | luaE_freeCI(L); /* free all CIs (list grew because of an error) */ |
222 | else | 222 | else |
223 | luaE_shrinkCI(L); /* shrink list */ | 223 | luaE_shrinkCI(L); /* shrink list */ |
224 | if (inuse > LUAI_MAXSTACK || /* still handling stack overflow? */ | 224 | if (inuse <= LUAI_MAXSTACK && /* not handling stack overflow? */ |
225 | goodsize >= L->stacksize) /* would grow instead of shrink? */ | 225 | goodsize < L->stacksize) /* trying to shrink? */ |
226 | condmovestack(L); /* don't change stack (change only for debugging) */ | ||
227 | else | ||
228 | luaD_reallocstack(L, goodsize); /* shrink it */ | 226 | luaD_reallocstack(L, goodsize); /* shrink it */ |
227 | else | ||
228 | condmovestack(L,,); /* don't change stack (change only for debugging) */ | ||
229 | } | 229 | } |
230 | 230 | ||
231 | 231 | ||
@@ -308,6 +308,13 @@ static void tryfuncTM (lua_State *L, StkId func) { | |||
308 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) | 308 | #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) |
309 | 309 | ||
310 | 310 | ||
311 | /* macro to check stack size, preserving 'p' */ | ||
312 | #define checkstackp(L,n,p) \ | ||
313 | luaD_checkstackaux(L, n, \ | ||
314 | ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ | ||
315 | luaC_checkGC(L), /* stack grow uses memory */ \ | ||
316 | p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ | ||
317 | |||
311 | /* | 318 | /* |
312 | ** returns true if function has been executed (C function) | 319 | ** returns true if function has been executed (C function) |
313 | */ | 320 | */ |
@@ -315,19 +322,17 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
315 | lua_CFunction f; | 322 | lua_CFunction f; |
316 | CallInfo *ci; | 323 | CallInfo *ci; |
317 | int n; /* number of arguments (Lua) or returns (C) */ | 324 | int n; /* number of arguments (Lua) or returns (C) */ |
318 | ptrdiff_t funcr = savestack(L, func); | ||
319 | switch (ttype(func)) { | 325 | switch (ttype(func)) { |
320 | case LUA_TLCF: /* light C function */ | ||
321 | f = fvalue(func); | ||
322 | goto Cfunc; | ||
323 | case LUA_TCCL: { /* C closure */ | 326 | case LUA_TCCL: { /* C closure */ |
324 | f = clCvalue(func)->f; | 327 | f = clCvalue(func)->f; |
328 | goto Cfunc; | ||
329 | case LUA_TLCF: /* light C function */ | ||
330 | f = fvalue(func); | ||
325 | Cfunc: | 331 | Cfunc: |
326 | luaC_checkGC(L); /* stack grow uses memory */ | 332 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
327 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ | ||
328 | ci = next_ci(L); /* now 'enter' new function */ | 333 | ci = next_ci(L); /* now 'enter' new function */ |
329 | ci->nresults = nresults; | 334 | ci->nresults = nresults; |
330 | ci->func = restorestack(L, funcr); | 335 | ci->func = func; |
331 | ci->top = L->top + LUA_MINSTACK; | 336 | ci->top = L->top + LUA_MINSTACK; |
332 | lua_assert(ci->top <= L->stack_last); | 337 | lua_assert(ci->top <= L->stack_last); |
333 | ci->callstatus = 0; | 338 | ci->callstatus = 0; |
@@ -344,15 +349,13 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
344 | StkId base; | 349 | StkId base; |
345 | Proto *p = clLvalue(func)->p; | 350 | Proto *p = clLvalue(func)->p; |
346 | n = cast_int(L->top - func) - 1; /* number of real arguments */ | 351 | n = cast_int(L->top - func) - 1; /* number of real arguments */ |
347 | luaC_checkGC(L); /* stack grow uses memory */ | 352 | checkstackp(L, p->maxstacksize, func); |
348 | luaD_checkstack(L, p->maxstacksize); | ||
349 | for (; n < p->numparams; n++) | 353 | for (; n < p->numparams; n++) |
350 | setnilvalue(L->top++); /* complete missing arguments */ | 354 | setnilvalue(L->top++); /* complete missing arguments */ |
351 | if (!p->is_vararg) { | 355 | if (!p->is_vararg) |
352 | func = restorestack(L, funcr); | ||
353 | base = func + 1; | 356 | base = func + 1; |
354 | } | ||
355 | else { | 357 | else { |
358 | ptrdiff_t funcr = savestack(L, func); | ||
356 | base = adjust_varargs(L, p, n); | 359 | base = adjust_varargs(L, p, n); |
357 | func = restorestack(L, funcr); /* previous call can change stack */ | 360 | func = restorestack(L, funcr); /* previous call can change stack */ |
358 | } | 361 | } |
@@ -370,8 +373,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |||
370 | return 0; | 373 | return 0; |
371 | } | 374 | } |
372 | default: { /* not a function */ | 375 | default: { /* not a function */ |
373 | luaD_checkstack(L, 1); /* ensure space for metamethod */ | 376 | checkstackp(L, 1, func); /* ensure space for metamethod */ |
374 | func = restorestack(L, funcr); /* previous call may change stack */ | ||
375 | tryfuncTM(L, func); /* try to get '__call' metamethod */ | 377 | tryfuncTM(L, func); /* try to get '__call' metamethod */ |
376 | return luaD_precall(L, func, nresults); /* now it must be a function */ | 378 | return luaD_precall(L, func, nresults); /* now it must be a function */ |
377 | } | 379 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.h,v 2.21 2014/10/25 11:50:46 roberto Exp roberto $ | 2 | ** $Id: ldo.h,v 2.22 2015/05/22 17:48:19 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -13,8 +13,19 @@ | |||
13 | #include "lzio.h" | 13 | #include "lzio.h" |
14 | 14 | ||
15 | 15 | ||
16 | #define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \ | 16 | /* |
17 | luaD_growstack(L, n); else condmovestack(L); | 17 | ** Macro to check stack size and grow stack if needed. Parameters |
18 | ** 'pre'/'pos' allow the macro to preserve a pointer into the | ||
19 | ** stack across realalocations, doing the work only when needed. | ||
20 | ** 'condmovestack' is used in heavy tests to force a stack reallocation | ||
21 | ** at every check. | ||
22 | */ | ||
23 | #define luaD_checkstackaux(L,n,pre,pos) \ | ||
24 | if (L->stack_last - L->top <= (n)) \ | ||
25 | { pre; luaD_growstack(L, n); pos; } else { condmovestack(L,pre,pos); } | ||
26 | |||
27 | /* In general, 'pre'/'pos' are empty (nothing to save) */ | ||
28 | #define luaD_checkstack(L,n) luaD_checkstackaux(L,n,,) | ||
18 | 29 | ||
19 | 30 | ||
20 | #define incr_top(L) {L->top++; luaD_checkstack(L,0);} | 31 | #define incr_top(L) {L->top++; luaD_checkstack(L,0);} |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: llimits.h,v 1.138 2015/09/22 14:18:24 roberto Exp roberto $ | 2 | ** $Id: llimits.h,v 1.139 2015/10/06 14:29:49 roberto Exp roberto $ |
3 | ** Limits, basic types, and some other 'installation-dependent' definitions | 3 | ** Limits, basic types, and some other 'installation-dependent' definitions |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -306,17 +306,18 @@ typedef unsigned long Instruction; | |||
306 | ** macro to control inclusion of some hard tests on stack reallocation | 306 | ** macro to control inclusion of some hard tests on stack reallocation |
307 | */ | 307 | */ |
308 | #if !defined(HARDSTACKTESTS) | 308 | #if !defined(HARDSTACKTESTS) |
309 | #define condmovestack(L) ((void)0) | 309 | #define condmovestack(L,pre,pos) ((void)0) |
310 | #else | 310 | #else |
311 | /* realloc stack keeping its size */ | 311 | /* realloc stack keeping its size */ |
312 | #define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) | 312 | #define condmovestack(L,pre,pos) \ |
313 | { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_); pos; } | ||
313 | #endif | 314 | #endif |
314 | 315 | ||
315 | #if !defined(HARDMEMTESTS) | 316 | #if !defined(HARDMEMTESTS) |
316 | #define condchangemem(L) condmovestack(L) | 317 | #define condchangemem(L,pre,pos) ((void)0) |
317 | #else | 318 | #else |
318 | #define condchangemem(L) \ | 319 | #define condchangemem(L,pre,pos) \ |
319 | ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) | 320 | { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } } |
320 | #endif | 321 | #endif |
321 | 322 | ||
322 | #endif | 323 | #endif |