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