Fixing GC
parent
d64921e8a2
commit
6842a2829d
|
@ -181,7 +181,6 @@ void free_unmarked(F_HEAP *heap)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case B_FREE:
|
case B_FREE:
|
||||||
printf("RECLAIMED\n");
|
|
||||||
if(prev && prev->status == B_FREE)
|
if(prev && prev->status == B_FREE)
|
||||||
prev->size += scan->size;
|
prev->size += scan->size;
|
||||||
break;
|
break;
|
||||||
|
@ -290,7 +289,7 @@ DEFINE_PRIMITIVE(code_room)
|
||||||
|
|
||||||
void code_gc(void)
|
void code_gc(void)
|
||||||
{
|
{
|
||||||
garbage_collection(TENURED,true,false,0);
|
garbage_collection(TENURED,false,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(code_gc)
|
DEFINE_PRIMITIVE(code_gc)
|
||||||
|
|
41
vm/data_gc.c
41
vm/data_gc.c
|
@ -1,10 +1,10 @@
|
||||||
#include "master.h"
|
#include "master.h"
|
||||||
|
|
||||||
//#define GC_DEBUG 1
|
#define GC_DEBUG 0
|
||||||
|
|
||||||
#define ALLOC_DATA_HEAP "alloc_data_heap: gens=%ld, young_size=%ld, aging_size=%ld\n"
|
#define ALLOC_DATA_HEAP "alloc_data_heap: gens=%ld, young_size=%ld, aging_size=%ld\n"
|
||||||
#define GC_REQUESTED "garbage_collection: code_gc=%d, growing_data_heap=%d, requested_bytes=%ld\n"
|
#define GC_REQUESTED "garbage_collection: growing_data_heap=%d, requested_bytes=%ld\n"
|
||||||
#define BEGIN_GC "begin_gc: code_gc=%d, growing_data_heap=%d, collecting_gen=%ld\n"
|
#define BEGIN_GC "begin_gc: growing_data_heap=%d, collecting_gen=%ld\n"
|
||||||
#define END_GC "end_gc: gc_elapsed=%ld\n"
|
#define END_GC "end_gc: gc_elapsed=%ld\n"
|
||||||
#define END_AGING_GC "end_gc: aging_collections=%ld, cards_scanned=%ld\n"
|
#define END_AGING_GC "end_gc: aging_collections=%ld, cards_scanned=%ld\n"
|
||||||
#define END_NURSERY_GC "end_gc: nursery_collections=%ld, cards_scanned=%ld\n"
|
#define END_NURSERY_GC "end_gc: nursery_collections=%ld, cards_scanned=%ld\n"
|
||||||
|
@ -29,7 +29,10 @@ void init_cards_offset(void)
|
||||||
- (data_heap->segment->start >> CARD_BITS);
|
- (data_heap->segment->start >> CARD_BITS);
|
||||||
}
|
}
|
||||||
|
|
||||||
F_DATA_HEAP *alloc_data_heap(CELL gens, CELL young_size, CELL aging_size)
|
F_DATA_HEAP *alloc_data_heap(CELL gens,
|
||||||
|
CELL young_size,
|
||||||
|
CELL aging_size,
|
||||||
|
CELL tenured_size)
|
||||||
{
|
{
|
||||||
GC_PRINT(ALLOC_DATA_HEAP,gens,young_size,aging_size);
|
GC_PRINT(ALLOC_DATA_HEAP,gens,young_size,aging_size);
|
||||||
|
|
||||||
|
@ -405,7 +408,7 @@ void collect_stack_frame(F_STACK_FRAME *frame)
|
||||||
callstack snapshot */
|
callstack snapshot */
|
||||||
void collect_callstack(F_CONTEXT *stacks)
|
void collect_callstack(F_CONTEXT *stacks)
|
||||||
{
|
{
|
||||||
if(collecting_code)
|
if(collecting_gen == TENURED)
|
||||||
{
|
{
|
||||||
CELL top = (CELL)stacks->callstack_top;
|
CELL top = (CELL)stacks->callstack_top;
|
||||||
CELL bottom = (CELL)stacks->callstack_bottom;
|
CELL bottom = (CELL)stacks->callstack_bottom;
|
||||||
|
@ -583,11 +586,8 @@ CELL collect_next(CELL scan)
|
||||||
{
|
{
|
||||||
do_slots(scan,copy_handle);
|
do_slots(scan,copy_handle);
|
||||||
|
|
||||||
if(collecting_code)
|
if(collecting_gen == TENURED)
|
||||||
{
|
|
||||||
printf("do_code_slots\n");
|
|
||||||
do_code_slots(scan);
|
do_code_slots(scan);
|
||||||
}
|
|
||||||
|
|
||||||
return scan + untagged_object_size(scan);
|
return scan + untagged_object_size(scan);
|
||||||
}
|
}
|
||||||
|
@ -641,11 +641,11 @@ void begin_gc(CELL requested_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GC_DEBUG
|
#ifdef GC_DEBUG
|
||||||
//printf("\n");
|
printf("\n");
|
||||||
dump_generations();
|
dump_generations();
|
||||||
printf("Newspace: ");
|
printf("Newspace: ");
|
||||||
dump_zone(newspace);
|
dump_zone(newspace);
|
||||||
//printf("\n");
|
printf("\n");
|
||||||
#endif;
|
#endif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,7 +690,7 @@ void end_gc(void)
|
||||||
nursery_collections++;
|
nursery_collections++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(collecting_code)
|
if(collecting_gen == TENURED)
|
||||||
{
|
{
|
||||||
/* now that all reachable code blocks have been marked,
|
/* now that all reachable code blocks have been marked,
|
||||||
deallocate the rest */
|
deallocate the rest */
|
||||||
|
@ -704,7 +704,6 @@ void end_gc(void)
|
||||||
If growing_data_heap_ is true, we must grow the data heap to such a size that
|
If growing_data_heap_ is true, we must grow the data heap to such a size that
|
||||||
an allocation of requested_bytes won't fail */
|
an allocation of requested_bytes won't fail */
|
||||||
void garbage_collection(CELL gen,
|
void garbage_collection(CELL gen,
|
||||||
bool code_gc,
|
|
||||||
bool growing_data_heap_,
|
bool growing_data_heap_,
|
||||||
CELL requested_bytes)
|
CELL requested_bytes)
|
||||||
{
|
{
|
||||||
|
@ -714,34 +713,26 @@ void garbage_collection(CELL gen,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GC_PRINT(GC_REQUESTED,code_gc,growing_data_heap_,requested_bytes);
|
GC_PRINT(GC_REQUESTED,growing_data_heap_,requested_bytes);
|
||||||
|
|
||||||
s64 start = current_millis();
|
s64 start = current_millis();
|
||||||
|
|
||||||
performing_gc = true;
|
performing_gc = true;
|
||||||
collecting_code = code_gc;
|
|
||||||
growing_data_heap = growing_data_heap_;
|
growing_data_heap = growing_data_heap_;
|
||||||
collecting_gen = gen;
|
collecting_gen = gen;
|
||||||
|
|
||||||
//if(collecting_gen == TENURED) collecting_code = true;
|
|
||||||
|
|
||||||
/* we come back here if a generation is full */
|
/* we come back here if a generation is full */
|
||||||
if(setjmp(gc_jmp))
|
if(setjmp(gc_jmp))
|
||||||
{
|
{
|
||||||
/* We have no older generations we can try collecting, so we
|
/* We have no older generations we can try collecting, so we
|
||||||
resort to growing the data heap */
|
resort to growing the data heap */
|
||||||
if(collecting_gen == TENURED)
|
if(collecting_gen == TENURED)
|
||||||
{
|
|
||||||
//if(collecting_code)
|
|
||||||
{
|
{
|
||||||
growing_data_heap = true;
|
growing_data_heap = true;
|
||||||
|
|
||||||
/* see the comment in unmark_marked() */
|
/* see the comment in unmark_marked() */
|
||||||
unmark_marked(&code_heap);
|
unmark_marked(&code_heap);
|
||||||
}
|
}
|
||||||
//else
|
|
||||||
// collecting_code = true;
|
|
||||||
}
|
|
||||||
/* we try collecting AGING space twice before going on to
|
/* we try collecting AGING space twice before going on to
|
||||||
collect TENURED */
|
collect TENURED */
|
||||||
else if(HAVE_AGING_P
|
else if(HAVE_AGING_P
|
||||||
|
@ -757,7 +748,7 @@ void garbage_collection(CELL gen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GC_PRINT(BEGIN_GC,collecting_code,growing_data_heap,collecting_gen);
|
GC_PRINT(BEGIN_GC,growing_data_heap,collecting_gen);
|
||||||
begin_gc(requested_bytes);
|
begin_gc(requested_bytes);
|
||||||
|
|
||||||
/* initialize chase pointer */
|
/* initialize chase pointer */
|
||||||
|
@ -768,7 +759,7 @@ void garbage_collection(CELL gen,
|
||||||
/* collect objects referenced from older generations */
|
/* collect objects referenced from older generations */
|
||||||
collect_cards();
|
collect_cards();
|
||||||
|
|
||||||
if(!collecting_code)
|
if(collecting_gen != TENURED)
|
||||||
{
|
{
|
||||||
/* don't scan code heap unless it has pointers to this
|
/* don't scan code heap unless it has pointers to this
|
||||||
generation or younger */
|
generation or younger */
|
||||||
|
@ -800,7 +791,7 @@ void garbage_collection(CELL gen,
|
||||||
|
|
||||||
void data_gc(void)
|
void data_gc(void)
|
||||||
{
|
{
|
||||||
garbage_collection(TENURED,false,false,0);
|
garbage_collection(TENURED,false,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PRIMITIVE(data_gc)
|
DEFINE_PRIMITIVE(data_gc)
|
||||||
|
|
31
vm/data_gc.h
31
vm/data_gc.h
|
@ -145,7 +145,6 @@ CELL cards_scanned;
|
||||||
/* only meaningful during a GC */
|
/* only meaningful during a GC */
|
||||||
bool performing_gc;
|
bool performing_gc;
|
||||||
CELL collecting_gen;
|
CELL collecting_gen;
|
||||||
bool collecting_code;
|
|
||||||
|
|
||||||
/* if true, we collecting AGING space for the second time, so if it is still
|
/* if true, we collecting AGING space for the second time, so if it is still
|
||||||
full, we go on to collect TENURED */
|
full, we go on to collect TENURED */
|
||||||
|
@ -222,7 +221,6 @@ CELL heap_scan_ptr;
|
||||||
bool gc_off;
|
bool gc_off;
|
||||||
|
|
||||||
void garbage_collection(volatile CELL gen,
|
void garbage_collection(volatile CELL gen,
|
||||||
bool code_gc,
|
|
||||||
bool growing_data_heap_,
|
bool growing_data_heap_,
|
||||||
CELL requested_bytes);
|
CELL requested_bytes);
|
||||||
|
|
||||||
|
@ -308,18 +306,27 @@ allocation (which does not call GC because of possible roots in volatile
|
||||||
registers) does not run out of memory */
|
registers) does not run out of memory */
|
||||||
#define ALLOT_BUFFER_ZONE 1024
|
#define ALLOT_BUFFER_ZONE 1024
|
||||||
|
|
||||||
|
#define SUFFICIENT_ROOM(a) (nursery->here + ALLOT_BUFFER_ZONE + a <= nursery->end)
|
||||||
|
|
||||||
INLINE void maybe_gc(CELL a)
|
INLINE void maybe_gc(CELL a)
|
||||||
{
|
{
|
||||||
/* If we are requesting a huge object, grow immediately */
|
/* If there is enough room, return */
|
||||||
if(nursery->size - ALLOT_BUFFER_ZONE <= a)
|
if(SUFFICIENT_ROOM(a))
|
||||||
garbage_collection(TENURED,false,true,a);
|
return;
|
||||||
/* If we have enough space in the nursery, just return.
|
/* If the object is bigger than the nursery, grow immediately */
|
||||||
Otherwise, perform a GC - this may grow the heap if
|
else if(nursery->size - ALLOT_BUFFER_ZONE <= a)
|
||||||
tenured space cannot hold all live objects from the nursery
|
garbage_collection(TENURED,true,a);
|
||||||
even after a full GC */
|
/* Otherwise, collect the nursery */
|
||||||
else if(a + ALLOT_BUFFER_ZONE + nursery->here > nursery->end)
|
else
|
||||||
garbage_collection(NURSERY,false,false,0);
|
{
|
||||||
/* There is now sufficient room in the nursery for 'a' */
|
garbage_collection(NURSERY,false,0);
|
||||||
|
|
||||||
|
/* If there is still insufficient room, try growing the heap.
|
||||||
|
This can only happen if the number of generations is 1. */
|
||||||
|
if(SUFFICIENT_ROOM(a)) return;
|
||||||
|
|
||||||
|
garbage_collection(TENURED,true,a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue