mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 11:50:28 +02:00
Factor out tracer interface to own file
This commit is contained in:
parent
82afee8693
commit
b4543ad641
3 changed files with 70 additions and 35 deletions
|
@ -12,6 +12,7 @@
|
||||||
#include "local-worklist.h"
|
#include "local-worklist.h"
|
||||||
#include "shared-worklist.h"
|
#include "shared-worklist.h"
|
||||||
#include "spin.h"
|
#include "spin.h"
|
||||||
|
#include "tracer.h"
|
||||||
|
|
||||||
enum trace_worker_state {
|
enum trace_worker_state {
|
||||||
TRACE_WORKER_STOPPED,
|
TRACE_WORKER_STOPPED,
|
||||||
|
@ -49,9 +50,6 @@ struct local_tracer {
|
||||||
struct local_worklist local;
|
struct local_worklist local;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct context;
|
|
||||||
static inline struct tracer* heap_tracer(struct gc_heap *heap);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
trace_worker_init(struct trace_worker *worker, struct gc_heap *heap,
|
trace_worker_init(struct trace_worker *worker, struct gc_heap *heap,
|
||||||
struct tracer *tracer, size_t id) {
|
struct tracer *tracer, size_t id) {
|
||||||
|
@ -147,15 +145,6 @@ tracer_maybe_unpark_workers(struct tracer *tracer) {
|
||||||
tracer_unpark_all_workers(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
|
static inline void
|
||||||
tracer_share(struct local_tracer *trace) {
|
tracer_share(struct local_tracer *trace) {
|
||||||
DEBUG("tracer #%zu: sharing\n", trace->worker->id);
|
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);
|
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
|
static struct gc_ref
|
||||||
tracer_steal_from_worker(struct tracer *tracer, size_t id) {
|
tracer_steal_from_worker(struct tracer *tracer, size_t id) {
|
||||||
ASSERT(id < tracer->worker_count);
|
ASSERT(id < tracer->worker_count);
|
||||||
|
|
|
@ -7,14 +7,12 @@
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "simple-worklist.h"
|
#include "simple-worklist.h"
|
||||||
|
#include "tracer.h"
|
||||||
|
|
||||||
struct tracer {
|
struct tracer {
|
||||||
struct simple_worklist worklist;
|
struct simple_worklist worklist;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gc_heap;
|
|
||||||
static inline struct tracer* heap_tracer(struct gc_heap *heap);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
tracer_init(struct gc_heap *heap, size_t parallelism) {
|
tracer_init(struct gc_heap *heap, size_t parallelism) {
|
||||||
return simple_worklist_init(&heap_tracer(heap)->worklist);
|
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);
|
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
|
static inline void
|
||||||
tracer_enqueue_root(struct tracer *tracer, struct gc_ref obj) {
|
tracer_enqueue_root(struct tracer *tracer, struct gc_ref obj) {
|
||||||
simple_worklist_push(&tracer->worklist, 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);
|
tracer_enqueue_root(heap_tracer(heap), ref);
|
||||||
}
|
}
|
||||||
static inline void
|
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) {
|
tracer_trace(struct gc_heap *heap) {
|
||||||
do {
|
do {
|
||||||
struct gc_ref obj = simple_worklist_pop(&heap_tracer(heap)->worklist);
|
struct gc_ref obj = simple_worklist_pop(&heap_tracer(heap)->worklist);
|
||||||
|
|
68
src/tracer.h
Normal file
68
src/tracer.h
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue