aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-22 09:41:10 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-22 09:41:10 -0300
commit9e6807c3c9d5036e999f636f936df07b72284442 (patch)
tree39100fb44792114905f00d1b638212f620d12a25
parent2f22c6bb79d209a55b3fc8e0b2d9c9f89f038174 (diff)
downloadlua-9e6807c3c9d5036e999f636f936df07b72284442.tar.gz
lua-9e6807c3c9d5036e999f636f936df07b72284442.tar.bz2
lua-9e6807c3c9d5036e999f636f936df07b72284442.zip
Do not collect open upvalues
Open upvalues are kept alive together with their corresponding stack. This change makes a simpler and safer fix to the issue in commit 440a5ee78c8, about upvalues in the list of open upvalues being collected while others are being created. (That previous fix may not be correct.)
-rw-r--r--lfunc.c15
-rw-r--r--lfunc.h2
-rw-r--r--lgc.c6
-rw-r--r--lvm.c2
4 files changed, 11 insertions, 14 deletions
diff --git a/lfunc.c b/lfunc.c
index f7edf56b..6f2f897f 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -83,21 +83,20 @@ static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) {
83 83
84/* 84/*
85** Find and reuse, or create if it does not exist, an upvalue 85** Find and reuse, or create if it does not exist, an upvalue
86** at the given level and set it to the given slot. 86** at the given level.
87*/ 87*/
88void luaF_setupval (lua_State *L, StkId level, UpVal **slot) { 88UpVal *luaF_findupval (lua_State *L, StkId level) {
89 UpVal **pp = &L->openupval; 89 UpVal **pp = &L->openupval;
90 UpVal *p; 90 UpVal *p;
91 lua_assert(isintwups(L) || L->openupval == NULL); 91 lua_assert(isintwups(L) || L->openupval == NULL);
92 while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */ 92 while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */
93 *slot = p; 93 lua_assert(!isdead(G(L), p));
94 if (uplevel(p) == level && !isdead(G(L), p)) /* corresponding upvalue? */ 94 if (uplevel(p) == level) /* corresponding upvalue? */
95 return; /* found it */ 95 return p; /* return it */
96 pp = &p->u.open.next; 96 pp = &p->u.open.next;
97 } 97 }
98 /* not found: create a new upvalue after 'pp' (which is 98 /* not found: create a new upvalue after 'pp' */
99 anchored in 'slot', in case of an emergency collection) */ 99 return newupval(L, 0, level, pp);
100 *slot = newupval(L, 0, level, pp);
101} 100}
102 101
103 102
diff --git a/lfunc.h b/lfunc.h
index 72fc913a..0ed79c48 100644
--- a/lfunc.h
+++ b/lfunc.h
@@ -57,7 +57,7 @@ LUAI_FUNC Proto *luaF_newproto (lua_State *L);
57LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); 57LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
58LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); 58LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
59LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); 59LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
60LUAI_FUNC void luaF_setupval (lua_State *L, StkId level, UpVal **slot); 60LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
61LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); 61LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level);
62LUAI_FUNC int luaF_close (lua_State *L, StkId level, int status); 62LUAI_FUNC int luaF_close (lua_State *L, StkId level, int status);
63LUAI_FUNC void luaF_unlinkupval (UpVal *uv); 63LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
diff --git a/lgc.c b/lgc.c
index c5babfed..b7220cf1 100644
--- a/lgc.c
+++ b/lgc.c
@@ -569,10 +569,8 @@ static int traversethread (global_State *g, lua_State *th) {
569 th->openupval == NULL || isintwups(th)); 569 th->openupval == NULL || isintwups(th));
570 for (; o < th->top; o++) /* mark live elements in the stack */ 570 for (; o < th->top; o++) /* mark live elements in the stack */
571 markvalue(g, s2v(o)); 571 markvalue(g, s2v(o));
572 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) { 572 for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
573 if (uv->tbc) /* to be closed? */ 573 markobject(g, uv); /* open upvalues cannot be collected */
574 markobject(g, uv); /* cannot be collected */
575 }
576 if (g->gcstate == GCSatomic) { /* final traversal? */ 574 if (g->gcstate == GCSatomic) { /* final traversal? */
577 StkId lim = th->stack + th->stacksize; /* real end of stack */ 575 StkId lim = th->stack + th->stacksize; /* real end of stack */
578 for (; o < lim; o++) /* clear not-marked stack slice */ 576 for (; o < lim; o++) /* clear not-marked stack slice */
diff --git a/lvm.c b/lvm.c
index d3e05199..d9bd0ab3 100644
--- a/lvm.c
+++ b/lvm.c
@@ -697,7 +697,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
697 setclLvalue2s(L, ra, ncl); /* anchor new closure in stack */ 697 setclLvalue2s(L, ra, ncl); /* anchor new closure in stack */
698 for (i = 0; i < nup; i++) { /* fill in its upvalues */ 698 for (i = 0; i < nup; i++) { /* fill in its upvalues */
699 if (uv[i].instack) /* upvalue refers to local variable? */ 699 if (uv[i].instack) /* upvalue refers to local variable? */
700 luaF_setupval(L, base + uv[i].idx, &ncl->upvals[i]); 700 ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx);
701 else /* get upvalue from enclosing function */ 701 else /* get upvalue from enclosing function */
702 ncl->upvals[i] = encup[uv[i].idx]; 702 ncl->upvals[i] = encup[uv[i].idx];
703 luaC_objbarrier(L, ncl, ncl->upvals[i]); 703 luaC_objbarrier(L, ncl, ncl->upvals[i]);