فهرست منبع

No more field 'lua_State.stacksize'

The stack size is derived from 'stack_last', when needed. Moreover,
the handling of stack sizes is more consistent, always excluding the
extra space except when allocating/deallocating the array.
Roberto Ierusalimschy 4 سال پیش
والد
کامیت
5aa36e894f
6فایلهای تغییر یافته به همراه29 افزوده شده و 26 حذف شده
  1. 9 10
      ldo.c
  2. 2 3
      lgc.c
  3. 3 5
      lstate.c
  4. 10 3
      lstate.h
  5. 4 4
      ltests.c
  6. 1 1
      lvm.c

+ 9 - 10
ldo.c

@@ -182,10 +182,10 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) {
 
 
 int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
-  int lim = L->stacksize;
-  StkId newstack = luaM_reallocvector(L, L->stack, lim, newsize, StackValue);
+  int lim = stacksize(L);
+  StkId newstack = luaM_reallocvector(L, L->stack,
+                      lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue);
   lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE);
-  lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK);
   if (unlikely(newstack == NULL)) {  /* reallocation failed? */
     if (raiseerror)
       luaM_error(L);
@@ -195,8 +195,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
     setnilvalue(s2v(newstack + lim)); /* erase new segment */
   correctstack(L, L->stack, newstack);
   L->stack = newstack;
-  L->stacksize = newsize;
-  L->stack_last = L->stack + newsize - EXTRA_STACK;
+  L->stack_last = L->stack + newsize;
   return 1;
 }
 
@@ -206,19 +205,19 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) {
 ** is true, raises any error; otherwise, return 0 in case of errors.
 */
 int luaD_growstack (lua_State *L, int n, int raiseerror) {
-  int size = L->stacksize;
+  int size = stacksize(L);
   if (unlikely(size > LUAI_MAXSTACK)) {
     /* if stack is larger than maximum, thread is already using the
        extra space reserved for errors, that is, thread is handling
        a stack error; cannot grow further than that. */
-    lua_assert(L->stacksize == ERRORSTACKSIZE);
+    lua_assert(stacksize(L) == ERRORSTACKSIZE);
     if (raiseerror)
       luaD_throw(L, LUA_ERRERR);  /* error inside message handler */
     return 0;  /* if not 'raiseerror', just signal it */
   }
   else {
     int newsize = 2 * size;  /* tentative new size */
-    int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK;
+    int needed = cast_int(L->top - L->stack) + n;
     if (newsize > LUAI_MAXSTACK)  /* cannot cross the limit */
       newsize = LUAI_MAXSTACK;
     if (newsize < needed)  /* but must respect what was asked for */
@@ -257,7 +256,7 @@ static int stackinuse (lua_State *L) {
 ** previous size, and half of its entries are empty.)
 ** As a particular case, if stack was handling a stack overflow and now
 ** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than
-** 'stacksize' (equal to ERRORSTACKSIZE in this case), and so the stack
+** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack
 ** will be reduced to a "regular" size.
 */
 void luaD_shrinkstack (lua_State *L) {
@@ -271,7 +270,7 @@ void luaD_shrinkstack (lua_State *L) {
   }
   /* if thread is currently not handling a stack overflow and its
      size is larger than maximum "reasonable" size, shrink it */
-  if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && L->stacksize > max)
+  if (inuse <= LUAI_MAXSTACK && stacksize(L) > max)
     luaD_reallocstack(L, nsize, 0);  /* ok if that fails */
   else  /* don't change stack */
     condmovestack(L,{},{});  /* (change only for debugging) */

+ 2 - 3
lgc.c

@@ -633,8 +633,7 @@ static int traversethread (global_State *g, lua_State *th) {
   for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
     markobject(g, uv);  /* open upvalues cannot be collected */
   if (g->gcstate == GCSatomic) {  /* final traversal? */
-    StkId lim = th->stack + th->stacksize;  /* real end of stack */
-    for (; o < lim; o++)  /* clear not-marked stack slice */
+    for (; o < th->stack_last; o++)  /* clear not-marked stack slice */
       setnilvalue(s2v(o));
     /* 'remarkupvals' may have removed thread from 'twups' list */
     if (!isintwups(th) && th->openupval != NULL) {
@@ -644,7 +643,7 @@ static int traversethread (global_State *g, lua_State *th) {
   }
   else if (!g->gcemergency)
     luaD_shrinkstack(th); /* do not change stack in emergency cycle */
-  return 1 + th->stacksize;
+  return 1 + stacksize(th);
 }
 
 

+ 3 - 5
lstate.c

@@ -180,12 +180,11 @@ LUAI_FUNC void luaE_incCstack (lua_State *L) {
 static void stack_init (lua_State *L1, lua_State *L) {
   int i; CallInfo *ci;
   /* initialize stack array */
-  L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue);
-  L1->stacksize = BASIC_STACK_SIZE;
+  L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue);
   for (i = 0; i < BASIC_STACK_SIZE; i++)
     setnilvalue(s2v(L1->stack + i));  /* erase new stack */
   L1->top = L1->stack;
-  L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
+  L1->stack_last = L1->stack + BASIC_STACK_SIZE;
   /* initialize first ci */
   ci = &L1->base_ci;
   ci->next = ci->previous = NULL;
@@ -206,7 +205,7 @@ static void freestack (lua_State *L) {
   L->ci = &L->base_ci;  /* free the entire 'ci' list */
   luaE_freeCI(L);
   lua_assert(L->nci == 0);
-  luaM_freearray(L, L->stack, L->stacksize);  /* free stack array */
+  luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK);  /* free stack */
 }
 
 
@@ -256,7 +255,6 @@ static void preinit_thread (lua_State *L, global_State *g) {
   L->stack = NULL;
   L->ci = NULL;
   L->nci = 0;
-  L->stacksize = 0;
   L->twups = L;  /* thread has no upvalues */
   L->errorJmp = NULL;
   L->hook = NULL;

+ 10 - 3
lstate.h

@@ -127,12 +127,20 @@ struct lua_longjmp;  /* defined in ldo.c */
 #endif
 
 
-/* extra stack space to handle TM calls and some other extras */
+/*
+** Extra stack space to handle TM calls and some other extras. This
+** space is not included in 'stack_last'. It is used only to avoid stack
+** checks, either because the element will be promptly popped or because
+** there will be a stack check soon after the push. Function frames
+** never use this extra space, so it does not need to be kept clean.
+*/
 #define EXTRA_STACK   5
 
 
 #define BASIC_STACK_SIZE        (2*LUA_MINSTACK)
 
+#define stacksize(th)	cast_int((th)->stack_last - (th)->stack)
+
 
 /* kinds of Garbage Collection */
 #define KGC_INC		0	/* incremental gc */
@@ -270,7 +278,7 @@ struct lua_State {
   StkId top;  /* first free slot in the stack */
   global_State *l_G;
   CallInfo *ci;  /* call info for current function */
-  StkId stack_last;  /* last free slot in the stack */
+  StkId stack_last;  /* end of stack (last element + 1) */
   StkId stack;  /* stack base */
   UpVal *openupval;  /* list of open upvalues in this stack */
   GCObject *gclist;
@@ -281,7 +289,6 @@ struct lua_State {
   ptrdiff_t errfunc;  /* current error handling function (stack index) */
   l_uint32 nCcalls;  /* number of nested (non-yieldable | C)  calls */
   int oldpc;  /* last pc traced */
-  int stacksize;
   int basehookcount;
   int hookcount;
   volatile l_signalT hookmask;

+ 4 - 4
ltests.c

@@ -430,17 +430,17 @@ static void checkstack (global_State *g, lua_State *L1) {
   UpVal *uv;
   lua_assert(!isdead(g, L1));
   if (L1->stack == NULL) {  /* incomplete thread? */
-    lua_assert(L1->stacksize == 0 && L1->openupval == NULL &&
-               L1->ci == NULL);
+    lua_assert(L1->openupval == NULL && L1->ci == NULL);
     return;
   }
   for (uv = L1->openupval; uv != NULL; uv = uv->u.open.next)
     lua_assert(upisopen(uv));  /* must be open */
+  lua_assert(L1->top <= L1->stack_last);
   for (ci = L1->ci; ci != NULL; ci = ci->previous) {
     lua_assert(ci->top <= L1->stack_last);
     lua_assert(lua_checkpc(ci));
   }
-  for (o = L1->stack; o < L1->stack_last + EXTRA_STACK; o++)
+  for (o = L1->stack; o < L1->stack_last; o++)
     checkliveness(L1, s2v(o));  /* entire stack must have valid values */
 }
 
@@ -969,7 +969,7 @@ static int hash_query (lua_State *L) {
 static int stacklevel (lua_State *L) {
   unsigned long a = 0;
   lua_pushinteger(L, (L->top - L->stack));
-  lua_pushinteger(L, (L->stack_last - L->stack));
+  lua_pushinteger(L, stacksize(L));
   lua_pushinteger(L, L->nCcalls);
   lua_pushinteger(L, L->nci);
   lua_pushinteger(L, (unsigned long)&a);

+ 1 - 1
lvm.c

@@ -1151,7 +1151,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
     StkId ra;  /* instruction's A register */
     vmfetch();
     lua_assert(base == ci->func + 1);
-    lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
+    lua_assert(base <= L->top && L->top < L->stack_last);
     /* invalidate top for instructions not expecting it */
     lua_assert(isIT(i) || (cast_void(L->top = base), 1));
     vmdispatch (GET_OPCODE(i)) {