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 ++++++- lstrlib.c | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) 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)); } diff --git a/lstrlib.c b/lstrlib.c index 321d6a0b..306cd0bf 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -1544,8 +1544,10 @@ static KOption getdetails (Header *h, size_t totalsize, const char **fmt, else { if (align > h->maxalign) /* enforce maximum alignment */ align = h->maxalign; - if (l_unlikely(!ispow2(align))) /* not a power of 2? */ + if (l_unlikely(!ispow2(align))) { /* not a power of 2? */ + *ntoalign = 0; /* to avoid warnings */ luaL_argerror(h->L, 1, "format asks for alignment not power of 2"); + } else { /* 'szmoda' = totalsize % align */ unsigned szmoda = cast_uint(totalsize & (align - 1)); -- cgit v1.2.3-55-g6feb