wingo pushed a commit to branch wip-whippet
in repository guile.

commit da4f1ec806309bc40d051b8ff00bccf86e099f1d
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Fri Oct 4 13:51:49 2024 +0200

    Fix bug in which head byte's logged bits were not cleared
---
 src/nofl-space.h | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/nofl-space.h b/src/nofl-space.h
index a6e2b2b13..01f446ad7 100644
--- a/src/nofl-space.h
+++ b/src/nofl-space.h
@@ -1442,8 +1442,9 @@ nofl_space_pin_object(struct nofl_space *space, struct 
gc_ref ref) {
                                                   memory_order_acquire));
 }
 
-static inline void
-clear_logged_bits_in_evacuated_object(uint8_t *metadata, size_t count) {
+static inline uint8_t
+clear_logged_bits_in_evacuated_object(uint8_t head, uint8_t *metadata,
+                                      size_t count) {
   // On a major collection, it could be that we evacuate an object that
   // has one or more fields in the old-to-new remembered set.  Because
   // the young generation is empty after a major collection, we know the
@@ -1461,10 +1462,11 @@ clear_logged_bits_in_evacuated_object(uint8_t 
*metadata, size_t count) {
   // never evacuate an object in the remembered set, because old objects
   // aren't traced during a minor collection.
   uint8_t mask = NOFL_METADATA_BYTE_LOGGED_0 | NOFL_METADATA_BYTE_LOGGED_1;
-  for (size_t i = 0; i < count; i++) {
+  for (size_t i = 1; i < count; i++) {
     if (metadata[i] & mask)
       metadata[i] &= ~mask;
   }    
+  return head & ~mask;
 }
 
 static inline int
@@ -1500,7 +1502,8 @@ nofl_space_evacuate(struct nofl_space *space, uint8_t 
*metadata, uint8_t byte,
       uint8_t *new_metadata = nofl_metadata_byte_for_object(new_ref);
       memcpy(new_metadata + 1, metadata + 1, object_granules - 1);
       if (GC_GENERATIONAL)
-        clear_logged_bits_in_evacuated_object(new_metadata, object_granules);
+        byte = clear_logged_bits_in_evacuated_object(byte, new_metadata,
+                                                     object_granules);
       gc_edge_update(edge, new_ref);
       return nofl_space_set_nonempty_mark(space, new_metadata, byte,
                                           new_ref);

Reply via email to