diff --git a/gc.c b/gc.c index 213e5d83..7d4500b0 100644 --- a/gc.c +++ b/gc.c @@ -71,8 +71,6 @@ void *gc_try_alloc(gc_heap *h, size_t size) } else { /* Take the whole chunk */ f1->next = f2->next; } - // zero-out the header - //memset((object)f2, 0, sizeof(gc_header_type)); return f2; } } @@ -216,7 +214,9 @@ size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr) object p, end; gc_free_list *q, *r, *s; for (; h; h = h->next) { // All heaps -fprintf(stdout, "sweep heap %p, size = %d\n", h, h->size); +#if GC_DEBUG_CONCISE_PRINTFS + fprintf(stdout, "sweep heap %p, size = %d\n", h, h->size); +#endif p = gc_heap_first_block(h); q = h->free_list; end = gc_heap_end(h); @@ -234,7 +234,7 @@ fprintf(stdout, "sweep heap %p, size = %d\n", h, h->size); size = gc_heap_align(gc_allocated_bytes(p)); //fprintf(stdout, "check object %p, size = %d\n", p, size); -//#if GC_DEBUG_PRINTFS +#if GC_DEBUG_CONCISE_PRINTFS // DEBUG if (!is_object_type(p)) fprintf(stderr, "sweep: invalid object at %p", p); @@ -243,7 +243,7 @@ fprintf(stdout, "sweep heap %p, size = %d\n", h, h->size); if (r && ((char *)p) + size > (char *)r) fprintf(stderr, "sweep: bad size at %p + %d > %p", p, size, r); // END DEBUG -//#endif +#endif if (!mark(p)) { #if GC_DEBUG_PRINTFS @@ -311,7 +311,9 @@ void gc_thr_grow_move_buffer(gc_thread_data *d) } d->moveBuf = realloc(d->moveBuf, d->moveBufLen * sizeof(void *)); +#if GC_DEBUG_CONCISE_PRINTFS printf("grew moveBuffer, len = %d\n", d->moveBufLen); +#endif } void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj) diff --git a/include/cyclone/types.h b/include/cyclone/types.h index 9768aec1..ecf58721 100644 --- a/include/cyclone/types.h +++ b/include/cyclone/types.h @@ -83,6 +83,7 @@ void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj); /* GC debugging flags */ //#define DEBUG_GC 0 #define GC_DEBUG_PRINTFS 0 +#define GC_DEBUG_CONCISE_PRINTFS 0 /* Show diagnostic information for the GC when program terminates */ #define DEBUG_SHOW_DIAG 0 @@ -93,13 +94,14 @@ void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj); /* Which way does the CPU grow its stack? */ #define STACK_GROWS_DOWNWARD 1 -/* Size of the stack buffer, in bytes. */ +/* Size of the stack buffer, in bytes. + This is used as the first generation of the GC. */ #define STACK_SIZE 250000 -/* Size of the 2nd generation, in bytes. */ +/* Size of a "page" on the heap (the 2nd generation), in bytes. */ #define HEAP_SIZE 6000000 -/* Define size of object tags. Options are "short" or "long". */ +/* Define size of object tags */ typedef long tag_type; #ifndef CLOCKS_PER_SEC @@ -150,7 +152,7 @@ typedef long tag_type; have extra least significant bits that can be used to mark them as values instead of objects (IE, pointer to a tagged object). On many machines, addresses are multiples of four, leaving the two - least significant bits free - according to lisp in small pieces. + least significant bits free - from lisp in small pieces. */ #define obj_is_char(x) ((unsigned long)(x) & (unsigned long)1) #define obj_obj2char(x) (char)((long)(x)>>1) diff --git a/runtime.c b/runtime.c index a3c8477e..cd47312f 100644 --- a/runtime.c +++ b/runtime.c @@ -10,7 +10,7 @@ #include "cyclone/runtime.h" //int JAE_DEBUG = 0; -int gcMoveCountsDEBUG[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +//int gcMoveCountsDEBUG[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Error checking section - type mismatch, num args, etc */ /* Type names to use for error messages */ @@ -2350,22 +2350,21 @@ void Cyc_apply_from_buf(int argc, object prim, object *buf) { // longjmp(jmp_main,1); /* Return globals gc_cont, gc_ans. */ //} -// NEW GC algorithm -// -// TODO: not quite sure when to call this function. might want to set a flag -// if the heap was expanded during alloc, and after all the allocs are done -// after a minor GC (or during the minor GC), call into this function to -// free up unused space +// 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 */ + 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 global, not the pvar + gc_mark(h, *(c->pvar)); // Mark actual object the global points to } } // TODO: what else to mark? gc_mark( @@ -2373,8 +2372,7 @@ size_t gc_collect(gc_heap *h, size_t *sum_freed) // weak refs? // finalize? return gc_sweep(h, sum_freed); - // debug print free stats - // return value from sweep?? + // debug print free stats? } // TODO: move globals to thread-specific structures. @@ -2383,7 +2381,7 @@ size_t gc_collect(gc_heap *h, size_t *sum_freed) char *gc_move(char *obj, gc_thread_data *thd, int *alloci, int *heap_grown) { if (!is_object_type(obj)) return obj; -gcMoveCountsDEBUG[type_of(obj)]++; +//gcMoveCountsDEBUG[type_of(obj)]++; //printf("DEBUG gc_move type = %ld\n", type_of(obj)); // JAE DEBUG switch(type_of(obj)){ @@ -2715,19 +2713,24 @@ void GC(cont, args, num_args) closure cont; object *args; int num_args; // Check if we need to do a major GC if (heap_grown) { - time_t majorStart = time(NULL); size_t freed = 0, max_freed = 0; -fprintf(stdout, "DEBUG, starting major mark/sweep GC\n"); // JAE DEBUG +#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); -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]);} +#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 } //fprintf(stdout, "DEBUG, finished minor GC\n"); // JAE DEBUG