From 0dc5deca1c0182a4a3db2fcfd7bc721f27fb352b Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 29 Jul 2020 17:05:47 -0300 Subject: Optimization in 'markold' OLD1 objects can be potentially anywhere in the 'allgc' list (up to 'reallyold'), but frequently they are all after 'old1' (natural evolution of survivals) or do not exist at all (when all objects die young). So, instead of 'markold' starts looking for them always from the start of 'allgc', the collector keeps an extra pointer, 'firstold1', that points to the first OLD1 object in the 'allgc' list, or is NULL if there are no OLD1 objects in that list. --- testes/gengc.lua | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'testes') diff --git a/testes/gengc.lua b/testes/gengc.lua index 7a7dabdd..93b5afd7 100644 --- a/testes/gengc.lua +++ b/testes/gengc.lua @@ -37,6 +37,22 @@ do end +do + -- ensure that 'firstold1' is corrected when object is removed from + -- the 'allgc' list + local function foo () end + local old = {10} + collectgarbage() -- make 'old' old + assert(not T or T.gcage(old) == "old") + setmetatable(old, {}) -- new table becomes OLD0 (barrier) + assert(not T or T.gcage(getmetatable(old)) == "old0") + collectgarbage("step", 0) -- new table becomes OLD1 and firstold1 + assert(not T or T.gcage(getmetatable(old)) == "old1") + setmetatable(getmetatable(old), {__gc = foo}) -- get it out of allgc list + collectgarbage("step", 0) -- should not seg. fault +end + + do -- bug in 5.4.0 -- When an object aged OLD1 is finalized, it is moved from the list -- 'finobj' to the *beginning* of the list 'allgc', but that part of the -- cgit v1.2.3-55-g6feb