From 1c0c0bb315661e22472bbf5770b63330316dce25 Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Fri, 15 Jul 2016 23:14:36 -0400 Subject: [PATCH] Change how mutations are stored in memory Use a reallocated memory buffer instead of malloc'd pairs. This should speed things up by reducing the number of allocations and by keeping mutations in contiguous sections of memory. --- gc.c | 27 ++++------------------ include/cyclone/types.h | 4 +++- runtime.c | 51 ++++++++++++++++++++++++++--------------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/gc.c b/gc.c index 30464566..89b42dda 100644 --- a/gc.c +++ b/gc.c @@ -831,27 +831,6 @@ void gc_thr_add_to_move_buffer(gc_thread_data * d, int *alloci, object obj) (*alloci)++; } -// Generic buffer functions -void **vpbuffer_realloc(void **buf, int *len) -{ - return realloc(buf, (*len) * sizeof(void *)); -} - -void **vpbuffer_add(void **buf, int *len, int i, void *obj) -{ - if (i == *len) { - *len *= 2; - buf = vpbuffer_realloc(buf, len); - } - buf[i] = obj; - return buf; -} - -void vpbuffer_free(void **buf) -{ - free(buf); -} - // END heap definitions // Tri-color GC section @@ -1458,6 +1437,10 @@ void gc_thread_data_init(gc_thread_data * thd, int mut_num, char *stack_base, thd->stack_trace_idx = 0; thd->stack_prev_frame = NULL; thd->mutations = NULL; + thd->mutation_buflen = 128; + thd->mutation_count = 0; + thd->mutations = + vpbuffer_realloc(thd->mutations, &(thd->mutation_buflen)); thd->exception_handler_stack = NULL; // thd->thread = NULL; thd->thread_state = CYC_THREAD_STATE_NEW; @@ -1503,7 +1486,7 @@ void gc_thread_data_free(gc_thread_data * thd) if (thd->stack_traces) free(thd->stack_traces); if (thd->mutations) { - clear_mutations(thd); + free(thd->mutations); } free(thd); } diff --git a/include/cyclone/types.h b/include/cyclone/types.h index f18aa1c6..0041415f 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -118,7 +118,9 @@ struct gc_thread_data_t { char *stack_start; char *stack_limit; // Minor GC write barrier - void *mutations; + void **mutations; + int mutation_buflen; + int mutation_count; // List of objects moved to heap during minor GC void **moveBuf; int moveBufLen; diff --git a/runtime.c b/runtime.c index 9f187d25..7a888ece 100644 --- a/runtime.c +++ b/runtime.c @@ -357,33 +357,26 @@ void debug_dump_globals() * Note these functions and underlying data structure are only used by * the calling thread, so locking is not required. */ - void add_mutation(void *data, object var, int index, object value) { gc_thread_data *thd = (gc_thread_data *) data; if (is_object_type(value)) { + thd->mutations = vpbuffer_add(thd->mutations, &(thd->mutation_buflen), thd->mutation_count, var); + thd->mutation_count++; if (index >= 0) { - // For vectors only, malloc_make_pair index as another var. That way + // For vectors only, add index as another var. That way // the write barrier only needs to inspect the mutated index. - thd->mutations = malloc_make_pair(obj_int2obj(index), thd->mutations); + thd->mutations = vpbuffer_add(thd->mutations, &(thd->mutation_buflen), thd->mutation_count, obj_int2obj(index)); + thd->mutation_count++; } - thd->mutations = malloc_make_pair(var, thd->mutations); } } -/* TODO: consider a more efficient implementation, such as reusing old nodes - instead of reclaiming them each time - */ void clear_mutations(void *data) { + // Not clearing memory, just resetting count gc_thread_data *thd = (gc_thread_data *) data; - list l = thd->mutations, next; - while (l != NULL) { - next = cdr(l); - free(l); - l = next; - } - thd->mutations = NULL; + thd->mutation_count = 0; } /* END mutation table */ @@ -3791,9 +3784,9 @@ int gc_minor(void *data, object low_limit, object high_limit, closure cont, // Transport mutations { - list l; - for (l = ((gc_thread_data *) data)->mutations; l != NULL; l = cdr(l)) { - object o = car(l); + int l = 0; + while (l < ((gc_thread_data *) data)->mutation_count) { + object o = ((gc_thread_data *) data)->mutations[l++]; //car(l); if (is_value_type(o)) { // Can happen if a vector element was already // moved and we found an index. Just ignore it @@ -3804,8 +3797,7 @@ int gc_minor(void *data, object low_limit, object high_limit, closure cont, int i; object idx; // For vectors, index is encoded as the next mutation - l = cdr(l); - idx = car(l); + idx = ((gc_thread_data *) data)->mutations[l++]; i = obj_obj2int(idx); gc_move2heap(((vector) o)->elements[i]); } else if (type_of(o) == forward_tag) { @@ -4446,6 +4438,27 @@ object copy2heap(void *data, object obj) &on_stack); } +// Generic buffer functions +void **vpbuffer_realloc(void **buf, int *len) +{ + return realloc(buf, (*len) * sizeof(void *)); +} + +void **vpbuffer_add(void **buf, int *len, int i, void *obj) +{ + if (i == *len) { + *len *= 2; + buf = vpbuffer_realloc(buf, len); + } + buf[i] = obj; + return buf; +} + +void vpbuffer_free(void **buf) +{ + free(buf); +} + /* RNG section */ #define norm 2.328306549295728e-10 #define m1 4294967087.0