diff options
Diffstat (limited to 'libguile/whippet/src/bdw.c')
-rw-r--r-- | libguile/whippet/src/bdw.c | 69 |
1 files changed, 63 insertions, 6 deletions
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, |