summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2025-05-15 14:47:07 +0200
committerAndy Wingo <wingo@pobox.com>2025-05-15 14:47:07 +0200
commitb97b12a19bd2715c99a7f9bcfc31fbcdb93fddc9 (patch)
tree353be3582f195b47fe5d437e080a1256486f4dde
parentf5a1d2ca33ef23066547c68602ae9b64890f1afe (diff)
parent08e6633f93803300e6700247f9a698ee423596dc (diff)
downloadguile-b97b12a19bd2715c99a7f9bcfc31fbcdb93fddc9.tar.gz
Merge remote-tracking branch 'whippet/main' into wip-whippet
-rw-r--r--libguile/whippet/api/gc-embedder-api.h19
-rw-r--r--libguile/whippet/benchmarks/simple-gc-embedder.h20
-rw-r--r--libguile/whippet/src/bdw.c23
-rw-r--r--libguile/whippet/src/mmc.c19
-rw-r--r--libguile/whippet/src/root.h16
5 files changed, 93 insertions, 4 deletions
diff --git a/libguile/whippet/api/gc-embedder-api.h b/libguile/whippet/api/gc-embedder-api.h
index c1b272a51..28a0fb6de 100644
--- a/libguile/whippet/api/gc-embedder-api.h
+++ b/libguile/whippet/api/gc-embedder-api.h
@@ -50,6 +50,25 @@ GC_EMBEDDER_API inline void gc_trace_heap_roots(struct gc_heap_roots *roots,
struct gc_heap *heap,
void *trace_data);
+GC_EMBEDDER_API inline void
+gc_trace_mutator_conservative_roots(struct gc_mutator_roots *roots,
+ void (*trace_range)(uintptr_t start,
+ uintptr_t end,
+ int possibly_interior,
+ struct gc_heap *heap,
+ void *data),
+ struct gc_heap *heap,
+ void *data);
+GC_EMBEDDER_API inline void
+gc_trace_heap_conservative_roots(struct gc_heap_roots *roots,
+ void (*trace_range)(uintptr_t start,
+ uintptr_t end,
+ int possibly_interior,
+ struct gc_heap *heap,
+ void *data),
+ struct gc_heap *heap,
+ void *data);
+
GC_EMBEDDER_API inline uintptr_t gc_object_forwarded_nonatomic(struct gc_ref ref);
GC_EMBEDDER_API inline void gc_object_forward_nonatomic(struct gc_ref ref,
struct gc_ref new_ref);
diff --git a/libguile/whippet/benchmarks/simple-gc-embedder.h b/libguile/whippet/benchmarks/simple-gc-embedder.h
index 904d2c740..6f329573b 100644
--- a/libguile/whippet/benchmarks/simple-gc-embedder.h
+++ b/libguile/whippet/benchmarks/simple-gc-embedder.h
@@ -92,6 +92,26 @@ static inline void gc_trace_heap_roots(struct gc_heap_roots *roots,
visit_roots(roots->roots, trace_edge, heap, trace_data);
}
+static inline void
+gc_trace_mutator_conservative_roots(struct gc_mutator_roots *roots,
+ void (*trace_range)(uintptr_t start,
+ uintptr_t end,
+ int possibly_interior,
+ struct gc_heap *heap,
+ void *data),
+ struct gc_heap *heap,
+ void *data) {}
+
+static inline void
+gc_trace_heap_conservative_roots(struct gc_heap_roots *roots,
+ void (*trace_range)(uintptr_t start,
+ uintptr_t end,
+ int possibly_interior,
+ struct gc_heap *heap,
+ void *data),
+ struct gc_heap *heap,
+ void *data) {}
+
static inline uintptr_t gc_object_forwarded_nonatomic(struct gc_ref ref) {
uintptr_t tag = *tag_word(ref);
return (tag & gcobj_not_forwarded_bit) ? 0 : tag;
diff --git a/libguile/whippet/src/bdw.c b/libguile/whippet/src/bdw.c
index 8419df46e..fa06f7256 100644
--- a/libguile/whippet/src/bdw.c
+++ b/libguile/whippet/src/bdw.c
@@ -228,6 +228,20 @@ static void bdw_mark_edge(struct gc_edge edge, struct gc_heap *heap,
NULL);
}
+static void bdw_mark_range(uintptr_t lo, uintptr_t hi, int possibly_interior,
+ struct gc_heap *heap, void *visit_data) {
+ struct bdw_mark_state *state = visit_data;
+
+ GC_ASSERT_EQ (lo, align_up (lo, sizeof(void*)));
+ GC_ASSERT_EQ (hi, align_up (hi, sizeof(void*)));
+
+ for (void **walk = (void**)lo, **end = (void**)hi; walk < end; walk++)
+ state->mark_stack_ptr = GC_MARK_AND_PUSH (*walk,
+ state->mark_stack_ptr,
+ state->mark_stack_limit,
+ NULL);
+}
+
static int heap_gc_kind;
static int mutator_gc_kind;
static int ephemeron_gc_kind;
@@ -380,8 +394,10 @@ mark_heap(GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
if (heap != __the_bdw_gc_heap)
return state.mark_stack_ptr;
- if (heap->roots)
+ if (heap->roots) {
+ gc_trace_heap_conservative_roots(heap->roots, bdw_mark_range, heap, &state);
gc_trace_heap_roots(heap->roots, bdw_mark_edge, heap, &state);
+ }
gc_visit_finalizer_roots(heap->finalizer_state, bdw_mark_edge, heap, &state);
@@ -415,8 +431,11 @@ mark_mutator(GC_word *addr, struct GC_ms_entry *mark_stack_ptr,
memset(mut->freelists, 0, sizeof(void*) * GC_INLINE_FREELIST_COUNT);
- if (mut->roots)
+ if (mut->roots) {
+ gc_trace_mutator_conservative_roots(mut->roots, bdw_mark_range,
+ mut->heap, &state);
gc_trace_mutator_roots(mut->roots, bdw_mark_edge, mut->heap, &state);
+ }
state.mark_stack_ptr = GC_MARK_AND_PUSH (mut->next,
state.mark_stack_ptr,
diff --git a/libguile/whippet/src/mmc.c b/libguile/whippet/src/mmc.c
index ab0b9f54a..4e79675cc 100644
--- a/libguile/whippet/src/mmc.c
+++ b/libguile/whippet/src/mmc.c
@@ -328,7 +328,8 @@ load_conservative_ref(uintptr_t addr) {
static inline void
trace_conservative_edges(uintptr_t low, uintptr_t high, int possibly_interior,
- struct gc_heap *heap, struct gc_trace_worker *worker) {
+ struct gc_heap *heap, void *data) {
+ struct gc_trace_worker *worker = 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))
@@ -402,6 +403,14 @@ trace_root(struct gc_root root, struct gc_heap *heap,
gc_field_set_visit_edge_buffer(&heap->remembered_set, root.edge_buffer,
trace_remembered_edge, heap, worker);
break;
+ case GC_ROOT_KIND_HEAP_CONSERVATIVE_ROOTS:
+ gc_trace_heap_conservative_roots(root.heap->roots, trace_conservative_edges,
+ heap, worker);
+ break;
+ case GC_ROOT_KIND_MUTATOR_CONSERVATIVE_ROOTS:
+ gc_trace_mutator_conservative_roots(root.mutator->roots,
+ trace_conservative_edges, heap, worker);
+ break;
default:
GC_CRASH();
}
@@ -639,9 +648,13 @@ enqueue_mutator_conservative_roots(struct gc_heap *heap) {
int possibly_interior = gc_mutator_conservative_roots_may_be_interior();
for (struct gc_mutator *mut = heap->mutators;
mut;
- mut = mut->next)
+ mut = mut->next) {
gc_stack_visit(&mut->stack, enqueue_conservative_roots, heap,
&possibly_interior);
+ if (mut->roots)
+ gc_tracer_add_root(&heap->tracer,
+ gc_root_mutator_conservative_roots(mut));
+ }
return 1;
}
return 0;
@@ -653,6 +666,8 @@ enqueue_global_conservative_roots(struct gc_heap *heap) {
int possibly_interior = 0;
gc_platform_visit_global_conservative_roots
(enqueue_conservative_roots, heap, &possibly_interior);
+ if (heap->roots)
+ gc_tracer_add_root(&heap->tracer, gc_root_heap_conservative_roots(heap));
return 1;
}
return 0;
diff --git a/libguile/whippet/src/root.h b/libguile/whippet/src/root.h
index 4fc705e61..597e8d840 100644
--- a/libguile/whippet/src/root.h
+++ b/libguile/whippet/src/root.h
@@ -18,6 +18,8 @@ enum gc_root_kind {
GC_ROOT_KIND_RESOLVED_EPHEMERONS,
GC_ROOT_KIND_EDGE,
GC_ROOT_KIND_EDGE_BUFFER,
+ GC_ROOT_KIND_HEAP_CONSERVATIVE_ROOTS,
+ GC_ROOT_KIND_MUTATOR_CONSERVATIVE_ROOTS,
};
struct gc_root {
@@ -78,4 +80,18 @@ gc_root_edge_buffer(struct gc_edge_buffer *buf) {
return ret;
}
+static inline struct gc_root
+gc_root_heap_conservative_roots(struct gc_heap* heap) {
+ struct gc_root ret = { GC_ROOT_KIND_HEAP_CONSERVATIVE_ROOTS };
+ ret.heap = heap;
+ return ret;
+}
+
+static inline struct gc_root
+gc_root_mutator_conservative_roots(struct gc_mutator* mutator) {
+ struct gc_root ret = { GC_ROOT_KIND_MUTATOR_CONSERVATIVE_ROOTS };
+ ret.mutator = mutator;
+ return ret;
+}
+
#endif // ROOT_H