mirror of
https://github.com/justinethier/cyclone.git
synced 2025-05-24 20:45:06 +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;
|
return total_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gc_mark(gc_heap *h, object obj)
|
//void gc_mark(gc_heap *h, object obj)
|
||||||
{
|
//{
|
||||||
if (nullp(obj) || is_value_type(obj) || mark(obj))
|
// if (nullp(obj) || is_value_type(obj) || mark(obj))
|
||||||
return;
|
// return;
|
||||||
|
//
|
||||||
#if GC_DEBUG_PRINTFS
|
//#if GC_DEBUG_PRINTFS
|
||||||
// fprintf(stdout, "gc_mark %p\n", obj);
|
//// fprintf(stdout, "gc_mark %p\n", obj);
|
||||||
#endif
|
//#endif
|
||||||
((list)obj)->hdr.mark = 1;
|
// ((list)obj)->hdr.mark = 1;
|
||||||
// TODO: mark heap saves (??)
|
// // TODO: mark heap saves (??)
|
||||||
// could this be a write barrier?
|
// // could this be a write barrier?
|
||||||
|
//
|
||||||
// Mark objects this one references
|
// // Mark objects this one references
|
||||||
if (type_of(obj) == cons_tag) {
|
// if (type_of(obj) == cons_tag) {
|
||||||
gc_mark(h, car(obj));
|
// gc_mark(h, car(obj));
|
||||||
gc_mark(h, cdr(obj));
|
// gc_mark(h, cdr(obj));
|
||||||
} else if (type_of(obj) == closure1_tag) {
|
// } else if (type_of(obj) == closure1_tag) {
|
||||||
gc_mark(h, ((closure1) obj)->elt1);
|
// gc_mark(h, ((closure1) obj)->elt1);
|
||||||
} else if (type_of(obj) == closure2_tag) {
|
// } else if (type_of(obj) == closure2_tag) {
|
||||||
gc_mark(h, ((closure2) obj)->elt1);
|
// gc_mark(h, ((closure2) obj)->elt1);
|
||||||
gc_mark(h, ((closure2) obj)->elt2);
|
// gc_mark(h, ((closure2) obj)->elt2);
|
||||||
} else if (type_of(obj) == closure3_tag) {
|
// } else if (type_of(obj) == closure3_tag) {
|
||||||
gc_mark(h, ((closure3) obj)->elt1);
|
// gc_mark(h, ((closure3) obj)->elt1);
|
||||||
gc_mark(h, ((closure3) obj)->elt2);
|
// gc_mark(h, ((closure3) obj)->elt2);
|
||||||
gc_mark(h, ((closure3) obj)->elt3);
|
// gc_mark(h, ((closure3) obj)->elt3);
|
||||||
} else if (type_of(obj) == closure4_tag) {
|
// } else if (type_of(obj) == closure4_tag) {
|
||||||
gc_mark(h, ((closure4) obj)->elt1);
|
// gc_mark(h, ((closure4) obj)->elt1);
|
||||||
gc_mark(h, ((closure4) obj)->elt2);
|
// gc_mark(h, ((closure4) obj)->elt2);
|
||||||
gc_mark(h, ((closure4) obj)->elt3);
|
// gc_mark(h, ((closure4) obj)->elt3);
|
||||||
gc_mark(h, ((closure4) obj)->elt4);
|
// gc_mark(h, ((closure4) obj)->elt4);
|
||||||
} else if (type_of(obj) == closureN_tag) {
|
// } else if (type_of(obj) == closureN_tag) {
|
||||||
int i, n = ((closureN) obj)->num_elt;
|
// int i, n = ((closureN) obj)->num_elt;
|
||||||
for (i = 0; i < n; i++) {
|
// for (i = 0; i < n; i++) {
|
||||||
gc_mark(h, ((closureN) obj)->elts[i]);
|
// gc_mark(h, ((closureN) obj)->elts[i]);
|
||||||
}
|
// }
|
||||||
} else if (type_of(obj) == vector_tag) {
|
// } else if (type_of(obj) == vector_tag) {
|
||||||
int i, n = ((vector) obj)->num_elt;
|
// int i, n = ((vector) obj)->num_elt;
|
||||||
for (i = 0; i < n; i++) {
|
// for (i = 0; i < n; i++) {
|
||||||
gc_mark(h, ((vector) obj)->elts[i]);
|
// gc_mark(h, ((vector) obj)->elts[i]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr)
|
size_t gc_sweep(gc_heap *h, size_t *sum_freed_ptr)
|
||||||
{
|
{
|
||||||
|
@ -670,28 +670,30 @@ void gc_collector()
|
||||||
int tmp;
|
int tmp;
|
||||||
// TODO: what kind of sync is required here?
|
// TODO: what kind of sync is required here?
|
||||||
|
|
||||||
//clear
|
//clear :
|
||||||
gc_stage = STAGE_CLEAR_OR_MARKING;
|
gc_stage = STAGE_CLEAR_OR_MARKING;
|
||||||
// exchange values of markColor and clearColor
|
// exchange values of markColor and clearColor
|
||||||
|
// TODO: synchronize?
|
||||||
tmp = gc_color_clear;
|
tmp = gc_color_clear;
|
||||||
gc_color_clear = gc_color_mark;
|
gc_color_clear = gc_color_mark;
|
||||||
gc_color_mark = tmp;
|
gc_color_mark = tmp;
|
||||||
gc_handshake(STATUS_SYNC1);
|
gc_handshake(STATUS_SYNC1);
|
||||||
//mark:
|
//mark :
|
||||||
gc_handshake(STATUS_SYNC2)
|
gc_handshake(STATUS_SYNC2)
|
||||||
gc_stage = STAGE_TRACING;
|
gc_stage = STAGE_TRACING;
|
||||||
gc_post_handshake(STATUS_ASYNC);
|
gc_post_handshake(STATUS_ASYNC);
|
||||||
TODO: mark global roots
|
gc_mark_globals();
|
||||||
gc_wait_handshake();
|
gc_wait_handshake();
|
||||||
//trace :
|
//trace :
|
||||||
CollectorTrace()
|
gc_collector_trace();
|
||||||
gc_stage = STAGE_SWEEPING;
|
gc_stage = STAGE_SWEEPING;
|
||||||
//sweep :
|
//sweep :
|
||||||
For each object x in the heap:
|
// TODO: For each object x in the heap:
|
||||||
if (color(x) = clearColor)
|
// TODO: if (color(x) = clearColor)
|
||||||
free free [ x
|
// TODO: free free [ x
|
||||||
color(x) blue
|
// TODO: color(x) blue
|
||||||
gc_stage = STAGE_RESTING;
|
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);
|
size_t gc_allocated_bytes(object obj);
|
||||||
gc_heap *gc_heap_last(gc_heap *h);
|
gc_heap *gc_heap_last(gc_heap *h);
|
||||||
size_t gc_heap_total_size(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_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_grow_move_buffer(gc_thread_data *d);
|
||||||
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);
|
||||||
void gc_thread_data_init(gc_thread_data *thd, int mut_num, char *stack_base, long stack_size);
|
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);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collect garbage using mark&sweep algorithm
|
//// Collect garbage using mark&sweep algorithm
|
||||||
// Note non-global roots should be marked prior to calling this function.
|
//// Note non-global roots should be marked prior to calling this function.
|
||||||
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));
|
||||||
|
//#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
|
#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
|
#endif
|
||||||
// Mark global variables
|
// Mark global variables
|
||||||
gc_mark(h, Cyc_global_variables); // Internal global used by the runtime
|
gc_mark_black(Cyc_global_variables); // Internal global used by the runtime
|
||||||
// Marking it ensures all glos are marked
|
// 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 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) {
|
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;
|
||||||
|
|
||||||
|
@ -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);
|
//fprintf(stdout, "DEBUG done minor GC, alloci = %d\n", alloci);
|
||||||
|
|
||||||
// Check if we need to do a major GC
|
// // Check if we need to do a major GC
|
||||||
if (heap_grown) {
|
// if (heap_grown) {
|
||||||
size_t freed = 0, max_freed = 0;
|
// size_t freed = 0, max_freed = 0;
|
||||||
#if GC_DEBUG_CONCISE_PRINTFS
|
//#if GC_DEBUG_CONCISE_PRINTFS
|
||||||
time_t majorStart = time(NULL);
|
// time_t majorStart = time(NULL);
|
||||||
fprintf(stdout, "DEBUG, starting major mark/sweep GC\n"); // JAE DEBUG
|
// fprintf(stdout, "DEBUG, starting major mark/sweep GC\n"); // JAE DEBUG
|
||||||
#endif
|
//#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);
|
||||||
#if GC_DEBUG_CONCISE_PRINTFS
|
//#if GC_DEBUG_CONCISE_PRINTFS
|
||||||
printf("done, freed = %d, max_freed = %d, elapsed = %ld\n", freed, max_freed, time(NULL) - majorStart);
|
// printf("done, freed = %d, max_freed = %d, elapsed = %ld\n", freed, max_freed, time(NULL) - majorStart);
|
||||||
//JAE_DEBUG++;
|
// //JAE_DEBUG++;
|
||||||
//if (JAE_DEBUG == 2) exit(1); // JAE DEBUG
|
// //if (JAE_DEBUG == 2) exit(1); // JAE DEBUG
|
||||||
for (i = 0; i < 20; i++){
|
// for (i = 0; i < 20; i++){
|
||||||
printf("gcMoveCountsDEBUG[%d] = %d\n", i, gcMoveCountsDEBUG[i]);
|
// printf("gcMoveCountsDEBUG[%d] = %d\n", i, gcMoveCountsDEBUG[i]);
|
||||||
}
|
// }
|
||||||
#endif
|
//#endif
|
||||||
}
|
// }
|
||||||
|
|
||||||
/* Let it all go, Neo... */
|
/* Let it all go, Neo... */
|
||||||
longjmp(*(((gc_thread_data *)data)->jmp_start), 1);
|
longjmp(*(((gc_thread_data *)data)->jmp_start), 1);
|
||||||
|
|
Loading…
Add table
Reference in a new issue