155 lines
6.0 KiB
Diff
155 lines
6.0 KiB
Diff
commit 6298903e35217ab69c279056f925fb72900ce0b7
|
|
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
Date: Mon Jul 6 12:11:54 2020 -0300
|
|
|
|
Keep minimum size when shrinking a stack
|
|
|
|
When shrinking a stack (during GC), do not make it smaller than the
|
|
initial stack size.
|
|
|
|
diff --git a/src/ldo.c b/src/ldo.c
|
|
index c563b1d9..a89ac010 100644
|
|
--- a/src/ldo.c
|
|
+++ b/src/ldo.c
|
|
@@ -245,13 +245,12 @@ static int stackinuse (lua_State *L) {
|
|
|
|
void luaD_shrinkstack (lua_State *L) {
|
|
int inuse = stackinuse(L);
|
|
- int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
|
|
+ int goodsize = inuse + BASIC_STACK_SIZE;
|
|
if (goodsize > LUAI_MAXSTACK)
|
|
goodsize = LUAI_MAXSTACK; /* respect stack limit */
|
|
/* if thread is currently not handling a stack overflow and its
|
|
good size is smaller than current size, shrink its stack */
|
|
- if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) &&
|
|
- goodsize < L->stacksize)
|
|
+ if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && goodsize < L->stacksize)
|
|
luaD_reallocstack(L, goodsize, 0); /* ok if that fails */
|
|
else /* don't change stack */
|
|
condmovestack(L,{},{}); /* (change only for debugging) */
|
|
|
|
commit eb41999461b6f428186c55abd95f4ce1a76217d5
|
|
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
|
|
Date: Tue Jul 7 18:03:48 2020 -0300
|
|
|
|
Fixed bugs of stack reallocation x GC
|
|
|
|
Macro 'checkstackGC' was doing a GC step after resizing the stack;
|
|
the GC could shrink the stack and undo the resize. Moreover, macro
|
|
'checkstackp' also does a GC step, which could remove the preallocated
|
|
CallInfo when calling a function. (Its name has been changed to
|
|
'checkstackGCp' to emphasize that it calls the GC.)
|
|
|
|
diff --git a/src/ldo.c b/src/ldo.c
|
|
index 66217a4b..e3db1f74 100644
|
|
--- a/src/ldo.c
|
|
+++ b/src/ldo.c
|
|
@@ -465,13 +465,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
|
|
f = fvalue(s2v(func));
|
|
Cfunc: {
|
|
int n; /* number of returns */
|
|
- CallInfo *ci = next_ci(L);
|
|
- checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
|
+ CallInfo *ci;
|
|
+ checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */
|
|
+ L->ci = ci = next_ci(L);
|
|
ci->nresults = nresults;
|
|
ci->callstatus = CIST_C;
|
|
ci->top = L->top + LUA_MINSTACK;
|
|
ci->func = func;
|
|
- L->ci = ci;
|
|
lua_assert(ci->top <= L->stack_last);
|
|
if (L->hookmask & LUA_MASKCALL) {
|
|
int narg = cast_int(L->top - func) - 1;
|
|
@@ -485,12 +485,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
|
|
break;
|
|
}
|
|
case LUA_VLCL: { /* Lua function */
|
|
- CallInfo *ci = next_ci(L);
|
|
+ CallInfo *ci;
|
|
Proto *p = clLvalue(s2v(func))->p;
|
|
int narg = cast_int(L->top - func) - 1; /* number of real arguments */
|
|
int nfixparams = p->numparams;
|
|
int fsize = p->maxstacksize; /* frame size */
|
|
- checkstackp(L, fsize, func);
|
|
+ checkstackGCp(L, fsize, func);
|
|
+ L->ci = ci = next_ci(L);
|
|
ci->nresults = nresults;
|
|
ci->u.l.savedpc = p->code; /* starting point */
|
|
ci->callstatus = 0;
|
|
@@ -504,7 +505,7 @@ void luaD_call (lua_State *L, StkId func, int nresults) {
|
|
break;
|
|
}
|
|
default: { /* not a function */
|
|
- checkstackp(L, 1, func); /* space for metamethod */
|
|
+ checkstackGCp(L, 1, func); /* space for metamethod */
|
|
luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
|
|
goto retry; /* try again with metamethod */
|
|
}
|
|
diff --git a/src/ldo.h b/src/ldo.h
|
|
index 7760f853..6c6cb285 100644
|
|
--- a/src/ldo.h
|
|
+++ b/src/ldo.h
|
|
@@ -17,6 +17,8 @@
|
|
** Macro to check stack size and grow stack if needed. Parameters
|
|
** 'pre'/'pos' allow the macro to preserve a pointer into the
|
|
** stack across reallocations, doing the work only when needed.
|
|
+** It also allows the running of one GC step when the stack is
|
|
+** reallocated.
|
|
** 'condmovestack' is used in heavy tests to force a stack reallocation
|
|
** at every check.
|
|
*/
|
|
@@ -35,7 +37,7 @@
|
|
|
|
|
|
/* macro to check stack size, preserving 'p' */
|
|
-#define checkstackp(L,n,p) \
|
|
+#define checkstackGCp(L,n,p) \
|
|
luaD_checkstackaux(L, n, \
|
|
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
|
|
luaC_checkGC(L), /* stack grow uses memory */ \
|
|
@@ -44,7 +46,7 @@
|
|
|
|
/* macro to check stack size and GC */
|
|
#define checkstackGC(L,fsize) \
|
|
- luaD_checkstackaux(L, (fsize), (void)0, luaC_checkGC(L))
|
|
+ luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0)
|
|
|
|
|
|
/* type of protected functions, to be ran by 'runprotected' */
|
|
diff --git a/src/ltm.c b/src/ltm.c
|
|
index ae60983f..4770f96b 100644
|
|
--- a/src/ltm.c
|
|
+++ b/src/ltm.c
|
|
@@ -240,7 +240,7 @@ void luaT_adjustvarargs (lua_State *L, int nfixparams, CallInfo *ci,
|
|
int actual = cast_int(L->top - ci->func) - 1; /* number of arguments */
|
|
int nextra = actual - nfixparams; /* number of extra arguments */
|
|
ci->u.l.nextraargs = nextra;
|
|
- checkstackGC(L, p->maxstacksize + 1);
|
|
+ luaD_checkstack(L, p->maxstacksize + 1);
|
|
/* copy function to the top of the stack */
|
|
setobjs2s(L, L->top++, ci->func);
|
|
/* move fixed parameters to the top of the stack */
|
|
@@ -259,7 +259,7 @@ void luaT_getvarargs (lua_State *L, CallInfo *ci, StkId where, int wanted) {
|
|
int nextra = ci->u.l.nextraargs;
|
|
if (wanted < 0) {
|
|
wanted = nextra; /* get all extra arguments available */
|
|
- checkstackp(L, nextra, where); /* ensure stack space */
|
|
+ checkstackGCp(L, nextra, where); /* ensure stack space */
|
|
L->top = where + nextra; /* next instruction will need top */
|
|
}
|
|
for (i = 0; i < wanted && i < nextra; i++)
|
|
diff --git a/src/lvm.c b/src/lvm.c
|
|
index ccbfbab5..d78d6be2 100644
|
|
--- a/src/lvm.c
|
|
+++ b/src/lvm.c
|
|
@@ -1634,7 +1634,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
|
|
while (!ttisfunction(s2v(ra))) { /* not a function? */
|
|
luaD_tryfuncTM(L, ra); /* try '__call' metamethod */
|
|
b++; /* there is now one extra argument */
|
|
- checkstackp(L, 1, ra);
|
|
+ checkstackGCp(L, 1, ra);
|
|
}
|
|
if (!ttisLclosure(s2v(ra))) { /* C function? */
|
|
luaD_call(L, ra, LUA_MULTRET); /* call it */
|