From 3dbb1a4b894c0744a331d4319d8d1704dc4ad943 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 15 Apr 2025 17:00:30 -0300 Subject: In gen. GC, some gray objects stay in gray lists In generational collection, objects marked as touched1 stay in gray lists between collections. This commit fixes a bug introduced in commit 808976bb59. --- lgc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'lgc.c') diff --git a/lgc.c b/lgc.c index cada07d9..c0d68377 100644 --- a/lgc.c +++ b/lgc.c @@ -465,6 +465,8 @@ static void restartcollection (global_State *g) { ** TOUCHED1 objects need to be in the list. TOUCHED2 doesn't need to go ** back to a gray list, but then it must become OLD. (That is what ** 'correctgraylist' does when it finds a TOUCHED2 object.) +** This function is a no-op in incremental mode, as objects cannot be +** marked as touched in that mode. */ static void genlink (global_State *g, GCObject *o) { lua_assert(isblack(o)); @@ -480,7 +482,8 @@ static void genlink (global_State *g, GCObject *o) { ** Traverse a table with weak values and link it to proper list. During ** propagate phase, keep it in 'grayagain' list, to be revisited in the ** atomic phase. In the atomic phase, if table has any white value, -** put it in 'weak' list, to be cleared. +** put it in 'weak' list, to be cleared; otherwise, call 'genlink' +** to check table age in generational mode. */ static void traverseweakvalue (global_State *g, Table *h) { Node *n, *limit = gnodelast(h); @@ -501,6 +504,8 @@ static void traverseweakvalue (global_State *g, Table *h) { linkgclist(h, g->grayagain); /* must retraverse it in atomic phase */ else if (hasclears) linkgclist(h, g->weak); /* has to be cleared later */ + else + genlink(g, obj2gco(h)); } -- cgit v1.2.3-55-g6feb