Working on gc_collector()

This commit is contained in:
Justin Ethier 2015-11-10 21:16:40 -05:00
parent d3a6418b0b
commit 41f2a9e6ca
3 changed files with 108 additions and 89 deletions

102
gc.c
View file

@ -178,48 +178,48 @@ size_t gc_heap_total_size(gc_heap *h)
return total_size;
}
void gc_mark(gc_heap *h, object obj)
{
if (nullp(obj) || is_value_type(obj) || mark(obj))
return;
#if GC_DEBUG_PRINTFS
// fprintf(stdout, "gc_mark %p\n", obj);
#endif
((list)obj)->hdr.mark = 1;
// TODO: mark heap saves (??)
// could this be a write barrier?
// Mark objects this one references
if (type_of(obj) == cons_tag) {
gc_mark(h, car(obj));
gc_mark(h, cdr(obj));
} else if (type_of(obj) == closure1_tag) {
gc_mark(h, ((closure1) obj)->elt1);
} else if (type_of(obj) == closure2_tag) {
gc_mark(h, ((closure2) obj)->elt1);
gc_mark(h, ((closure2) obj)->elt2);
} else if (type_of(obj) == closure3_tag) {
gc_mark(h, ((closure3) obj)->elt1);
gc_mark(h, ((closure3) obj)->elt2);
gc_mark(h, ((closure3) obj)->elt3);
} else if (type_of(obj) == closure4_tag) {
gc_mark(h, ((closure4) obj)->elt1);
gc_mark(h, ((closure4) obj)->elt2);
gc_mark(h, ((closure4) obj)->elt3);
gc_mark(h, ((closure4) obj)->elt4);
} else if (type_of(obj) == closureN_tag) {
int i, n = ((closureN) obj)->num_elt;
for (i = 0; i < n; i++) {
gc_mark(h, ((closureN) obj)->elts[i]);
}
} else if (type_of(obj) == vector_tag) {
int i, n = ((vector) obj)->num_elt;
for (i = 0; i < n; i++) {
gc_mark(h, ((vector) obj)->elts[i]);
}
}
}
//void gc_mark(gc_heap *h, object obj)
//{
// if (nullp(obj) || is_value_type(obj) || mark(obj))
// return;
//
//#if GC_DEBUG_PRINTFS
//// fprintf(stdout, "gc_mark %p\n", obj);
//#endif
// ((list)obj)->hdr.mark = 1;
// // TODO: mark heap saves (??)
// // could this be a write barrier?
//
// // Mark objects this one references
// if (type_of(obj) == cons_tag) {
// gc_mark(h, car(obj));
// gc_mark(h, cdr(obj));
// } else if (type_of(obj) == closure1_tag) {
// gc_mark(h, ((closure1) obj)->elt1);
// } else if (type_of(obj) == closure2_tag) {
// gc_mark(h, ((closure2) obj)->elt1);
// gc_mark(h, ((closure2) obj)->elt2);
// } else if (type_of(obj) == closure3_tag) {
// gc_mark(h, ((closure3) obj)->elt1);
// gc_mark(h, ((closure3) obj)->elt2);
// gc_mark(h, ((closure3) obj)->elt3);
// } else if (type_of(obj) == closure4_tag) {
// gc_mark(h, ((closure4) obj)->elt1);
// gc_mark(h, ((closure4) obj)->elt2);
// gc_mark(h, ((closure4) obj)->elt3);
// gc_mark(h, ((closure4) obj)->elt4);
// } else if (type_of(obj) == closureN_tag) {
// int i, n = ((closureN) obj)->num_elt;
// for (i = 0; i < n; i++) {
// gc_mark(h, ((closureN) obj)->elts[i]);
// }
// } else if (type_of(obj) == vector_tag) {
// int i, n = ((vector) obj)->num_elt;
// for (i = 0; i < n; i++) {
// gc_mark(h, ((vector) obj)->elts[i]);
// }
// }
//}
size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr)
{
@ -670,28 +670,30 @@ void gc_collector()
int tmp;
// TODO: what kind of sync is required here?
//clear
//clear :
gc_stage = STAGE_CLEAR_OR_MARKING;
// exchange values of markColor and clearColor
// TODO: synchronize?
tmp = gc_color_clear;
gc_color_clear = gc_color_mark;
gc_color_mark = tmp;
gc_handshake(STATUS_SYNC1);
//mark:
//mark :
gc_handshake(STATUS_SYNC2)
gc_stage = STAGE_TRACING;
gc_post_handshake(STATUS_ASYNC);
TODO: mark global roots
gc_mark_globals();
gc_wait_handshake();
//trace :
CollectorTrace()
gc_collector_trace();
gc_stage = STAGE_SWEEPING;
//sweep :
For each object x in the heap:
if (color(x) = clearColor)
free free [ x
color(x) blue
// TODO: For each object x in the heap:
// TODO: if (color(x) = clearColor)
// TODO: free free [ x
// TODO: color(x) blue
gc_stage = STAGE_RESTING;
// TODO: how long to rest?
}
/////////////////////////////////////////////

View file

@ -133,9 +133,10 @@ void *gc_alloc(gc_heap *h, size_t size, int *heap_grown);
size_t gc_allocated_bytes(object obj);
gc_heap *gc_heap_last(gc_heap *h);
size_t gc_heap_total_size(gc_heap *h);
void gc_mark(gc_heap *h, object obj);
//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);
size_t gc_collect(gc_heap *h, size_t *sum_freed);
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);

View file

@ -2362,34 +2362,50 @@ void Cyc_start_thread(gc_thread_data *thd)
exit(0);
}
// Collect garbage using mark&sweep algorithm
// Note non-global roots should be marked prior to calling this function.
size_t gc_collect(gc_heap *h, size_t *sum_freed)
//// Collect garbage using mark&sweep algorithm
//// Note non-global roots should be marked prior to calling this function.
//size_t gc_collect(gc_heap *h, size_t *sum_freed)
//{
//#if GC_DEBUG_CONCISE_PRINTFS
// printf("(heap: %p size: %d)\n", h, (unsigned int)gc_heap_total_size(h));
//#endif
// // Mark global variables
// gc_mark(h, Cyc_global_variables); // Internal global used by the runtime
// // Marking it ensures all glos are marked
// {
// list l = global_table;
// for(; !nullp(l); l = cdr(l)){
// cvar_type *c = (cvar_type *)car(l);
// gc_mark(h, *(c->pvar)); // Mark actual object the global points to
// }
// }
// // TODO: what else to mark? gc_mark(
// // conservative mark?
// // weak refs?
// // finalize?
// return gc_sweep(h, sum_freed);
// // debug print free stats?
//}
// Mark globals as part of the tracing collector
// This is called by the collector thread
void gc_mark_globals()
{
#if GC_DEBUG_CONCISE_PRINTFS
printf("(heap: %p size: %d)\n", h, (unsigned int)gc_heap_total_size(h));
printf("(gc_mark_globals heap: %p size: %d)\n", h, (unsigned int)gc_heap_total_size(h));
#endif
// Mark global variables
gc_mark(h, Cyc_global_variables); // Internal global used by the runtime
// Marking it ensures all glos are marked
gc_mark_black(Cyc_global_variables); // Internal global used by the runtime
// Marking it ensures all glos are marked
{
list l = global_table;
for(; !nullp(l); l = cdr(l)){
cvar_type *c = (cvar_type *)car(l);
gc_mark(h, *(c->pvar)); // Mark actual object the global points to
gc_mark_black(*(c->pvar)); // Mark actual object the global points to
}
}
// TODO: what else to mark? gc_mark(
// conservative mark?
// weak refs?
// finalize?
return gc_sweep(h, sum_freed);
// debug print free stats?
}
// TODO: move globals to thread-specific structures.
// for example - gc_cont, gc_ans, gc_num_ans
char *gc_move(char *obj, gc_thread_data *thd, int *alloci, int *heap_grown) {
if (!is_object_type(obj)) return obj;
@ -2723,27 +2739,27 @@ void GC(void *data, closure cont, object *args, int num_args)
//fprintf(stdout, "DEBUG done minor GC, alloci = %d\n", alloci);
// Check if we need to do a major GC
if (heap_grown) {
size_t freed = 0, max_freed = 0;
#if GC_DEBUG_CONCISE_PRINTFS
time_t majorStart = time(NULL);
fprintf(stdout, "DEBUG, starting major mark/sweep GC\n"); // JAE DEBUG
#endif
gc_mark(Cyc_heap, cont);
for (i = 0; i < num_args; i++){
gc_mark(Cyc_heap, args[i]);
}
max_freed = gc_collect(Cyc_heap, &freed);
#if GC_DEBUG_CONCISE_PRINTFS
printf("done, freed = %d, max_freed = %d, elapsed = %ld\n", freed, max_freed, time(NULL) - majorStart);
//JAE_DEBUG++;
//if (JAE_DEBUG == 2) exit(1); // JAE DEBUG
for (i = 0; i < 20; i++){
printf("gcMoveCountsDEBUG[%d] = %d\n", i, gcMoveCountsDEBUG[i]);
}
#endif
}
// // Check if we need to do a major GC
// if (heap_grown) {
// size_t freed = 0, max_freed = 0;
//#if GC_DEBUG_CONCISE_PRINTFS
// time_t majorStart = time(NULL);
// fprintf(stdout, "DEBUG, starting major mark/sweep GC\n"); // JAE DEBUG
//#endif
// gc_mark(Cyc_heap, cont);
// for (i = 0; i < num_args; i++){
// gc_mark(Cyc_heap, args[i]);
// }
// max_freed = gc_collect(Cyc_heap, &freed);
//#if GC_DEBUG_CONCISE_PRINTFS
// printf("done, freed = %d, max_freed = %d, elapsed = %ld\n", freed, max_freed, time(NULL) - majorStart);
// //JAE_DEBUG++;
// //if (JAE_DEBUG == 2) exit(1); // JAE DEBUG
// for (i = 0; i < 20; i++){
// printf("gcMoveCountsDEBUG[%d] = %d\n", i, gcMoveCountsDEBUG[i]);
// }
//#endif
// }
/* Let it all go, Neo... */
longjmp(*(((gc_thread_data *)data)->jmp_start), 1);