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

commit b4543ad6418ac779c3c4f8d53db1ef05dd46240c
Author: Andy Wingo <wi...@igalia.com>
AuthorDate: Mon Jul 8 14:38:15 2024 +0200

    Factor out tracer interface to own file
---
 src/parallel-tracer.h | 19 +-------------
 src/serial-tracer.h   | 18 +-------------
 src/tracer.h          | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 35 deletions(-)

diff --git a/src/parallel-tracer.h b/src/parallel-tracer.h
index 18fd03899..9d04f264b 100644
--- a/src/parallel-tracer.h
+++ b/src/parallel-tracer.h
@@ -12,6 +12,7 @@
 #include "local-worklist.h"
 #include "shared-worklist.h"
 #include "spin.h"
+#include "tracer.h"
 
 enum trace_worker_state {
   TRACE_WORKER_STOPPED,
@@ -49,9 +50,6 @@ struct local_tracer {
   struct local_worklist local;
 };
 
-struct context;
-static inline struct tracer* heap_tracer(struct gc_heap *heap);
-
 static int
 trace_worker_init(struct trace_worker *worker, struct gc_heap *heap,
                  struct tracer *tracer, size_t id) {
@@ -147,15 +145,6 @@ tracer_maybe_unpark_workers(struct tracer *tracer) {
     tracer_unpark_all_workers(tracer);
 }
 
-static inline void tracer_visit(struct gc_edge edge, struct gc_heap *heap,
-                                void *trace_data) GC_ALWAYS_INLINE;
-static inline void tracer_enqueue(struct gc_ref ref, struct gc_heap *heap,
-                                  void *trace_data) GC_ALWAYS_INLINE;
-static inline void trace_one(struct gc_ref ref, struct gc_heap *heap,
-                             void *trace_data) GC_ALWAYS_INLINE;
-static inline int trace_edge(struct gc_heap *heap,
-                             struct gc_edge edge) GC_ALWAYS_INLINE;
-
 static inline void
 tracer_share(struct local_tracer *trace) {
   DEBUG("tracer #%zu: sharing\n", trace->worker->id);
@@ -177,12 +166,6 @@ tracer_enqueue(struct gc_ref ref, struct gc_heap *heap, 
void *trace_data) {
   local_worklist_push(&trace->local, ref);
 }
 
-static inline void
-tracer_visit(struct gc_edge edge, struct gc_heap *heap, void *trace_data) {
-  if (trace_edge(heap, edge))
-    tracer_enqueue(gc_edge_ref(edge), heap, trace_data);
-}
-
 static struct gc_ref
 tracer_steal_from_worker(struct tracer *tracer, size_t id) {
   ASSERT(id < tracer->worker_count);
diff --git a/src/serial-tracer.h b/src/serial-tracer.h
index 2246eb360..13aae60ce 100644
--- a/src/serial-tracer.h
+++ b/src/serial-tracer.h
@@ -7,14 +7,12 @@
 #include "assert.h"
 #include "debug.h"
 #include "simple-worklist.h"
+#include "tracer.h"
 
 struct tracer {
   struct simple_worklist worklist;
 };
 
-struct gc_heap;
-static inline struct tracer* heap_tracer(struct gc_heap *heap);
-
 static int
 tracer_init(struct gc_heap *heap, size_t parallelism) {
   return simple_worklist_init(&heap_tracer(heap)->worklist);
@@ -24,15 +22,6 @@ static void tracer_release(struct gc_heap *heap) {
   simple_worklist_release(&heap_tracer(heap)->worklist);
 }
 
-static inline void tracer_visit(struct gc_edge edge, struct gc_heap *heap,
-                                void *trace_data) GC_ALWAYS_INLINE;
-static inline void tracer_enqueue(struct gc_ref ref, struct gc_heap *heap,
-                                  void *trace_data) GC_ALWAYS_INLINE;
-static inline void trace_one(struct gc_ref ref, struct gc_heap *heap,
-                             void *trace_data) GC_ALWAYS_INLINE;
-static inline int trace_edge(struct gc_heap *heap,
-                             struct gc_edge edge) GC_ALWAYS_INLINE;
-
 static inline void
 tracer_enqueue_root(struct tracer *tracer, struct gc_ref obj) {
   simple_worklist_push(&tracer->worklist, obj);
@@ -47,11 +36,6 @@ tracer_enqueue(struct gc_ref ref, struct gc_heap *heap, void 
*trace_data) {
   tracer_enqueue_root(heap_tracer(heap), ref);
 }
 static inline void
-tracer_visit(struct gc_edge edge, struct gc_heap *heap, void *trace_data) {
-  if (trace_edge(heap, edge))
-    tracer_enqueue(gc_edge_ref(edge), heap, trace_data);
-}
-static inline void
 tracer_trace(struct gc_heap *heap) {
   do {
     struct gc_ref obj = simple_worklist_pop(&heap_tracer(heap)->worklist);
diff --git a/src/tracer.h b/src/tracer.h
new file mode 100644
index 000000000..15b37e0d4
--- /dev/null
+++ b/src/tracer.h
@@ -0,0 +1,68 @@
+#ifndef TRACER_H
+#define TRACER_H
+
+#include "gc-ref.h"
+#include "gc-edge.h"
+
+struct gc_heap;
+
+////////////////////////////////////////////////////////////////////////
+/// To be implemented by collector.
+////////////////////////////////////////////////////////////////////////
+
+// Initialize the tracer when the heap is created.
+static inline struct tracer* heap_tracer(struct gc_heap *heap);
+
+// Visit all fields in an object.
+static inline void trace_one(struct gc_ref ref, struct gc_heap *heap,
+                             void *trace_data) GC_ALWAYS_INLINE;
+
+// Visit one edge.  Return nonzero if this call shaded the object grey.
+static inline int trace_edge(struct gc_heap *heap,
+                             struct gc_edge edge) GC_ALWAYS_INLINE;
+
+////////////////////////////////////////////////////////////////////////
+/// To be implemented by tracer.
+////////////////////////////////////////////////////////////////////////
+
+// The tracer struct itself should be defined in the implementation.
+struct tracer;
+
+// Initialize the tracer when the heap is created.
+static int tracer_init(struct gc_heap *heap, size_t parallelism);
+
+// Initialize the tracer for a new GC cycle.
+static void tracer_prepare(struct gc_heap *heap);
+
+// Release any resources allocated during the trace.
+static void tracer_release(struct gc_heap *heap);
+
+// Add root objects to the trace.  Call before tracer_trace.
+static inline void tracer_enqueue_root(struct tracer *tracer,
+                                       struct gc_ref obj);
+static inline void tracer_enqueue_roots(struct tracer *tracer,
+                                        struct gc_ref *objs,
+                                        size_t count);
+
+// Given that an object has been shaded grey, enqueue for tracing.
+static inline void tracer_enqueue(struct gc_ref ref, struct gc_heap *heap,
+                                  void *trace_data) GC_ALWAYS_INLINE;
+
+// Run the full trace.
+static inline void tracer_trace(struct gc_heap *heap);
+
+////////////////////////////////////////////////////////////////////////
+/// Procedures that work with any tracer.
+////////////////////////////////////////////////////////////////////////
+
+// Visit one edge.  If we shade the edge target grey, enqueue it for
+// tracing.
+static inline void tracer_visit(struct gc_edge edge, struct gc_heap *heap,
+                                void *trace_data) GC_ALWAYS_INLINE;
+static inline void
+tracer_visit(struct gc_edge edge, struct gc_heap *heap, void *trace_data) {
+  if (trace_edge(heap, edge))
+    tracer_enqueue(gc_edge_ref(edge), heap, trace_data);
+}
+
+#endif // TRACER_H

Reply via email to