mirror of https://github.com/rusefi/lua.git
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 440a5ee78c
, about upvalues in the list of open upvalues
being collected while others are being created. (That previous fix
may not be correct.)
This commit is contained in:
parent
2f22c6bb79
commit
9e6807c3c9
15
lfunc.c
15
lfunc.c
|
@ -83,21 +83,20 @@ static UpVal *newupval (lua_State *L, int tbc, StkId level, UpVal **prev) {
|
|||
|
||||
/*
|
||||
** Find and reuse, or create if it does not exist, an upvalue
|
||||
** at the given level and set it to the given slot.
|
||||
** at the given level.
|
||||
*/
|
||||
void luaF_setupval (lua_State *L, StkId level, UpVal **slot) {
|
||||
UpVal *luaF_findupval (lua_State *L, StkId level) {
|
||||
UpVal **pp = &L->openupval;
|
||||
UpVal *p;
|
||||
lua_assert(isintwups(L) || L->openupval == NULL);
|
||||
while ((p = *pp) != NULL && uplevel(p) >= level) { /* search for it */
|
||||
*slot = p;
|
||||
if (uplevel(p) == level && !isdead(G(L), p)) /* corresponding upvalue? */
|
||||
return; /* found it */
|
||||
lua_assert(!isdead(G(L), p));
|
||||
if (uplevel(p) == level) /* corresponding upvalue? */
|
||||
return p; /* return it */
|
||||
pp = &p->u.open.next;
|
||||
}
|
||||
/* not found: create a new upvalue after 'pp' (which is
|
||||
anchored in 'slot', in case of an emergency collection) */
|
||||
*slot = newupval(L, 0, level, pp);
|
||||
/* not found: create a new upvalue after 'pp' */
|
||||
return newupval(L, 0, level, pp);
|
||||
}
|
||||
|
||||
|
||||
|
|
2
lfunc.h
2
lfunc.h
|
@ -57,7 +57,7 @@ LUAI_FUNC Proto *luaF_newproto (lua_State *L);
|
|||
LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
|
||||
LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
|
||||
LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
|
||||
LUAI_FUNC void luaF_setupval (lua_State *L, StkId level, UpVal **slot);
|
||||
LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
|
||||
LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level);
|
||||
LUAI_FUNC int luaF_close (lua_State *L, StkId level, int status);
|
||||
LUAI_FUNC void luaF_unlinkupval (UpVal *uv);
|
||||
|
|
6
lgc.c
6
lgc.c
|
@ -569,10 +569,8 @@ static int traversethread (global_State *g, lua_State *th) {
|
|||
th->openupval == NULL || isintwups(th));
|
||||
for (; o < th->top; o++) /* mark live elements in the stack */
|
||||
markvalue(g, s2v(o));
|
||||
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) {
|
||||
if (uv->tbc) /* to be closed? */
|
||||
markobject(g, uv); /* cannot be collected */
|
||||
}
|
||||
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 */
|
||||
|
|
2
lvm.c
2
lvm.c
|
@ -697,7 +697,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
|||
setclLvalue2s(L, ra, ncl); /* anchor new closure in stack */
|
||||
for (i = 0; i < nup; i++) { /* fill in its upvalues */
|
||||
if (uv[i].instack) /* upvalue refers to local variable? */
|
||||
luaF_setupval(L, base + uv[i].idx, &ncl->upvals[i]);
|
||||
ncl->upvals[i] = luaF_findupval(L, base + uv[i].idx);
|
||||
else /* get upvalue from enclosing function */
|
||||
ncl->upvals[i] = encup[uv[i].idx];
|
||||
luaC_objbarrier(L, ncl, ncl->upvals[i]);
|
||||
|
|
Loading…
Reference in New Issue