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') |
