This commit is contained in:
Justin Ethier 2015-10-24 00:58:06 -04:00
parent 434bac8a2f
commit bbf4914d30
3 changed files with 35 additions and 28 deletions

12
gc.c
View file

@ -71,8 +71,6 @@ void *gc_try_alloc(gc_heap *h, size_t size)
} else { /* Take the whole chunk */ } else { /* Take the whole chunk */
f1->next = f2->next; f1->next = f2->next;
} }
// zero-out the header
//memset((object)f2, 0, sizeof(gc_header_type));
return f2; return f2;
} }
} }
@ -216,7 +214,9 @@ size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr)
object p, end; object p, end;
gc_free_list *q, *r, *s; gc_free_list *q, *r, *s;
for (; h; h = h->next) { // All heaps 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); p = gc_heap_first_block(h);
q = h->free_list; q = h->free_list;
end = gc_heap_end(h); 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)); size = gc_heap_align(gc_allocated_bytes(p));
//fprintf(stdout, "check object %p, size = %d\n", p, size); //fprintf(stdout, "check object %p, size = %d\n", p, size);
//#if GC_DEBUG_PRINTFS #if GC_DEBUG_CONCISE_PRINTFS
// DEBUG // DEBUG
if (!is_object_type(p)) if (!is_object_type(p))
fprintf(stderr, "sweep: invalid object at %p", 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) if (r && ((char *)p) + size > (char *)r)
fprintf(stderr, "sweep: bad size at %p + %d > %p", p, size, r); fprintf(stderr, "sweep: bad size at %p + %d > %p", p, size, r);
// END DEBUG // END DEBUG
//#endif #endif
if (!mark(p)) { if (!mark(p)) {
#if GC_DEBUG_PRINTFS #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 *)); d->moveBuf = realloc(d->moveBuf, d->moveBufLen * sizeof(void *));
#if GC_DEBUG_CONCISE_PRINTFS
printf("grew moveBuffer, len = %d\n", d->moveBufLen); printf("grew moveBuffer, len = %d\n", d->moveBufLen);
#endif
} }
void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj) void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj)

View file

@ -83,6 +83,7 @@ void gc_thr_add_to_move_buffer(gc_thread_data *d, int *alloci, object obj);
/* GC debugging flags */ /* GC debugging flags */
//#define DEBUG_GC 0 //#define DEBUG_GC 0
#define GC_DEBUG_PRINTFS 0 #define GC_DEBUG_PRINTFS 0
#define GC_DEBUG_CONCISE_PRINTFS 0
/* Show diagnostic information for the GC when program terminates */ /* Show diagnostic information for the GC when program terminates */
#define DEBUG_SHOW_DIAG 0 #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? */ /* Which way does the CPU grow its stack? */
#define STACK_GROWS_DOWNWARD 1 #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 #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 HEAP_SIZE 6000000
/* Define size of object tags. Options are "short" or "long". */ /* Define size of object tags */
typedef long tag_type; typedef long tag_type;
#ifndef CLOCKS_PER_SEC #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 have extra least significant bits that can be used to mark them as
values instead of objects (IE, pointer to a tagged object). values instead of objects (IE, pointer to a tagged object).
On many machines, addresses are multiples of four, leaving the two 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_is_char(x) ((unsigned long)(x) & (unsigned long)1)
#define obj_obj2char(x) (char)((long)(x)>>1) #define obj_obj2char(x) (char)((long)(x)>>1)

View file

@ -10,7 +10,7 @@
#include "cyclone/runtime.h" #include "cyclone/runtime.h"
//int JAE_DEBUG = 0; //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 */ /* Error checking section - type mismatch, num args, etc */
/* Type names to use for error messages */ /* 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. */ // longjmp(jmp_main,1); /* Return globals gc_cont, gc_ans. */
//} //}
// NEW GC algorithm // Collect garbage using mark&sweep algorithm
// // Note non-global roots should be marked prior to calling this function.
// 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
size_t gc_collect(gc_heap *h, size_t *sum_freed) 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)); printf("(heap: %p size: %d)\n", h, (unsigned int)gc_heap_total_size(h));
#endif
// Mark global variables // 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; list l = global_table;
for(; !nullp(l); l = cdr(l)){ for(; !nullp(l); l = cdr(l)){
cvar_type *c = (cvar_type *)car(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( // TODO: what else to mark? gc_mark(
@ -2373,8 +2372,7 @@ size_t gc_collect(gc_heap *h, size_t *sum_freed)
// weak refs? // weak refs?
// finalize? // finalize?
return gc_sweep(h, sum_freed); return gc_sweep(h, sum_freed);
// debug print free stats // debug print free stats?
// return value from sweep??
} }
// TODO: move globals to thread-specific structures. // 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) { 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;
gcMoveCountsDEBUG[type_of(obj)]++; //gcMoveCountsDEBUG[type_of(obj)]++;
//printf("DEBUG gc_move type = %ld\n", type_of(obj)); // JAE DEBUG //printf("DEBUG gc_move type = %ld\n", type_of(obj)); // JAE DEBUG
switch(type_of(obj)){ 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 // Check if we need to do a major GC
if (heap_grown) { if (heap_grown) {
time_t majorStart = time(NULL);
size_t freed = 0, max_freed = 0; 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); gc_mark(Cyc_heap, cont);
for (i = 0; i < num_args; i++){ for (i = 0; i < num_args; i++){
gc_mark(Cyc_heap, args[i]); gc_mark(Cyc_heap, args[i]);
} }
max_freed = gc_collect(Cyc_heap, &freed); max_freed = gc_collect(Cyc_heap, &freed);
printf("done, freed = %d, max_freed = %d, elapsed = %ld\n", freed, max_freed, time(NULL) - majorStart); #if GC_DEBUG_CONCISE_PRINTFS
//JAE_DEBUG++; printf("done, freed = %d, max_freed = %d, elapsed = %ld\n", freed, max_freed, time(NULL) - majorStart);
//if (JAE_DEBUG == 2) exit(1); // JAE DEBUG //JAE_DEBUG++;
for (i = 0; i < 20; i++){ //if (JAE_DEBUG == 2) exit(1); // JAE DEBUG
printf("gcMoveCountsDEBUG[%d] = %d\n", i, gcMoveCountsDEBUG[i]);} for (i = 0; i < 20; i++){
printf("gcMoveCountsDEBUG[%d] = %d\n", i, gcMoveCountsDEBUG[i]);
}
#endif
} }
//fprintf(stdout, "DEBUG, finished minor GC\n"); // JAE DEBUG //fprintf(stdout, "DEBUG, finished minor GC\n"); // JAE DEBUG