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

commit cd54bbc627bebd85af69421c7283968c3f5e2927
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Thu Jul 3 10:13:20 2025 +0200

    nofl: Pin untagged pointerless allocations
    
    This was the case before, but I forgot why and removed it :/
---
 api/mmc-attrs.h  |  4 +++-
 src/mmc.c        |  6 ++----
 src/nofl-space.h | 13 ++++++++++---
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/api/mmc-attrs.h b/api/mmc-attrs.h
index 116c64036..a9fdcc844 100644
--- a/api/mmc-attrs.h
+++ b/api/mmc-attrs.h
@@ -35,6 +35,7 @@ static inline uint8_t 
gc_allocator_alloc_table_begin_pattern(enum gc_allocation_
   uint8_t trace_precisely = 0;
   uint8_t trace_none = 8;
   uint8_t trace_conservatively = 16;
+  uint8_t pinned = 16;
   switch (kind) {
   case GC_ALLOCATION_TAGGED:
     return young | trace_precisely;
@@ -43,8 +44,9 @@ static inline uint8_t 
gc_allocator_alloc_table_begin_pattern(enum gc_allocation_
       GC_CRASH ();
     return young | trace_conservatively;
   case GC_ALLOCATION_TAGGED_POINTERLESS:
-  case GC_ALLOCATION_UNTAGGED_POINTERLESS:
     return young | trace_none;
+  case GC_ALLOCATION_UNTAGGED_POINTERLESS:
+    return young | trace_none | pinned;
   default:
     GC_CRASH();
   }
diff --git a/src/mmc.c b/src/mmc.c
index 9b9b00046..65d076b06 100644
--- a/src/mmc.c
+++ b/src/mmc.c
@@ -617,7 +617,7 @@ grow_heap_if_necessary(struct gc_heap *heap,
   // If we cannot defragment and are making no progress but have a
   // growable heap, expand by 25% to add some headroom.
   size_t needed_headroom =
-    GC_CONSERVATIVE_TRACE
+    nofl_space_heap_has_ambiguous_edges (nofl)
     ? (progress ? 0 : nofl_active_block_count (nofl) * NOFL_BLOCK_SIZE / 4)
     : 0;
   size_t headroom = nofl_empty_block_count(nofl) * NOFL_BLOCK_SIZE;
@@ -1031,8 +1031,6 @@ compute_trace_kind(enum gc_allocation_kind kind) {
   case GC_ALLOCATION_TAGGED:
     return GC_TRACE_PRECISELY;
   case GC_ALLOCATION_UNTAGGED_CONSERVATIVE:
-    if (!GC_CONSERVATIVE_TRACE)
-      GC_CRASH ();
     return GC_TRACE_CONSERVATIVELY;
   case GC_ALLOCATION_TAGGED_POINTERLESS:
   case GC_ALLOCATION_UNTAGGED_POINTERLESS:
@@ -1359,7 +1357,7 @@ gc_init(const struct gc_options *options, struct 
gc_stack_addr stack_base,
     
GC_ASSERT_EQ(gc_allocator_alloc_table_begin_pattern(GC_ALLOCATION_UNTAGGED_CONSERVATIVE),
                  NOFL_METADATA_BYTE_YOUNG | 
NOFL_METADATA_BYTE_TRACE_CONSERVATIVELY);
   
GC_ASSERT_EQ(gc_allocator_alloc_table_begin_pattern(GC_ALLOCATION_UNTAGGED_POINTERLESS),
-               NOFL_METADATA_BYTE_YOUNG | NOFL_METADATA_BYTE_TRACE_NONE);
+               NOFL_METADATA_BYTE_YOUNG | NOFL_METADATA_BYTE_TRACE_NONE | 
NOFL_METADATA_BYTE_PINNED);
   GC_ASSERT_EQ(gc_allocator_alloc_table_end_pattern(), NOFL_METADATA_BYTE_END);
   if (GC_GENERATIONAL) {
     GC_ASSERT_EQ(gc_write_barrier_field_table_alignment(), NOFL_SLAB_SIZE);
diff --git a/src/nofl-space.h b/src/nofl-space.h
index ce62c17d3..d9a3fd99a 100644
--- a/src/nofl-space.h
+++ b/src/nofl-space.h
@@ -1357,12 +1357,19 @@ nofl_metadata_byte_trace_kind(struct nofl_space *space, 
uint8_t byte)
   switch (byte & mask) {
   case NOFL_METADATA_BYTE_TRACE_PRECISELY:
     return GC_TRACE_PRECISELY;
-  case NOFL_METADATA_BYTE_TRACE_NONE:
-    return GC_TRACE_NONE;
   case NOFL_METADATA_BYTE_TRACE_CONSERVATIVELY:
     return GC_TRACE_CONSERVATIVELY;
+  case NOFL_METADATA_BYTE_TRACE_NONE:
+    return GC_TRACE_NONE;
   default:
-    GC_CRASH();
+    /* Untagged pointerless objects are allocated with the PINNED bit,
+       because we can't relocate them, because we don't have a tag word
+       to hold the forwarding state.  Fortunately, this bit pattern is
+       different from NOFL_METADATA_BYTE_TRACE_CONSERVATIVELY; we can
+       just leave it as-is.  */
+    GC_ASSERT_EQ (byte & mask,
+                  NOFL_METADATA_BYTE_TRACE_NONE | NOFL_METADATA_BYTE_PINNED);
+    return GC_TRACE_NONE;
   }
 }
 

Reply via email to