summaryrefslogtreecommitdiff
path: root/libguile/whippet/src/mmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/whippet/src/mmc.c')
-rw-r--r--libguile/whippet/src/mmc.c58
1 files changed, 54 insertions, 4 deletions
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;
+}