mirror of https://github.com/rusefi/lua.git
TOUCHED2 objects are not always black
This commit fixes a bug introduced in commit 9cf3299fa
. TOUCHED2
objects are always black while the mutator runs, but they can become
temporarily gray inside a minor collection (e.g., if the object is a
weak table).
This commit is contained in:
parent
65141832d2
commit
f7ce7e5faa
10
lgc.c
10
lgc.c
|
@ -1146,15 +1146,9 @@ static GCObject **correctgraylist (GCObject **p) {
|
||||||
}
|
}
|
||||||
else { /* everything else is removed */
|
else { /* everything else is removed */
|
||||||
lua_assert(isold(curr)); /* young objects should be white here */
|
lua_assert(isold(curr)); /* young objects should be white here */
|
||||||
if (getage(curr) == G_TOUCHED2) { /* advance from TOUCHED2... */
|
if (getage(curr) == G_TOUCHED2) /* advance from TOUCHED2... */
|
||||||
changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */
|
changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */
|
||||||
lua_assert(isblack(curr)); /* TOUCHED2 objects are always black */
|
gray2black(curr); /* make object black (to be removed) */
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* everything else in a gray list should be gray */
|
|
||||||
lua_assert(isgray(curr));
|
|
||||||
gray2black(curr); /* make object black (to be removed) */
|
|
||||||
}
|
|
||||||
goto remove;
|
goto remove;
|
||||||
}
|
}
|
||||||
remove: *p = *next; continue;
|
remove: *p = *next; continue;
|
||||||
|
|
|
@ -106,6 +106,23 @@ do -- another bug in 5.4.0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
do -- bug introduced in commit 9cf3299fa
|
||||||
|
local t = setmetatable({}, {__mode = "kv"}) -- all-weak table
|
||||||
|
collectgarbage() -- full collection
|
||||||
|
assert(not T or T.gcage(t) == "old")
|
||||||
|
t[1] = {10}
|
||||||
|
assert(not T or (T.gcage(t) == "touched1" and T.gccolor(t) == "gray"))
|
||||||
|
collectgarbage("step", 0) -- minor collection
|
||||||
|
assert(not T or (T.gcage(t) == "touched2" and T.gccolor(t) == "black"))
|
||||||
|
collectgarbage("step", 0) -- minor collection
|
||||||
|
assert(not T or T.gcage(t) == "old") -- t should be black, but it was gray
|
||||||
|
t[1] = {10} -- no barrier here, so t was still old
|
||||||
|
collectgarbage("step", 0) -- minor collection
|
||||||
|
-- t, being old, is ignored by the collection, so it is not cleared
|
||||||
|
assert(t[1] == nil) -- fails with the bug
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
if T == nil then
|
if T == nil then
|
||||||
(Message or print)('\n >>> testC not active: \z
|
(Message or print)('\n >>> testC not active: \z
|
||||||
skipping some generational tests <<<\n')
|
skipping some generational tests <<<\n')
|
||||||
|
|
Loading…
Reference in New Issue