Perform major GC if necessary

This commit is contained in:
Justin Ethier 2015-10-17 02:25:22 -04:00
parent 5ed84d5332
commit b08f68cf52
3 changed files with 14 additions and 7 deletions

3
gc.c
View file

@ -71,7 +71,7 @@ void *gc_try_alloc(gc_heap *h, size_t size)
return NULL; return NULL;
} }
void *gc_alloc(gc_heap *h, size_t size) void *gc_alloc(gc_heap *h, size_t size, int *heap_grown)
{ {
void *result = NULL; void *result = NULL;
size_t max_freed, sum_freed, total_size; size_t max_freed, sum_freed, total_size;
@ -95,6 +95,7 @@ max_freed = 0;
(total_size - sum_freed) > (total_size * 0.75))) // Grow ratio (total_size - sum_freed) > (total_size * 0.75))) // Grow ratio
&& ((!h->max_size) || (total_size < h->max_size))) { && ((!h->max_size) || (total_size < h->max_size))) {
gc_grow_heap(h, size, 0); gc_grow_heap(h, size, 0);
*heap_grown = 1;
} }
result = gc_try_alloc(h, size); result = gc_try_alloc(h, size);
if (!result) { if (!result) {

View file

@ -69,7 +69,7 @@ struct gc_header_type_t {
gc_heap *gc_heap_create(size_t size, size_t max_size, size_t chunk_size); gc_heap *gc_heap_create(size_t size, size_t max_size, size_t chunk_size);
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);
void *gc_try_alloc(gc_heap *h, size_t size); void *gc_try_alloc(gc_heap *h, size_t size);
void *gc_alloc(gc_heap *h, size_t size); void *gc_alloc(gc_heap *h, size_t size, int *heap_grown);
size_t gc_allocated_bytes(object obj); size_t gc_allocated_bytes(object obj);
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);

View file

@ -2378,12 +2378,12 @@ void gc_collect(gc_heap *h, size_t *sum_freed)
// TODO: move globals to thread-specific structures. // TODO: move globals to thread-specific structures.
// for example - gc_cont, gc_ans, gc_num_ans // for example - gc_cont, gc_ans, gc_num_ans
char *gc_move(char *obj, gc_thread_data *thd, int *alloci) { char *gc_move(char *obj, gc_thread_data *thd, int *alloci, int *heap_grown) {
if (!is_object_type(obj)) return obj; if (!is_object_type(obj)) return obj;
switch(type_of(obj)){ switch(type_of(obj)){
case cons_tag: { case cons_tag: {
list hobj = gc_alloc(Cyc_heap, sizeof(cons_type)); list hobj = gc_alloc(Cyc_heap, sizeof(cons_type), heap_grown);
hobj->hdr.mark = 0; hobj->hdr.mark = 0;
type_of(hobj) = cons_tag; type_of(hobj) = cons_tag;
car(hobj) = car(obj); car(hobj) = car(obj);
@ -2403,7 +2403,7 @@ char *gc_move(char *obj, gc_thread_data *thd, int *alloci) {
temp = obj; \ temp = obj; \
if (check_overflow(low_limit, temp) && \ if (check_overflow(low_limit, temp) && \
check_overflow(temp, high_limit)){ \ check_overflow(temp, high_limit)){ \
(obj) = (object) gc_move(temp, Cyc_thread, &alloci); \ (obj) = (object) gc_move(temp, Cyc_thread, &alloci, &heap_grown); \
} \ } \
} }
@ -2415,6 +2415,7 @@ void GC(cont, args, num_args) closure cont; object *args; int num_args;
object high_limit = stack_begin; // TODO: move to thread-specific struct object high_limit = stack_begin; // TODO: move to thread-specific struct
int i; int i;
int scani = 0, alloci = 0; // TODO: not quite sure how to do this yet, want to user pointers but realloc can move them... need to think about how this will work int scani = 0, alloci = 0; // TODO: not quite sure how to do this yet, want to user pointers but realloc can move them... need to think about how this will work
int heap_grown = 0;
// Prevent overrunning buffer // Prevent overrunning buffer
if (num_args > NUM_GC_ANS) { if (num_args > NUM_GC_ANS) {
@ -2472,8 +2473,13 @@ void GC(cont, args, num_args) closure cont; object *args; int num_args;
scani++; scani++;
} }
// TODO: at some point during all of this, check the 'major GC' flag // Check if we need to do a major GC
// to see if we need to do a gc_collect if (heap_grown) {
size_t freed = 0;
// TODO: not good enough, need to pass current cont/args
// what about mutation barrier, do we care at this point???
gc_collect(Cyc_heap, &freed);
}
longjmp(jmp_main,1); // Return globals gc_cont, gc_ans longjmp(jmp_main,1); // Return globals gc_cont, gc_ans
} }