From e28951a8d5019524b0babf8ef8ba8b184bd0773a Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Mon, 4 Jan 2016 22:54:23 -0500 Subject: [PATCH] Move the mutation table into thread data. --- gc.c | 4 ++++ include/cyclone/runtime.h | 4 ---- include/cyclone/types.h | 6 +++++- runtime.c | 27 +++++++++++++++------------ 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/gc.c b/gc.c index 480dacc7..cf5acd65 100644 --- a/gc.c +++ b/gc.c @@ -1199,6 +1199,7 @@ void gc_thread_data_init(gc_thread_data *thd, int mut_num, char *stack_base, lon thd->stack_traces = calloc(MAX_STACK_TRACES, sizeof(char *)); thd->stack_trace_idx = 0; thd->stack_prev_frame = NULL; + thd->mutations = NULL; // thd->thread = NULL; thd->thread_state = CYC_THREAD_STATE_NEW; //thd->mutator_num = mut_num; @@ -1234,6 +1235,9 @@ void gc_thread_data_free(gc_thread_data *thd) if (thd->moveBuf) free(thd->moveBuf); if (thd->mark_buffer) free(thd->mark_buffer); if (thd->stack_traces) free(thd->stack_traces); + if (thd->mutations) { + clear_mutations(thd); + } free(thd); } } diff --git a/include/cyclone/runtime.h b/include/cyclone/runtime.h index 4f35bcd7..4d0dbf69 100644 --- a/include/cyclone/runtime.h +++ b/include/cyclone/runtime.h @@ -211,10 +211,6 @@ object find_or_add_symbol(const char *name); extern list global_table; void add_global(object *glo); -void add_mutation(object var, object value); -void clear_mutations(); -extern list mutation_table; - void dispatch(void *data, int argc, function_type func, object clo, object cont, object args); void dispatch_va(void *data, int argc, function_type_va func, object clo, object cont, object args); void do_dispatch(void *data, int argc, function_type func, object clo, object *buffer); diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 40b9721c..8c482ebe 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -66,7 +66,8 @@ struct gc_thread_data_t { // Data needed to initiate stack-based minor GC char *stack_start; char *stack_limit; -//TODO: store stack traces per thread + // Minor GC write barrier + void *mutations; // List of objects moved to heap during minor GC void **moveBuf; int moveBufLen; @@ -452,4 +453,7 @@ void gc_mutator_thread_runnable(gc_thread_data *thd, object result); gc_heap *gc_get_heap(); int gc_minor(void *data, object low_limit, object high_limit, closure cont, object *args, int num_args); +void add_mutation(void *data, object var, object value); +void clear_mutations(void *data); + #endif /* CYCLONE_TYPES_H */ diff --git a/runtime.c b/runtime.c index f14301cf..266de942 100644 --- a/runtime.c +++ b/runtime.c @@ -312,30 +312,33 @@ void debug_dump_globals() /* END Global table */ -/* Mutation table +/* Mutation table functions * * Keep track of mutations (EG: set-car!) so that new * values are transported to the heap during GC. + * Note these functions and underlying data structure are only used by + * the calling thread, so locking is not required. */ -list mutation_table = nil; -void add_mutation(object var, object value){ +void add_mutation(void *data, object var, object value){ + gc_thread_data *thd = (gc_thread_data *)data; if (is_object_type(value)) { - mutation_table = mcons(var, mutation_table); + thd->mutations = mcons(var, thd->mutations); } } /* TODO: consider a more efficient implementation, such as reusing old nodes instead of reclaiming them each time */ -void clear_mutations() { - list l = mutation_table, next; +void clear_mutations(void *data) { + gc_thread_data *thd = (gc_thread_data *)data; + list l = thd->mutations, next; while (!nullp(l)) { next = cdr(l); free(l); l = next; } - mutation_table = nil; + thd->mutations = nil; } /* END mutation table */ @@ -897,7 +900,7 @@ object Cyc_set_car(void *data, object l, object val) { if (Cyc_is_cons(l) == boolean_f) Cyc_invalid_type_error(data, cons_tag, l); gc_mut_update((gc_thread_data *)data, car(l), val); car(l) = val; - add_mutation(l, val); + add_mutation(data, l, val); return l; } @@ -905,7 +908,7 @@ object Cyc_set_cdr(void *data, object l, object val) { if (Cyc_is_cons(l) == boolean_f) Cyc_invalid_type_error(data, cons_tag, l); gc_mut_update((gc_thread_data *)data, cdr(l), val); cdr(l) = val; - add_mutation(l, val); + add_mutation(data, l, val); return l; } @@ -926,7 +929,7 @@ object Cyc_vector_set(void *data, object v, object k, object obj) { ((vector)v)->elts[idx] = obj; // TODO: probably could be more efficient here and also pass // index, so only that one entry needs GC. - add_mutation(v, obj); + add_mutation(data, v, obj); return v; } @@ -2366,7 +2369,7 @@ int gc_minor(void *data, object low_limit, object high_limit, closure cont, obje // Transport mutations { list l; - for (l = mutation_table; !nullp(l); l = cdr(l)) { + for (l = ((gc_thread_data *)data)->mutations; !nullp(l); l = cdr(l)) { object o = car(l); if (type_of(o) == cons_tag) { gc_move2heap(car(o)); @@ -2385,7 +2388,7 @@ int gc_minor(void *data, object low_limit, object high_limit, closure cont, obje } } } - clear_mutations(); // Reset for next time + clear_mutations(data); // Reset for next time // Transport globals gc_move2heap(Cyc_global_variables); // Internal global used by the runtime