lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


>>>>> "Andrew" == Andrew Gierth <andrew@tao11.riddles.org.uk> writes:

 Andrew> Doesn't need the loop; just doing require 're';
 Andrew> collectgarbage(); triggers it for me.

So it looks like a bug in generational GC.

What I've found so far is that the states of the "marked" flags of
object U (the userdata) and T (the table stored in the uservalue)
change like this, starting from the creation of T:

T: luaC_newobj: (undef) -> 00010000 (WHITE1 | G_NEW)
T: luaH_getn: 00010000 (WHITE1 | G_NEW) -> 10010000 (RAS | WHITE1 | G_NEW)
U: luaC_barrierback_: 01100100 (FINALIZED | BLACK | G_OLD) -> 01000100 (FINALIZED | G_OLD)
U: luaC_barrierback_: 01000100 (FINALIZED | G_OLD) -> 01000101 (FINALIZED | G_TOUCHED1)
U: propagatemark: 01000101 (FINALIZED | G_TOUCHED1) -> 01100101 (FINALIZED | BLACK | G_TOUCHED1)
T: reallymarkobject: 10010000 (RAS | WHITE1 | G_NEW) -> 10000000 (RAS | G_NEW)
T: propagatemark: 10000000 (RAS | G_NEW) -> 10100000 (RAS | BLACK | G_NEW)
T: traversestrongtable: 10100000 (RAS | BLACK | G_NEW) -> 10000000 (RAS | G_NEW)
T: sweepgen: 10000000 (RAS | G_NEW) -> 10001000 (RAS | WHITE0 | G_NEW)
T: sweepgen: 10001000 (RAS | WHITE0 | G_NEW) -> 10001001 (RAS | WHITE0 | G_SURVIVAL)

and at this point, U (marked black) points at T (marked white), and T
gets freed shortly after without any further changes to either object's
"marked" field.

So unless I'm missing something, the problem here is that the userdata
and its uservalue entries are being treated differently than a strong
table would have been: the strong table is marked grayagain after
traversing if gckind == KGC_GEN, but the userdata remains black after
traversing its uservalue entries. Surely the logic should be the same
for both cases, since both are strong references?

-- 
Andrew.