mirror of https://github.com/rusefi/lua.git
Open upvalues should be gray when entering gen. mode
Open upvalues are never black; so, when entering generational mode, they must be colored gray, not black.
This commit is contained in:
parent
f13dc59416
commit
65141832d2
21
lgc.c
21
lgc.c
|
@ -267,21 +267,22 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
|
||||||
** Mark an object. Userdata, strings, and closed upvalues are visited
|
** Mark an object. Userdata, strings, and closed upvalues are visited
|
||||||
** and turned black here. Other objects are marked gray and added
|
** and turned black here. Other objects are marked gray and added
|
||||||
** to appropriate list to be visited (and turned black) later. (Open
|
** to appropriate list to be visited (and turned black) later. (Open
|
||||||
** upvalues are already linked in 'headuv' list. They are kept gray
|
** upvalues are already indirectly linked through the 'twups' list. They
|
||||||
** to avoid barriers, as their values will be revisited by the thread.)
|
** are kept gray to avoid barriers, as their values will be revisited by
|
||||||
|
** the thread or by 'remarkupvals'.)
|
||||||
*/
|
*/
|
||||||
static void reallymarkobject (global_State *g, GCObject *o) {
|
static void reallymarkobject (global_State *g, GCObject *o) {
|
||||||
white2gray(o);
|
white2gray(o);
|
||||||
switch (o->tt) {
|
switch (o->tt) {
|
||||||
case LUA_VSHRSTR:
|
case LUA_VSHRSTR:
|
||||||
case LUA_VLNGSTR: {
|
case LUA_VLNGSTR: {
|
||||||
gray2black(o);
|
gray2black(o); /* nothing to visit */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LUA_VUPVAL: {
|
case LUA_VUPVAL: {
|
||||||
UpVal *uv = gco2upv(o);
|
UpVal *uv = gco2upv(o);
|
||||||
if (!upisopen(uv)) /* open upvalues are kept gray */
|
if (!upisopen(uv)) /* open upvalues are kept gray */
|
||||||
gray2black(o);
|
gray2black(o); /* closed upvalues are visited here */
|
||||||
markvalue(g, uv->v); /* mark its content */
|
markvalue(g, uv->v); /* mark its content */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -296,7 +297,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
||||||
} /* FALLTHROUGH */
|
} /* FALLTHROUGH */
|
||||||
case LUA_VLCL: case LUA_VCCL: case LUA_VTABLE:
|
case LUA_VLCL: case LUA_VCCL: case LUA_VTABLE:
|
||||||
case LUA_VTHREAD: case LUA_VPROTO: {
|
case LUA_VTHREAD: case LUA_VPROTO: {
|
||||||
linkobjgclist(o, g->gray);
|
linkobjgclist(o, g->gray); /* to be visited later */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: lua_assert(0); break;
|
default: lua_assert(0); break;
|
||||||
|
@ -355,8 +356,10 @@ static int remarkupvals (global_State *g) {
|
||||||
for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) {
|
for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) {
|
||||||
lua_assert(getage(uv) <= getage(thread));
|
lua_assert(getage(uv) <= getage(thread));
|
||||||
work++;
|
work++;
|
||||||
if (!iswhite(uv)) /* upvalue already visited? */
|
if (!iswhite(uv)) { /* upvalue already visited? */
|
||||||
|
lua_assert(upisopen(uv) && isgray(uv));
|
||||||
markvalue(g, uv->v); /* mark its value */
|
markvalue(g, uv->v); /* mark its value */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1028,8 +1031,8 @@ static void setpause (global_State *g);
|
||||||
/*
|
/*
|
||||||
** Sweep a list of objects to enter generational mode. Deletes dead
|
** Sweep a list of objects to enter generational mode. Deletes dead
|
||||||
** objects and turns the non dead to old. All non-dead threads---which
|
** objects and turns the non dead to old. All non-dead threads---which
|
||||||
** are now old---must be in a gray list. Everything else is not in a
|
** are now old---must be in a gray list. Everything else is not in a
|
||||||
** gray list.
|
** gray list. Open upvalues are also kept gray.
|
||||||
*/
|
*/
|
||||||
static void sweep2old (lua_State *L, GCObject **p) {
|
static void sweep2old (lua_State *L, GCObject **p) {
|
||||||
GCObject *curr;
|
GCObject *curr;
|
||||||
|
@ -1047,6 +1050,8 @@ static void sweep2old (lua_State *L, GCObject **p) {
|
||||||
linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
|
linkgclist(th, g->grayagain); /* insert into 'grayagain' list */
|
||||||
black2gray(th); /* OK if already gray */
|
black2gray(th); /* OK if already gray */
|
||||||
}
|
}
|
||||||
|
else if (curr->tt == LUA_VUPVAL && upisopen(gco2upv(curr)))
|
||||||
|
black2gray(curr); /* open upvalues are always gray */
|
||||||
else /* everything else is black */
|
else /* everything else is black */
|
||||||
gray2black(curr); /* OK if already black */
|
gray2black(curr); /* OK if already black */
|
||||||
p = &curr->next; /* go to next element */
|
p = &curr->next; /* go to next element */
|
||||||
|
|
14
lstate.h
14
lstate.h
|
@ -63,7 +63,7 @@
|
||||||
** can become gray have such a field. The field is not the same
|
** can become gray have such a field. The field is not the same
|
||||||
** in all objects, but it always has this name.) Any gray object
|
** in all objects, but it always has this name.) Any gray object
|
||||||
** must belong to one of these lists, and all objects in these lists
|
** must belong to one of these lists, and all objects in these lists
|
||||||
** must be gray (with one exception explained below):
|
** must be gray (with two exceptions explained below):
|
||||||
**
|
**
|
||||||
** 'gray': regular gray objects, still waiting to be visited.
|
** 'gray': regular gray objects, still waiting to be visited.
|
||||||
** 'grayagain': objects that must be revisited at the atomic phase.
|
** 'grayagain': objects that must be revisited at the atomic phase.
|
||||||
|
@ -75,11 +75,13 @@
|
||||||
** 'ephemeron': ephemeron tables with white->white entries;
|
** 'ephemeron': ephemeron tables with white->white entries;
|
||||||
** 'allweak': tables with weak keys and/or weak values to be cleared.
|
** 'allweak': tables with weak keys and/or weak values to be cleared.
|
||||||
**
|
**
|
||||||
** The exception to that "gray rule" is the TOUCHED2 objects in
|
** The exceptions to that "gray rule" are:
|
||||||
** generational mode. Those objects stay in a gray list (because they
|
** - TOUCHED2 objects in generational mode stay in a gray list (because
|
||||||
** must be visited again at the end of the cycle), but they are marked
|
** they must be visited again at the end of the cycle), but they are
|
||||||
** black (because assignments to them must activate barriers, to move
|
** marked black because assignments to them must activate barriers (to
|
||||||
** them back to TOUCHED1).
|
** move them back to TOUCHED1).
|
||||||
|
** - Open upvales are kept gray to avoid barriers, but they stay out
|
||||||
|
** of gray lists. (They don't even have a 'gclist' field.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue