1
0
mirror of https://github.com/lua/lua.git synced 2025-01-28 06:03:00 +08:00
lua/testes/gengc.lua
Roberto Ierusalimschy 2e297d6ab3 Fixed bug in generational collection of userdata
During generational collection, a userdatum must become gray and
go to a gray list after being traversed (like tables), so that
'correctgraylist' can handle it to its next stage.

This commit also added minimum tests for the generational collector,
including one that would detect this bug.
2018-07-13 15:43:02 -03:00

84 lines
2.0 KiB
Lua

-- $Id: gengc.lua $
-- See Copyright Notice in file all.lua
print('testing generational garbage collection')
local debug = require"debug"
assert(collectgarbage("isrunning"))
collectgarbage()
local oldmode = collectgarbage("generational")
-- ensure that table barrier evolves correctly
do
local U = {}
-- full collection makes 'U' old
collectgarbage()
assert(not T or T.gcage(U) == "old")
-- U refers to a new table, so it becomes 'touched1'
U[1] = {x = {234}}
assert(not T or (T.gcage(U) == "touched1" and T.gcage(U[1]) == "new"))
-- both U and the table survive one more collection
collectgarbage("step", 0)
assert(not T or (T.gcage(U) == "touched2" and T.gcage(U[1]) == "survival"))
-- both U and the table survive yet another collection
-- now everything is old
collectgarbage("step", 0)
assert(not T or (T.gcage(U) == "old" and T.gcage(U[1]) == "old1"))
-- data was not corrupted
assert(U[1].x[1] == 234)
end
if T == nil then
(Message or print)('\n >>> testC not active: \z
skipping some generational tests <<<\n')
print 'OK'
return
end
-- ensure that userdata barrier evolves correctly
do
local U = T.newuserdata(0, 1)
-- full collection makes 'U' old
collectgarbage()
assert(T.gcage(U) == "old")
-- U refers to a new table, so it becomes 'touched1'
debug.setuservalue(U, {x = {234}})
assert(T.gcage(U) == "touched1" and
T.gcage(debug.getuservalue(U)) == "new")
-- both U and the table survive one more collection
collectgarbage("step", 0)
assert(T.gcage(U) == "touched2" and
T.gcage(debug.getuservalue(U)) == "survival")
-- both U and the table survive yet another collection
-- now everything is old
collectgarbage("step", 0)
assert(T.gcage(U) == "old" and
T.gcage(debug.getuservalue(U)) == "old1")
-- data was not corrupted
assert(debug.getuservalue(U).x[1] == 234)
end
-- just to make sure
assert(collectgarbage'isrunning')
collectgarbage(oldmode)
print('OK')