1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

Factor out tracer interface to own file

This commit is contained in:
Andy Wingo 2024-07-08 14:38:15 +02:00
parent 82afee8693
commit b4543ad641
3 changed files with 70 additions and 35 deletions

View file

@ -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);

View file

@ -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);

68
src/tracer.h Normal file
View file

@ -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