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

commit d560676572eb83736ae265ba41213936f7fb9c26
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Thu May 15 15:15:28 2025 +0200

    Wire loader DT_GUILE_GC_ROOT sections to Whippet API
    
    * libguile/loader.c (add_roots):
    (scm_trace_loader_conservative_roots):
    (process_dynamic_segment): Use Whippet API to register roots.
    * libguile/trace.h (struct gc_heap_roots): Define here.
    * libguile/whippet-embedder.h (gc_trace_mutator_conservative_roots):
    (gc_trace_heap_conservative_roots): Add definitions.
---
 libguile/gc.c               |  6 ++++++
 libguile/loader.c           | 42 ++++++++++++++++++++++++++++++++++++++++--
 libguile/trace.h            | 10 ++++++++++
 libguile/whippet-embedder.h | 25 +++++++++++++++++++++++++
 4 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/libguile/gc.c b/libguile/gc.c
index 42c93cfc3..289adf3f1 100644
--- a/libguile/gc.c
+++ b/libguile/gc.c
@@ -53,6 +53,7 @@
 #include "strings.h"
 #include "struct.h"
 #include "symbols.h"
+#include "trace.h"
 #include "vectors.h"
 
 #include "gc.h"
@@ -634,6 +635,7 @@ scm_gc_unregister_roots (SCM *b, unsigned long n)
 
 
 
+static struct gc_heap_roots heap_roots;
 
 struct gc_mutator *
 scm_storage_prehistory (struct gc_stack_addr base)
@@ -661,6 +663,10 @@ scm_storage_prehistory (struct gc_stack_addr base)
       abort ();
     }
 
+  // We need to set roots so that scm_trace_loader_conservative_roots
+  // gets called.
+  gc_heap_set_roots(the_gc_heap, &heap_roots);
+
   /* Sanity check.  */
   if (!GC_is_visible (&scm_protects))
     abort ();
diff --git a/libguile/loader.c b/libguile/loader.c
index 09bd166ec..bd91601b6 100644
--- a/libguile/loader.c
+++ b/libguile/loader.c
@@ -37,18 +37,19 @@
 #include <sys/mman.h>
 #endif
 
-#include "bdw-gc.h"
 #include "boolean.h"
 #include "bytevectors.h"
 #include "elf.h"
 #include "eval.h"
 #include "extensions.h"
 #include "gsubr.h"
+#include "gc-internal.h"
 #include "list.h"
 #include "pairs.h"
 #include "programs.h"
 #include "strings.h"
 #include "threads.h"
+#include "trace.h"
 #include "version.h"
 
 #include "loader.h"
@@ -93,6 +94,43 @@
 #define ELFDATA ELFDATA2LSB
 #endif
 
+static scm_i_pthread_mutex_t roots_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
+static size_t roots_count = 0;
+static size_t roots_capacity = 0;
+struct loader_roots { uintptr_t lo, hi; };
+static struct loader_roots *roots;
+
+static void
+add_roots(char *lo, char *hi)
+{
+  scm_i_pthread_mutex_lock (&roots_lock);
+  if (roots_count == roots_capacity)
+    {
+      roots_capacity = roots_capacity * 2 + 128;
+      size_t elt_size = sizeof(*roots);
+      struct loader_roots *new_roots = calloc (roots_capacity, elt_size);
+      // Leak the old roots; we're still O(n) as all previous root
+      // arrays sum to less than the new roots_capacity.
+      memcpy (new_roots, roots, roots_count * elt_size);
+      roots = new_roots;
+    }
+  roots[roots_count++] = (struct loader_roots){ (uintptr_t)lo, (uintptr_t)hi };
+  scm_i_pthread_mutex_unlock (&roots_lock);
+}
+
+void
+scm_trace_loader_conservative_roots (void (*trace_range)(uintptr_t lo,
+                                                         uintptr_t hi,
+                                                         int possibly_interior,
+                                                         struct gc_heap *heap,
+                                                         void *trace_data),
+                                     struct gc_heap *heap,
+                                     void *trace_data) 
+{
+  for (size_t i = 0; i < roots_count; i++)
+    trace_range(roots[i].lo, roots[i].hi, 0, heap, trace_data);
+}
+
 /* The page size.  */
 static size_t page_size;
 
@@ -345,7 +383,7 @@ process_dynamic_segment (char *base, Elf_Phdr *dyn_phdr,
     }
 
   if (gc_root)
-    GC_add_roots (gc_root, gc_root + gc_root_size);
+    add_roots (gc_root, gc_root + gc_root_size);
 
   *init_out = init ? pointer_to_procedure (bytecode_kind, init) : SCM_BOOL_F;
   *entry_out = pointer_to_procedure (bytecode_kind, entry);
diff --git a/libguile/trace.h b/libguile/trace.h
index e05050470..d2705c112 100644
--- a/libguile/trace.h
+++ b/libguile/trace.h
@@ -29,6 +29,7 @@
 struct scm_thread;
 struct scm_vm;
 struct gc_heap;
+struct gc_heap_roots { int unused; };
 
 SCM_INTERNAL void
 scm_trace_thread_mutator_roots (struct scm_thread *thread,
@@ -52,5 +53,14 @@ SCM_INTERNAL void scm_trace_vm (struct scm_vm *vp,
                                 struct gc_heap *heap,
                                 void *trace_data);
 
+SCM_INTERNAL void
+scm_trace_loader_conservative_roots (void (*trace_range)(uintptr_t lo,
+                                                         uintptr_t hi,
+                                                         int possibly_interior,
+                                                         struct gc_heap *heap,
+                                                         void *trace_data),
+                                     struct gc_heap *heap,
+                                     void *trace_data);
+
 
 #endif  /* SCM_THREADS_INTERNAL_H */
diff --git a/libguile/whippet-embedder.h b/libguile/whippet-embedder.h
index aa82eb4f1..82e177936 100644
--- a/libguile/whippet-embedder.h
+++ b/libguile/whippet-embedder.h
@@ -109,6 +109,31 @@ static inline void gc_trace_heap_roots (struct 
gc_heap_roots *roots,
                                         void *trace_data) {
 }
 
+static inline void
+gc_trace_mutator_conservative_roots (struct gc_mutator_roots *roots,
+                                     void (*trace_range) (uintptr_t lo,
+                                                          uintptr_t hi,
+                                                          int 
possibly_interior,
+                                                          struct gc_heap *heap,
+                                                          void *trace_data),
+                                     struct gc_heap *heap,
+                                     void *trace_data) {
+  /* FIXME: thread stack?  Currently traced via the precise
+     gc_trace_mutator_roots.  */
+}
+
+static inline void
+gc_trace_heap_conservative_roots (struct gc_heap_roots *roots,
+                                  void (*trace_range) (uintptr_t lo,
+                                                       uintptr_t hi,
+                                                       int possibly_interior,
+                                                       struct gc_heap *heap,
+                                                       void *trace_data),
+                                  struct gc_heap *heap,
+                                  void *trace_data) {
+  scm_trace_loader_conservative_roots(trace_range, heap, trace_data);
+}
+
 static inline SCM scm_from_gc_ref (struct gc_ref ref) {
   return SCM_PACK (gc_ref_value (ref));
 }

Reply via email to