summaryrefslogtreecommitdiff
path: root/libguile/whippet/src/bdw.c
diff options
context:
space:
mode:
Diffstat (limited to 'libguile/whippet/src/bdw.c')
-rw-r--r--libguile/whippet/src/bdw.c69
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,