Browse Source

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.
Roberto Ierusalimschy 3 months ago
parent
commit
3dbb1a4b89
2 changed files with 9 additions and 2 deletions
  1. 6 1
      lgc.c
  2. 3 1
      lstrlib.c

+ 6 - 1
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));
 }
 
 

+ 3 - 1
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));