diff options
| -rw-r--r-- | lgc.c | 10 | ||||
| -rw-r--r-- | testes/gengc.lua | 17 |
2 files changed, 19 insertions, 8 deletions
| @@ -1146,15 +1146,9 @@ static GCObject **correctgraylist (GCObject **p) { | |||
| 1146 | } | 1146 | } |
| 1147 | else { /* everything else is removed */ | 1147 | else { /* everything else is removed */ |
| 1148 | lua_assert(isold(curr)); /* young objects should be white here */ | 1148 | lua_assert(isold(curr)); /* young objects should be white here */ |
| 1149 | if (getage(curr) == G_TOUCHED2) { /* advance from TOUCHED2... */ | 1149 | if (getage(curr) == G_TOUCHED2) /* advance from TOUCHED2... */ |
| 1150 | changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */ | 1150 | changeage(curr, G_TOUCHED2, G_OLD); /* ... to OLD */ |
| 1151 | lua_assert(isblack(curr)); /* TOUCHED2 objects are always black */ | 1151 | gray2black(curr); /* make object black (to be removed) */ |
| 1152 | } | ||
| 1153 | else { | ||
| 1154 | /* everything else in a gray list should be gray */ | ||
| 1155 | lua_assert(isgray(curr)); | ||
| 1156 | gray2black(curr); /* make object black (to be removed) */ | ||
| 1157 | } | ||
| 1158 | goto remove; | 1152 | goto remove; |
| 1159 | } | 1153 | } |
| 1160 | remove: *p = *next; continue; | 1154 | remove: *p = *next; continue; |
diff --git a/testes/gengc.lua b/testes/gengc.lua index 93b5afd7..3d4f67f8 100644 --- a/testes/gengc.lua +++ b/testes/gengc.lua | |||
| @@ -106,6 +106,23 @@ do -- another bug in 5.4.0 | |||
| 106 | end | 106 | end |
| 107 | 107 | ||
| 108 | 108 | ||
| 109 | do -- bug introduced in commit 9cf3299fa | ||
| 110 | local t = setmetatable({}, {__mode = "kv"}) -- all-weak table | ||
| 111 | collectgarbage() -- full collection | ||
| 112 | assert(not T or T.gcage(t) == "old") | ||
| 113 | t[1] = {10} | ||
| 114 | assert(not T or (T.gcage(t) == "touched1" and T.gccolor(t) == "gray")) | ||
| 115 | collectgarbage("step", 0) -- minor collection | ||
| 116 | assert(not T or (T.gcage(t) == "touched2" and T.gccolor(t) == "black")) | ||
| 117 | collectgarbage("step", 0) -- minor collection | ||
| 118 | assert(not T or T.gcage(t) == "old") -- t should be black, but it was gray | ||
| 119 | t[1] = {10} -- no barrier here, so t was still old | ||
| 120 | collectgarbage("step", 0) -- minor collection | ||
| 121 | -- t, being old, is ignored by the collection, so it is not cleared | ||
| 122 | assert(t[1] == nil) -- fails with the bug | ||
| 123 | end | ||
| 124 | |||
| 125 | |||
| 109 | if T == nil then | 126 | if T == nil then |
| 110 | (Message or print)('\n >>> testC not active: \z | 127 | (Message or print)('\n >>> testC not active: \z |
| 111 | skipping some generational tests <<<\n') | 128 | skipping some generational tests <<<\n') |
