mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-23 20:15:05 +02:00
Working on gc_collector()
This commit is contained in:
parent
d3a6418b0b
commit
41f2a9e6ca
3 changed files with 108 additions and 89 deletions
102
gc.c
102
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?
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
|
|
@ -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);
|
||||
|
|
90
runtime.c
90
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue