Separate cooperation/longjmp from core minor GC

This commit is contained in:
Justin Ethier 2015-12-23 03:02:52 -05:00
parent 9fd4929bb0
commit f0b992335e
2 changed files with 60 additions and 55 deletions

View file

@ -164,56 +164,6 @@ typedef enum { STAGE_CLEAR_OR_MARKING
#define gc_color_red 0 // Memory not to be GC'd, such as on the stack
#define gc_color_blue 2 // Unallocated memory
/* Utility functions */
void **vpbuffer_realloc(void **buf, int *len);
void **vpbuffer_add(void **buf, int *len, int i, void *obj);
void vpbuffer_free(void **buf);
/* GC prototypes */
void gc_initialize();
void gc_add_mutator(gc_thread_data *thd);
void gc_remove_mutator(gc_thread_data *thd);
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);
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_alloc(gc_heap *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);
gc_heap *gc_heap_last(gc_heap *h);
size_t gc_heap_total_size(gc_heap *h);
//size_t gc_heap_total_free_size(gc_heap *h);
//size_t gc_collect(gc_heap *h, size_t *sum_freed);
//void gc_mark(gc_heap *h, object obj);
void gc_mark_globals(void);
size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr);
void gc_thr_grow_move_buffer(gc_thread_data *d);
void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj);
void gc_thread_data_init(gc_thread_data *thd, int mut_num, char *stack_base, long stack_size);
void gc_thread_data_free(gc_thread_data *thd);
// Prototypes for mutator/collector:
int gc_is_stack_obj(gc_thread_data *thd, object obj);
void gc_mut_update(gc_thread_data *thd, object old_obj, object value);
void gc_mut_cooperate(gc_thread_data *thd, int buf_len);
void gc_mark_gray(gc_thread_data *thd, object obj);
void gc_mark_gray2(gc_thread_data *thd, object obj);
void gc_collector_trace();
void gc_mark_black(object obj);
void gc_collector_mark_gray(object parent, object obj);
void gc_empty_collector_stack();
void gc_handshake(gc_status_type s);
void gc_post_handshake(gc_status_type s);
void gc_wait_handshake();
void gc_start_collector();
void gc_set_thread_state_blocked(gc_thread_data *thd);
void gc_set_thread_state_runnable(gc_thread_data *thd);
gc_heap *gc_get_heap();
/////////////////////////////////////////////
// GC Collection cycle
// TODO:
//void gc_collector()
/* Show diagnostic information for the GC when program terminates */
#define DEBUG_SHOW_DIAG 0
@ -451,6 +401,51 @@ typedef union {
double_type double_t;
} common_type;
/* Utility functions */
void **vpbuffer_realloc(void **buf, int *len);
void **vpbuffer_add(void **buf, int *len, int i, void *obj);
void vpbuffer_free(void **buf);
/* GC prototypes */
void gc_initialize();
void gc_add_mutator(gc_thread_data *thd);
void gc_remove_mutator(gc_thread_data *thd);
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);
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_alloc(gc_heap *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);
gc_heap *gc_heap_last(gc_heap *h);
size_t gc_heap_total_size(gc_heap *h);
//size_t gc_heap_total_free_size(gc_heap *h);
//size_t gc_collect(gc_heap *h, size_t *sum_freed);
//void gc_mark(gc_heap *h, object obj);
void gc_mark_globals(void);
size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr);
void gc_thr_grow_move_buffer(gc_thread_data *d);
void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj);
void gc_thread_data_init(gc_thread_data *thd, int mut_num, char *stack_base, long stack_size);
void gc_thread_data_free(gc_thread_data *thd);
// Prototypes for mutator/collector:
int gc_is_stack_obj(gc_thread_data *thd, object obj);
void gc_mut_update(gc_thread_data *thd, object old_obj, object value);
void gc_mut_cooperate(gc_thread_data *thd, int buf_len);
void gc_mark_gray(gc_thread_data *thd, object obj);
void gc_mark_gray2(gc_thread_data *thd, object obj);
void gc_collector_trace();
void gc_mark_black(object obj);
void gc_collector_mark_gray(object parent, object obj);
void gc_empty_collector_stack();
void gc_handshake(gc_status_type s);
void gc_post_handshake(gc_status_type s);
void gc_wait_handshake();
void gc_start_collector();
void gc_set_thread_state_blocked(gc_thread_data *thd);
void gc_set_thread_state_runnable(gc_thread_data *thd);
gc_heap *gc_get_heap();
int gc_minor(void *data, object low_limit, object high_limit, closure cont, object *args, int num_args);
// Atomics section
// TODO: this is all compiler dependent, need to use different macros depending
// upon the compiler (and arch)

View file

@ -2254,12 +2254,10 @@ char *gc_move(char *obj, gc_thread_data *thd, int *alloci, int *heap_grown) {
} \
}
void GC(void *data, closure cont, object *args, int num_args)
// Do a minor GC
int gc_minor(void *data, object low_limit, object high_limit, closure cont, object *args, int num_args)
{
char tmp;
object temp;
object low_limit = &tmp; // This is one end of the stack...
object high_limit = ((gc_thread_data *)data)->stack_start;
int i;
int scani = 0, alloci = 0;
int heap_grown = 0;
@ -2374,10 +2372,22 @@ void GC(void *data, closure cont, object *args, int num_args)
}
scani++;
}
return alloci;
}
/**
* Run a minor GC from a mutator thread.
* This function runs the core GC algorithm, cooperates with
* the collector, and then calls its continuation.
*/
void GC(void *data, closure cont, object *args, int num_args)
{
char tmp;
object low_limit = &tmp; // This is one end of the stack...
object high_limit = ((gc_thread_data *)data)->stack_start;
int alloci = gc_minor(data, low_limit, high_limit, cont, args, num_args);
// Cooperate with the collector thread
gc_mut_cooperate((gc_thread_data *)data, alloci);
#if GC_DEBUG_TRACE
fprintf(stderr, "done with minor GC\n");
#endif