1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-15 16:20:17 +02:00

Fix bug in which head byte's logged bits were not cleared

This commit is contained in:
Andy Wingo 2024-10-04 13:51:49 +02:00
parent b4ea55b9c4
commit da4f1ec806

View file

@ -1442,8 +1442,9 @@ nofl_space_pin_object(struct nofl_space *space, struct gc_ref ref) {
memory_order_acquire)); memory_order_acquire));
} }
static inline void static inline uint8_t
clear_logged_bits_in_evacuated_object(uint8_t *metadata, size_t count) { 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 // 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 // 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 // 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 // never evacuate an object in the remembered set, because old objects
// aren't traced during a minor collection. // aren't traced during a minor collection.
uint8_t mask = NOFL_METADATA_BYTE_LOGGED_0 | NOFL_METADATA_BYTE_LOGGED_1; 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) if (metadata[i] & mask)
metadata[i] &= ~mask; metadata[i] &= ~mask;
} }
return head & ~mask;
} }
static inline int 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); uint8_t *new_metadata = nofl_metadata_byte_for_object(new_ref);
memcpy(new_metadata + 1, metadata + 1, object_granules - 1); memcpy(new_metadata + 1, metadata + 1, object_granules - 1);
if (GC_GENERATIONAL) 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); gc_edge_update(edge, new_ref);
return nofl_space_set_nonempty_mark(space, new_metadata, byte, return nofl_space_set_nonempty_mark(space, new_metadata, byte,
new_ref); new_ref);