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 |
