1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-16 18:50:23 +02:00

Pass heap to tracer functions

This will allow conservative intra-heap edges.  Hopefully no overhead?
This commit is contained in:
Andy Wingo 2022-10-25 14:25:55 +02:00
parent 5e986e84e9
commit 053dbf0b61
14 changed files with 141 additions and 74 deletions

View file

@ -710,8 +710,9 @@ static inline struct gc_ref trace_conservative_ref(struct gc_heap *heap,
ref, possibly_interior);
}
static inline void trace_one(struct gc_ref ref, void *mark_data) {
gc_trace_object(ref, tracer_visit, mark_data, NULL);
static inline void trace_one(struct gc_ref ref, struct gc_heap *heap,
void *mark_data) {
gc_trace_object(ref, tracer_visit, heap, mark_data, NULL);
}
static int heap_has_multiple_mutators(struct gc_heap *heap) {
@ -959,55 +960,60 @@ void gc_heap_set_roots(struct gc_heap *heap, struct gc_heap_roots *roots) {
heap->roots = roots;
}
static void trace_and_enqueue_locally(struct gc_edge edge, void *data) {
static void trace_and_enqueue_locally(struct gc_edge edge,
struct gc_heap *heap,
void *data) {
struct gc_mutator *mut = data;
if (trace_edge(mutator_heap(mut), edge))
if (trace_edge(heap, edge))
mutator_mark_buf_push(&mut->mark_buf, gc_edge_ref(edge));
}
static inline void do_trace_conservative_ref_and_enqueue_locally(struct gc_conservative_ref ref,
struct gc_heap *heap,
void *data,
int possibly_interior) {
struct gc_mutator *mut = data;
struct gc_ref object = trace_conservative_ref(mutator_heap(mut), ref,
possibly_interior);
struct gc_ref object = trace_conservative_ref(heap, ref, possibly_interior);
if (gc_ref_is_heap_object(object))
mutator_mark_buf_push(&mut->mark_buf, object);
}
static void trace_possibly_interior_conservative_ref_and_enqueue_locally
(struct gc_conservative_ref ref, void *data) {
return do_trace_conservative_ref_and_enqueue_locally(ref, data, 1);
(struct gc_conservative_ref ref, struct gc_heap *heap, void *data) {
return do_trace_conservative_ref_and_enqueue_locally(ref, heap, data, 1);
}
static void trace_conservative_ref_and_enqueue_locally
(struct gc_conservative_ref ref, void *data) {
return do_trace_conservative_ref_and_enqueue_locally(ref, data, 0);
(struct gc_conservative_ref ref, struct gc_heap *heap, void *data) {
return do_trace_conservative_ref_and_enqueue_locally(ref, heap, data, 0);
}
static void trace_and_enqueue_globally(struct gc_edge edge, void *data) {
struct gc_heap *heap = data;
static void trace_and_enqueue_globally(struct gc_edge edge,
struct gc_heap *heap,
void *unused) {
if (trace_edge(heap, edge))
tracer_enqueue_root(&heap->tracer, gc_edge_ref(edge));
}
static inline void do_trace_conservative_ref_and_enqueue_globally(struct gc_conservative_ref ref,
struct gc_heap *heap,
void *data,
int possibly_interior) {
struct gc_heap *heap = data;
struct gc_ref object = trace_conservative_ref(heap, ref, possibly_interior);
if (gc_ref_is_heap_object(object))
tracer_enqueue_root(&heap->tracer, object);
}
static void trace_possibly_interior_conservative_ref_and_enqueue_globally(struct gc_conservative_ref ref,
struct gc_heap *heap,
void *data) {
return do_trace_conservative_ref_and_enqueue_globally(ref, data, 1);
return do_trace_conservative_ref_and_enqueue_globally(ref, heap, data, 1);
}
static void trace_conservative_ref_and_enqueue_globally(struct gc_conservative_ref ref,
struct gc_heap *heap,
void *data) {
return do_trace_conservative_ref_and_enqueue_globally(ref, data, 0);
return do_trace_conservative_ref_and_enqueue_globally(ref, heap, data, 0);
}
static inline struct gc_conservative_ref
@ -1021,75 +1027,84 @@ load_conservative_ref(uintptr_t addr) {
static inline void
trace_conservative_edges(uintptr_t low,
uintptr_t high,
void (*trace)(struct gc_conservative_ref, void *),
void (*trace)(struct gc_conservative_ref,
struct gc_heap *, void *),
struct gc_heap *heap,
void *data) {
GC_ASSERT(low == align_down(low, sizeof(uintptr_t)));
GC_ASSERT(high == align_down(high, sizeof(uintptr_t)));
for (uintptr_t addr = low; addr < high; addr += sizeof(uintptr_t))
trace(load_conservative_ref(addr), data);
trace(load_conservative_ref(addr), heap, data);
}
static void
mark_and_globally_enqueue_mutator_conservative_roots(uintptr_t low,
uintptr_t high,
struct gc_heap *heap,
void *data) {
trace_conservative_edges(low, high,
gc_mutator_conservative_roots_may_be_interior()
? trace_possibly_interior_conservative_ref_and_enqueue_globally
: trace_conservative_ref_and_enqueue_globally,
data);
heap, data);
}
static void
mark_and_globally_enqueue_heap_conservative_roots(uintptr_t low,
uintptr_t high,
struct gc_heap *heap,
void *data) {
trace_conservative_edges(low, high,
trace_conservative_ref_and_enqueue_globally,
data);
heap, data);
}
static void
mark_and_locally_enqueue_mutator_conservative_roots(uintptr_t low,
uintptr_t high,
struct gc_heap *heap,
void *data) {
trace_conservative_edges(low, high,
gc_mutator_conservative_roots_may_be_interior()
? trace_possibly_interior_conservative_ref_and_enqueue_locally
: trace_conservative_ref_and_enqueue_locally,
data);
heap, data);
}
static inline void
trace_mutator_conservative_roots(struct gc_mutator *mut,
void (*trace_range)(uintptr_t low,
uintptr_t high,
struct gc_heap *heap,
void *data),
struct gc_heap *heap,
void *data) {
if (gc_has_mutator_conservative_roots())
gc_stack_visit(&mut->stack, trace_range, data);
gc_stack_visit(&mut->stack, trace_range, heap, data);
}
// Mark the roots of a mutator that is stopping for GC. We can't
// enqueue them directly, so we send them to the controller in a buffer.
static void trace_stopping_mutator_roots(struct gc_mutator *mut) {
GC_ASSERT(mutator_should_mark_while_stopping(mut));
struct gc_heap *heap = mutator_heap(mut);
trace_mutator_conservative_roots(mut,
mark_and_locally_enqueue_mutator_conservative_roots,
mut);
gc_trace_mutator_roots(mut->roots, trace_and_enqueue_locally, mut);
heap, mut);
gc_trace_mutator_roots(mut->roots, trace_and_enqueue_locally, heap, mut);
}
static void trace_mutator_conservative_roots_with_lock(struct gc_mutator *mut) {
trace_mutator_conservative_roots(mut,
mark_and_globally_enqueue_mutator_conservative_roots,
mutator_heap(mut));
mutator_heap(mut),
NULL);
}
static void trace_mutator_roots_with_lock(struct gc_mutator *mut) {
trace_mutator_conservative_roots_with_lock(mut);
gc_trace_mutator_roots(mut->roots, trace_and_enqueue_globally,
mutator_heap(mut));
mutator_heap(mut), NULL);
}
static void trace_mutator_roots_with_lock_before_stop(struct gc_mutator *mut) {
@ -1154,7 +1169,7 @@ static void trace_mutator_roots_after_stop(struct gc_heap *heap) {
static void trace_global_conservative_roots(struct gc_heap *heap) {
if (gc_has_global_conservative_roots())
gc_platform_visit_global_conservative_roots
(mark_and_globally_enqueue_heap_conservative_roots, heap);
(mark_and_globally_enqueue_heap_conservative_roots, heap, NULL);
}
static inline uint64_t load_eight_aligned_bytes(uint8_t *mark) {
@ -1601,7 +1616,7 @@ static void trace_pinned_roots_after_stop(struct gc_heap *heap) {
static void trace_roots_after_stop(struct gc_heap *heap) {
trace_mutator_roots_after_stop(heap);
gc_trace_heap_roots(heap->roots, trace_and_enqueue_globally, heap);
gc_trace_heap_roots(heap->roots, trace_and_enqueue_globally, heap, NULL);
trace_generational_roots(heap);
}