From 41f2a9e6caa07ace4ee8a601a5c8febad0f3c51b Mon Sep 17 00:00:00 2001 From: Justin Ethier Date: Tue, 10 Nov 2015 21:16:40 -0500 Subject: [PATCH] Working on gc_collector() --- gc.c | 102 ++++++++++++++++++++-------------------- include/cyclone/types.h | 5 +- runtime.c | 90 ++++++++++++++++++++--------------- 3 files changed, 108 insertions(+), 89 deletions(-) diff --git a/gc.c b/gc.c index 2c369457..95f7bf5e 100644 --- a/gc.c +++ b/gc.c @@ -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? } ///////////////////////////////////////////// diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 69f2466e..60b29bb5 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -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); diff --git a/runtime.c b/runtime.c index 6df073cf..d0da084f 100644 --- a/runtime.c +++ b/runtime.c @@ -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);