mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-23 20:15:05 +02:00
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.
This commit is contained in:
parent
9e2a51fdae
commit
1c0c0bb315
3 changed files with 40 additions and 42 deletions
27
gc.c
27
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
51
runtime.c
51
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
|
||||
|
|
Loading…
Add table
Reference in a new issue