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

10
gc.c
View file

@ -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
#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)

View file

@ -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)

View file

@ -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;
#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]);}
printf("gcMoveCountsDEBUG[%d] = %d\n", i, gcMoveCountsDEBUG[i]);
}
#endif
}
//fprintf(stdout, "DEBUG, finished minor GC\n"); // JAE DEBUG