diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-27 10:26:20 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2020-07-27 10:26:20 -0300 |
commit | a6da1472c0c5e05ff249325f979531ad51533110 (patch) | |
tree | 984a5355d168a60e604f7bc27fc7a2b3628620f3 /testes | |
parent | 34affe7a63fc5d842580a9f23616d057e17dfe27 (diff) | |
download | lua-a6da1472c0c5e05ff249325f979531ad51533110.tar.gz lua-a6da1472c0c5e05ff249325f979531ad51533110.tar.bz2 lua-a6da1472c0c5e05ff249325f979531ad51533110.zip |
Fixed bug: barriers cannot be active during sweep
Barriers cannot be active during sweep, even in generational mode.
(Although gen. mode is not incremental, it can hit a barrier when
deleting a thread and closing its upvalues.) The colors of objects are
being changed during sweep and, therefore, cannot be trusted.
Diffstat (limited to 'testes')
-rw-r--r-- | testes/gengc.lua | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/testes/gengc.lua b/testes/gengc.lua index 4e80dd7e..7a7dabdd 100644 --- a/testes/gengc.lua +++ b/testes/gengc.lua | |||
@@ -57,13 +57,39 @@ do -- bug in 5.4.0 | |||
57 | local obj = {} -- create a new object | 57 | local obj = {} -- create a new object |
58 | collectgarbage("step", 0) -- make it a survival | 58 | collectgarbage("step", 0) -- make it a survival |
59 | assert(not T or T.gcage(obj) == "survival") | 59 | assert(not T or T.gcage(obj) == "survival") |
60 | setmetatable(obj, {__gc = gcf, x = "ok"}) -- create its metatable | 60 | setmetatable(obj, {__gc = gcf, x = "+"}) -- create its metatable |
61 | assert(not T or T.gcage(getmetatable(obj)) == "new") | 61 | assert(not T or T.gcage(getmetatable(obj)) == "new") |
62 | obj = nil -- clear object | 62 | obj = nil -- clear object |
63 | collectgarbage("step", 0) -- will call obj's finalizer | 63 | collectgarbage("step", 0) -- will call obj's finalizer |
64 | end | 64 | end |
65 | 65 | ||
66 | 66 | ||
67 | do -- another bug in 5.4.0 | ||
68 | local old = {10} | ||
69 | collectgarbage() -- make 'old' old | ||
70 | local co = coroutine.create( | ||
71 | function () | ||
72 | local x = nil | ||
73 | local f = function () | ||
74 | return x[1] | ||
75 | end | ||
76 | x = coroutine.yield(f) | ||
77 | coroutine.yield() | ||
78 | end | ||
79 | ) | ||
80 | local _, f = coroutine.resume(co) -- create closure over 'x' in coroutine | ||
81 | collectgarbage("step", 0) -- make upvalue a survival | ||
82 | old[1] = {"hello"} -- 'old' go to grayagain as 'touched1' | ||
83 | coroutine.resume(co, {123}) -- its value will be new | ||
84 | co = nil | ||
85 | collectgarbage("step", 0) -- hit the barrier | ||
86 | assert(f() == 123 and old[1][1] == "hello") | ||
87 | collectgarbage("step", 0) -- run the collector once more | ||
88 | -- make sure old[1] was not collected | ||
89 | assert(f() == 123 and old[1][1] == "hello") | ||
90 | end | ||
91 | |||
92 | |||
67 | if T == nil then | 93 | if T == nil then |
68 | (Message or print)('\n >>> testC not active: \z | 94 | (Message or print)('\n >>> testC not active: \z |
69 | skipping some generational tests <<<\n') | 95 | skipping some generational tests <<<\n') |