summaryrefslogtreecommitdiff
path: root/libguile/whippet
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/whippet')
-rw-r--r--libguile/whippet/api/gc-api.h24
-rw-r--r--libguile/whippet/api/gc-embedder-api.h19
-rw-r--r--libguile/whippet/benchmarks/ephemerons.c4
-rw-r--r--libguile/whippet/benchmarks/finalizers.c4
-rw-r--r--libguile/whippet/benchmarks/mt-gcbench.c4
-rw-r--r--libguile/whippet/benchmarks/simple-gc-embedder.h20
-rw-r--r--libguile/whippet/src/bdw.c69
-rw-r--r--libguile/whippet/src/mmc.c58
-rw-r--r--libguile/whippet/src/pcc.c42
-rw-r--r--libguile/whippet/src/root.h16
-rw-r--r--libguile/whippet/src/semi.c21
11 files changed, 256 insertions, 25 deletions
diff --git a/libguile/whippet/api/gc-api.h b/libguile/whippet/api/gc-api.h
index e34e0d57e..2ab063f8d 100644
--- a/libguile/whippet/api/gc-api.h
+++ b/libguile/whippet/api/gc-api.h
@@ -53,8 +53,14 @@ GC_API_ void gc_heap_set_extern_space(struct gc_heap *heap,
GC_API_ struct gc_mutator* gc_init_for_thread(struct gc_stack_addr base,
struct gc_heap *heap);
GC_API_ void gc_finish_for_thread(struct gc_mutator *mut);
-GC_API_ void* gc_call_without_gc(struct gc_mutator *mut, void* (*f)(void*),
- void *data) GC_NEVER_INLINE;
+GC_API_ void gc_deactivate(struct gc_mutator *mut);
+GC_API_ void gc_reactivate(struct gc_mutator *mut);
+GC_API_ void* gc_deactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator*, void*),
+ void *data);
+GC_API_ void* gc_reactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator*, void*),
+ void *data);
GC_API_ void gc_collect(struct gc_mutator *mut,
enum gc_collection_kind requested_kind);
@@ -301,4 +307,18 @@ static inline void gc_safepoint(struct gc_mutator *mut) {
gc_safepoint_slow(mut);
}
+GC_API_ int gc_safepoint_signal_number(void);
+GC_API_ void gc_safepoint_signal_inhibit(struct gc_mutator *mut);
+GC_API_ void gc_safepoint_signal_reallow(struct gc_mutator *mut);
+
+static inline void gc_inhibit_preemption(struct gc_mutator *mut) {
+ if (gc_safepoint_mechanism() == GC_SAFEPOINT_MECHANISM_SIGNAL)
+ gc_safepoint_signal_inhibit(mut);
+}
+
+static inline void gc_reallow_preemption(struct gc_mutator *mut) {
+ if (gc_safepoint_mechanism() == GC_SAFEPOINT_MECHANISM_SIGNAL)
+ gc_safepoint_signal_reallow(mut);
+}
+
#endif // GC_API_H_
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/ephemerons.c b/libguile/whippet/benchmarks/ephemerons.c
index c74db9d43..f0459dab4 100644
--- a/libguile/whippet/benchmarks/ephemerons.c
+++ b/libguile/whippet/benchmarks/ephemerons.c
@@ -183,7 +183,7 @@ static void* run_one_test_in_thread(void *arg) {
}
struct join_data { int status; pthread_t thread; };
-static void *join_thread(void *data) {
+static void *join_thread(struct gc_mutator *unused, void *data) {
struct join_data *join_data = data;
void *ret;
join_data->status = pthread_join(join_data->thread, &ret);
@@ -256,7 +256,7 @@ int main(int argc, char *argv[]) {
run_one_test(&main_thread);
for (size_t i = 1; i < nthreads; i++) {
struct join_data data = { 0, threads[i] };
- gc_call_without_gc(mut, join_thread, &data);
+ gc_deactivate_for_call(mut, join_thread, &data);
if (data.status) {
errno = data.status;
perror("Failed to join thread");
diff --git a/libguile/whippet/benchmarks/finalizers.c b/libguile/whippet/benchmarks/finalizers.c
index 79a2660c3..8d4b5c25a 100644
--- a/libguile/whippet/benchmarks/finalizers.c
+++ b/libguile/whippet/benchmarks/finalizers.c
@@ -190,7 +190,7 @@ static void* run_one_test_in_thread(void *arg) {
}
struct join_data { int status; pthread_t thread; };
-static void *join_thread(void *data) {
+static void *join_thread(struct gc_mutator *unused, void *data) {
struct join_data *join_data = data;
void *ret;
join_data->status = pthread_join(join_data->thread, &ret);
@@ -263,7 +263,7 @@ int main(int argc, char *argv[]) {
ssize_t outstanding = (size_t)run_one_test(&main_thread);
for (size_t i = 1; i < nthreads; i++) {
struct join_data data = { 0, threads[i] };
- void *ret = gc_call_without_gc(mut, join_thread, &data);
+ void *ret = gc_deactivate_for_call(mut, join_thread, &data);
if (data.status) {
errno = data.status;
perror("Failed to join thread");
diff --git a/libguile/whippet/benchmarks/mt-gcbench.c b/libguile/whippet/benchmarks/mt-gcbench.c
index 62fdc7154..e705702bb 100644
--- a/libguile/whippet/benchmarks/mt-gcbench.c
+++ b/libguile/whippet/benchmarks/mt-gcbench.c
@@ -319,7 +319,7 @@ static void* run_one_test_in_thread(void *arg) {
}
struct join_data { int status; pthread_t thread; };
-static void *join_thread(void *data) {
+static void *join_thread(struct gc_mutator *unused, void *data) {
struct join_data *join_data = data;
void *ret;
join_data->status = pthread_join(join_data->thread, &ret);
@@ -389,7 +389,7 @@ int main(int argc, char *argv[]) {
run_one_test(&main_thread);
for (size_t i = 1; i < nthreads; i++) {
struct join_data data = { 0, threads[i] };
- gc_call_without_gc(mut, join_thread, &data);
+ gc_deactivate_for_call(mut, join_thread, &data);
if (data.status) {
errno = data.status;
perror("Failed to join thread");
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 e6b3f4ef5..fc228c15e 100644
--- a/libguile/whippet/src/bdw.c
+++ b/libguile/whippet/src/bdw.c
@@ -203,6 +203,16 @@ void gc_write_barrier_slow(struct gc_mutator *mut, struct gc_ref obj,
int* gc_safepoint_flag_loc(struct gc_mutator *mut) { GC_CRASH(); }
void gc_safepoint_slow(struct gc_mutator *mut) { GC_CRASH(); }
+int gc_safepoint_signal_number(void) {
+ return GC_get_suspend_signal();
+}
+void gc_safepoint_signal_inhibit(struct gc_mutator *mut) {
+ GC_alloc_lock();
+}
+void gc_safepoint_signal_reallow(struct gc_mutator *mut) {
+ GC_alloc_unlock();
+}
+
struct bdw_mark_state {
struct GC_ms_entry *mark_stack_ptr;
struct GC_ms_entry *mark_stack_limit;
@@ -218,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;
@@ -370,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);
@@ -405,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,
@@ -529,6 +558,11 @@ static void* oom_fn(size_t nbytes) {
return NULL;
}
+static void warn_fn(char *fmt, GC_word arg) {
+ /* FIXME: Do something better with this. */
+ fprintf (stderr, fmt, arg);
+}
+
void gc_heap_set_allocation_failure_handler(struct gc_heap *heap,
void* (*handler)(struct gc_heap*,
size_t)) {
@@ -587,6 +621,7 @@ int gc_init(const struct gc_options *options, struct gc_stack_addr stack_base,
snprintf(markers, sizeof(markers), "%d", options->common.parallelism);
setenv("GC_MARKERS", markers, 1);
GC_init();
+ GC_set_warn_proc (warn_fn);
size_t current_heap_size = GC_get_heap_size();
if (options->common.heap_size > current_heap_size)
GC_expand_hp(options->common.heap_size - current_heap_size);
@@ -650,10 +685,32 @@ void gc_finish_for_thread(struct gc_mutator *mut) {
GC_unregister_my_thread();
}
-void* gc_call_without_gc(struct gc_mutator *mut,
- void* (*f)(void*),
- void *data) {
- return GC_do_blocking(f, data);
+struct call_with_mutator_data {
+ void* (*proc) (struct gc_mutator*, void*);
+ struct gc_mutator *mutator;
+ void *data;
+};
+
+static void* call_with_mutator (void *p) {
+ struct call_with_mutator_data *data = p;
+ return data->proc(data->mutator, data->data);
+}
+
+void gc_deactivate(struct gc_mutator *mut) {};
+void gc_reactivate(struct gc_mutator *mut) {};
+
+void* gc_deactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator *, void*),
+ void *data) {
+ struct call_with_mutator_data d = { f, mut, data };
+ return GC_do_blocking(call_with_mutator, &d);
+}
+
+void* gc_reactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator *, void*),
+ void *data) {
+ struct call_with_mutator_data d = { f, mut, data };
+ return GC_call_with_gc_active(call_with_mutator, &d);
}
void gc_mutator_set_roots(struct gc_mutator *mut,
diff --git a/libguile/whippet/src/mmc.c b/libguile/whippet/src/mmc.c
index 1ae342f5e..4e79675cc 100644
--- a/libguile/whippet/src/mmc.c
+++ b/libguile/whippet/src/mmc.c
@@ -88,6 +88,7 @@ struct gc_mutator {
void *event_listener_data;
struct gc_mutator *next;
struct gc_mutator *prev;
+ int active;
};
struct gc_trace_worker_data {
@@ -216,6 +217,7 @@ add_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
while (mutators_are_stopping(heap))
pthread_cond_wait(&heap->mutator_cond, &heap->lock);
mut->next = mut->prev = NULL;
+ mut->active = 1;
struct gc_mutator *tail = heap->mutators;
if (tail) {
mut->next = tail;
@@ -235,6 +237,7 @@ remove_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
mut->heap = NULL;
heap_lock(heap);
heap->mutator_count--;
+ mut->active = 0;
if (mut->next)
mut->next->prev = mut->prev;
if (mut->prev)
@@ -325,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))
@@ -399,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();
}
@@ -636,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;
@@ -650,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;
@@ -869,6 +887,10 @@ gc_safepoint_slow(struct gc_mutator *mut) {
heap_unlock(heap);
}
+int gc_safepoint_signal_number(void) { GC_CRASH(); }
+void gc_safepoint_signal_inhibit(struct gc_mutator *mut) { GC_CRASH(); }
+void gc_safepoint_signal_reallow(struct gc_mutator *mut) { GC_CRASH(); }
+
static enum gc_trace_kind
compute_trace_kind(enum gc_allocation_kind kind) {
if (GC_CONSERVATIVE_TRACE) {
@@ -1274,6 +1296,7 @@ deactivate_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
gc_field_set_writer_release_buffer(&mut->logger);
heap_lock(heap);
heap->inactive_mutator_count++;
+ mut->active = 0;
gc_stack_capture_hot(&mut->stack);
if (all_mutators_stopped(heap))
pthread_cond_signal(&heap->collector_cond);
@@ -1285,15 +1308,42 @@ reactivate_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
heap_lock(heap);
while (mutators_are_stopping(heap))
pthread_cond_wait(&heap->mutator_cond, &heap->lock);
+ mut->active = 1;
heap->inactive_mutator_count--;
heap_unlock(heap);
}
+void gc_deactivate(struct gc_mutator *mut) {
+ GC_ASSERT(mut->active);
+ deactivate_mutator(mutator_heap(mut), mut);
+}
+
+void gc_reactivate(struct gc_mutator *mut) {
+ GC_ASSERT(!mut->active);
+ reactivate_mutator(mutator_heap(mut), mut);
+}
+
void*
-gc_call_without_gc(struct gc_mutator *mut, void* (*f)(void*), void *data) {
+gc_deactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator*, void*),
+ void *data) {
struct gc_heap *heap = mutator_heap(mut);
deactivate_mutator(heap, mut);
- void *ret = f(data);
+ void *ret = f(mut, data);
reactivate_mutator(heap, mut);
return ret;
}
+
+void*
+gc_reactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator*, void*),
+ void *data) {
+ struct gc_heap *heap = mutator_heap(mut);
+ int reactivate = !mut->active;
+ if (reactivate)
+ reactivate_mutator(heap, mut);
+ void *ret = f(mut, data);
+ if (reactivate)
+ deactivate_mutator(heap, mut);
+ return ret;
+}
diff --git a/libguile/whippet/src/pcc.c b/libguile/whippet/src/pcc.c
index 6b656360c..6902b3412 100644
--- a/libguile/whippet/src/pcc.c
+++ b/libguile/whippet/src/pcc.c
@@ -96,6 +96,7 @@ struct gc_mutator {
void *event_listener_data;
struct gc_mutator *next;
struct gc_mutator *prev;
+ int active;
};
struct gc_trace_worker_data {
@@ -501,6 +502,7 @@ static void add_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
while (mutators_are_stopping(heap))
pthread_cond_wait(&heap->mutator_cond, &heap->lock);
mut->next = mut->prev = NULL;
+ mut->active = 1;
struct gc_mutator *tail = heap->mutators;
if (tail) {
mut->next = tail;
@@ -520,6 +522,7 @@ static void remove_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
mut->heap = NULL;
heap_lock(heap);
heap->mutator_count--;
+ mut->active = 0;
if (mut->next)
mut->next->prev = mut->prev;
if (mut->prev)
@@ -1081,6 +1084,10 @@ void gc_safepoint_slow(struct gc_mutator *mut) {
heap_unlock(heap);
}
+int gc_safepoint_signal_number(void) { GC_CRASH(); }
+void gc_safepoint_signal_inhibit(struct gc_mutator *mut) { GC_CRASH(); }
+void gc_safepoint_signal_reallow(struct gc_mutator *mut) { GC_CRASH(); }
+
struct gc_ephemeron* gc_allocate_ephemeron(struct gc_mutator *mut) {
return gc_allocate(mut, gc_ephemeron_size(), GC_ALLOCATION_TAGGED);
}
@@ -1354,31 +1361,58 @@ void gc_finish_for_thread(struct gc_mutator *mut) {
static void deactivate_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
GC_ASSERT(mut->next == NULL);
+ GC_ASSERT(mut->active);
copy_space_allocator_finish(&mut->allocator, heap_allocation_space(heap));
if (GC_GENERATIONAL)
gc_field_set_writer_release_buffer(mutator_field_logger(mut));
heap_lock(heap);
heap->inactive_mutator_count++;
+ mut->active = 0;
if (all_mutators_stopped(heap))
pthread_cond_signal(&heap->collector_cond);
heap_unlock(heap);
}
static void reactivate_mutator(struct gc_heap *heap, struct gc_mutator *mut) {
+ GC_ASSERT(!mut->active);
heap_lock(heap);
while (mutators_are_stopping(heap))
pthread_cond_wait(&heap->mutator_cond, &heap->lock);
+ mut->active = 1;
heap->inactive_mutator_count--;
maybe_increase_max_active_mutator_count(heap);
heap_unlock(heap);
}
-void* gc_call_without_gc(struct gc_mutator *mut,
- void* (*f)(void*),
- void *data) {
+void gc_deactivate(struct gc_mutator *mut) {
+ GC_ASSERT(mut->active);
+ deactivate_mutator(mutator_heap(mut), mut);
+}
+
+void gc_reactivate(struct gc_mutator *mut) {
+ GC_ASSERT(!mut->active);
+ reactivate_mutator(mutator_heap(mut), mut);
+}
+
+void* gc_deactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator*, void*),
+ void *data) {
struct gc_heap *heap = mutator_heap(mut);
deactivate_mutator(heap, mut);
- void *ret = f(data);
+ void *ret = f(mut, data);
reactivate_mutator(heap, mut);
return ret;
}
+
+void* gc_reactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator*, void*),
+ void *data) {
+ struct gc_heap *heap = mutator_heap(mut);
+ int reactivate = !mut->active;
+ if (reactivate)
+ reactivate_mutator(heap, mut);
+ void *ret = f(mut, data);
+ if (reactivate)
+ deactivate_mutator(heap, mut);
+ return ret;
+}
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
diff --git a/libguile/whippet/src/semi.c b/libguile/whippet/src/semi.c
index 9754b3fa2..a1526cec4 100644
--- a/libguile/whippet/src/semi.c
+++ b/libguile/whippet/src/semi.c
@@ -487,6 +487,9 @@ void gc_write_barrier_slow(struct gc_mutator *mut, struct gc_ref obj,
int* gc_safepoint_flag_loc(struct gc_mutator *mut) { GC_CRASH(); }
void gc_safepoint_slow(struct gc_mutator *mut) { GC_CRASH(); }
+int gc_safepoint_signal_number(void) { GC_CRASH(); }
+void gc_safepoint_signal_inhibit(struct gc_mutator *mut) { GC_CRASH(); }
+void gc_safepoint_signal_reallow(struct gc_mutator *mut) { GC_CRASH(); }
static int collect_for_large_alloc(struct gc_mutator *mut, size_t npages) {
size_t bytes = npages * mutator_semi_space(mut)->page_size;
@@ -761,8 +764,20 @@ struct gc_mutator* gc_init_for_thread(struct gc_stack_addr base,
void gc_finish_for_thread(struct gc_mutator *space) {
}
-void* gc_call_without_gc(struct gc_mutator *mut, void* (*f)(void*),
- void *data) {
+void gc_deactivate(struct gc_mutator *mut) {}
+
+void gc_reactivate(struct gc_mutator *mut) {}
+
+void* gc_deactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator *, void*),
+ void *data) {
+ // Can't be threads, then there won't be collection.
+ return f(mut, data);
+}
+
+void* gc_reactivate_for_call(struct gc_mutator *mut,
+ void* (*f)(struct gc_mutator *mut, void*),
+ void *data) {
// Can't be threads, then there won't be collection.
- return f(data);
+ return f(mut, data);
}