WIP - use differnt heap for small objects

This commit is contained in:
Justin Ethier 2016-04-11 23:37:49 -04:00
parent b848e589f4
commit 9174e320dc
3 changed files with 26 additions and 7 deletions

13
gc.c
View file

@ -426,15 +426,22 @@ void *gc_try_alloc(gc_heap *h, size_t size, char *obj, gc_thread_data *thd)
return NULL; return NULL;
} }
void *gc_alloc(gc_heap *h, size_t size, char *obj, gc_thread_data *thd, int *heap_grown) void *gc_alloc(gc_heap_root *hrt, size_t size, char *obj, gc_thread_data *thd, int *heap_grown)
{ {
void *result = NULL; void *result = NULL;
gc_heap *h = NULL;
size_t max_freed = 0, sum_freed = 0, total_size; size_t max_freed = 0, sum_freed = 0, total_size;
// TODO: check return value, if null (could not alloc) then // TODO: check return value, if null (could not alloc) then
// run a collection and check how much free space there is. if less // run a collection and check how much free space there is. if less
// the allowed ratio, try growing heap. // the allowed ratio, try growing heap.
// then try realloc. if cannot alloc now, then throw out of memory error // then try realloc. if cannot alloc now, then throw out of memory error
size = gc_heap_align(size); size = gc_heap_align(size);
if (size <= 32){
h = hrt->small_obj_heap;
} else {
h = hrt->heap;
}
result = gc_try_alloc(h, size, obj, thd); result = gc_try_alloc(h, size, obj, thd);
if (!result) { if (!result) {
// A vanilla mark&sweep collector would collect now, but unfortunately // A vanilla mark&sweep collector would collect now, but unfortunately
@ -1190,7 +1197,8 @@ fprintf(stderr, "DEBUG - after wait_handshake async\n");
ck_pr_cas_int(&gc_stage, STAGE_TRACING, STAGE_SWEEPING); ck_pr_cas_int(&gc_stage, STAGE_TRACING, STAGE_SWEEPING);
// //
//sweep : //sweep :
max_freed = gc_sweep(gc_get_heap(), &freed); max_freed = gc_sweep(gc_get_heap()->heap, &freed);
max_freed = gc_sweep(gc_get_heap()->small_obj_heap, &freed);
total_size = cached_heap_total_size; //gc_heap_total_size(gc_get_heap()); total_size = cached_heap_total_size; //gc_heap_total_size(gc_get_heap());
total_free = cached_heap_free_size; //gc_heap_total_free_size(gc_get_heap()); total_free = cached_heap_free_size; //gc_heap_total_free_size(gc_get_heap());
@ -1200,6 +1208,7 @@ fprintf(stderr, "DEBUG - after wait_handshake async\n");
fprintf(stdout, "Less than %f%% of the heap is free, growing it\n", fprintf(stdout, "Less than %f%% of the heap is free, growing it\n",
100.0 * GC_FREE_THRESHOLD); 100.0 * GC_FREE_THRESHOLD);
#endif #endif
TODO: how do we know which heap to grow???
gc_grow_heap(gc_get_heap(), 0, 0); gc_grow_heap(gc_get_heap(), 0, 0);
total_size = cached_heap_total_size; total_size = cached_heap_total_size;
total_free = cached_heap_free_size; total_free = cached_heap_free_size;

View file

@ -128,6 +128,12 @@ struct gc_heap_t {
char *data; char *data;
}; };
typedef struct gc_heap_root_t gc_heap_root;
struct gc_heap_root_t {
gc_heap *small_obj_heap;
gc_heap *heap;
};
typedef struct gc_header_type_t gc_header_type; typedef struct gc_header_type_t gc_header_type;
struct gc_header_type_t { struct gc_header_type_t {
unsigned int mark; // mark bits (TODO: only need 2, reduce size of type?) unsigned int mark; // mark bits (TODO: only need 2, reduce size of type?)
@ -398,7 +404,7 @@ void gc_print_stats(gc_heap *h);
int gc_grow_heap(gc_heap *h, size_t size, size_t chunk_size); int gc_grow_heap(gc_heap *h, size_t size, size_t chunk_size);
char *gc_copy_obj(object hp, char *obj, gc_thread_data *thd); char *gc_copy_obj(object hp, char *obj, gc_thread_data *thd);
void *gc_try_alloc(gc_heap *h, size_t size, char *obj, gc_thread_data *thd); void *gc_try_alloc(gc_heap *h, size_t size, char *obj, gc_thread_data *thd);
void *gc_alloc(gc_heap *h, size_t size, char *obj, gc_thread_data *thd, int *heap_grown); void *gc_alloc(gc_heap_root *h, size_t size, char *obj, gc_thread_data *thd, int *heap_grown);
size_t gc_allocated_bytes(object obj, gc_free_list *q, gc_free_list *r); size_t gc_allocated_bytes(object obj, gc_free_list *q, gc_free_list *r);
gc_heap *gc_heap_last(gc_heap *h); gc_heap *gc_heap_last(gc_heap *h);
size_t gc_heap_total_size(gc_heap *h); size_t gc_heap_total_size(gc_heap *h);
@ -435,7 +441,7 @@ void gc_mutator_thread_runnable(gc_thread_data *thd, object result);
// set_thread_blocked((data), (cont)); \ // set_thread_blocked((data), (cont)); \
// body \ // body \
// return_thread_runnable((data), (result)); // return_thread_runnable((data), (result));
gc_heap *gc_get_heap(); gc_heap_root *gc_get_heap();
int gc_minor(void *data, object low_limit, object high_limit, closure cont, object *args, int num_args); int gc_minor(void *data, object low_limit, object high_limit, closure cont, object *args, int num_args);
/* Mutation table to support minor GC write barrier */ /* Mutation table to support minor GC write barrier */
void add_mutation(void *data, object var, int index, object value); void add_mutation(void *data, object var, int index, object value);

View file

@ -95,7 +95,7 @@ void Cyc_check_bounds(void *data, const char *label, int len, int index) {
/*END closcall section */ /*END closcall section */
/* Global variables. */ /* Global variables. */
static gc_heap *Cyc_heap; static gc_heap_root *Cyc_heap;
long no_gcs = 0; /* Count the number of GC's. */ long no_gcs = 0; /* Count the number of GC's. */
long no_major_gcs = 0; /* Count the number of GC's. */ long no_major_gcs = 0; /* Count the number of GC's. */
@ -164,7 +164,11 @@ static bool set_insert(ck_hs_t *hs, const void *value)
void gc_init_heap(long heap_size) void gc_init_heap(long heap_size)
{ {
Cyc_heap = gc_heap_create(heap_size, 0, 0);
Cyc_heap = malloc(sizeof(gc_heap_root));
Cyc_heap->heap = gc_heap_create(heap_size, 0, 0);
Cyc_heap->small_obj_heap = gc_heap_create(heap_size, 0, 0);
if (!ck_hs_init(&symbol_table, if (!ck_hs_init(&symbol_table,
CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC, CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC,
hs_hash, hs_compare, hs_hash, hs_compare,
@ -180,7 +184,7 @@ void gc_init_heap(long heap_size)
} }
} }
gc_heap *gc_get_heap() gc_heap_root *gc_get_heap()
{ {
return Cyc_heap; return Cyc_heap;
} }