Fixing GC
parent
d64921e8a2
commit
6842a2829d
|
@ -181,7 +181,6 @@ void free_unmarked(F_HEAP *heap)
|
|||
}
|
||||
break;
|
||||
case B_FREE:
|
||||
printf("RECLAIMED\n");
|
||||
if(prev && prev->status == B_FREE)
|
||||
prev->size += scan->size;
|
||||
break;
|
||||
|
@ -290,7 +289,7 @@ DEFINE_PRIMITIVE(code_room)
|
|||
|
||||
void code_gc(void)
|
||||
{
|
||||
garbage_collection(TENURED,true,false,0);
|
||||
garbage_collection(TENURED,false,0);
|
||||
}
|
||||
|
||||
DEFINE_PRIMITIVE(code_gc)
|
||||
|
|
47
vm/data_gc.c
47
vm/data_gc.c
|
@ -1,10 +1,10 @@
|
|||
#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 GC_REQUESTED "garbage_collection: code_gc=%d, 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 GC_REQUESTED "garbage_collection: growing_data_heap=%d, requested_bytes=%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_AGING_GC "end_gc: aging_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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -405,7 +408,7 @@ void collect_stack_frame(F_STACK_FRAME *frame)
|
|||
callstack snapshot */
|
||||
void collect_callstack(F_CONTEXT *stacks)
|
||||
{
|
||||
if(collecting_code)
|
||||
if(collecting_gen == TENURED)
|
||||
{
|
||||
CELL top = (CELL)stacks->callstack_top;
|
||||
CELL bottom = (CELL)stacks->callstack_bottom;
|
||||
|
@ -583,11 +586,8 @@ CELL collect_next(CELL scan)
|
|||
{
|
||||
do_slots(scan,copy_handle);
|
||||
|
||||
if(collecting_code)
|
||||
{
|
||||
printf("do_code_slots\n");
|
||||
if(collecting_gen == TENURED)
|
||||
do_code_slots(scan);
|
||||
}
|
||||
|
||||
return scan + untagged_object_size(scan);
|
||||
}
|
||||
|
@ -641,11 +641,11 @@ void begin_gc(CELL requested_bytes)
|
|||
}
|
||||
|
||||
#ifdef GC_DEBUG
|
||||
//printf("\n");
|
||||
printf("\n");
|
||||
dump_generations();
|
||||
printf("Newspace: ");
|
||||
dump_zone(newspace);
|
||||
//printf("\n");
|
||||
printf("\n");
|
||||
#endif;
|
||||
}
|
||||
|
||||
|
@ -690,7 +690,7 @@ void end_gc(void)
|
|||
nursery_collections++;
|
||||
}
|
||||
|
||||
if(collecting_code)
|
||||
if(collecting_gen == TENURED)
|
||||
{
|
||||
/* now that all reachable code blocks have been marked,
|
||||
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
|
||||
an allocation of requested_bytes won't fail */
|
||||
void garbage_collection(CELL gen,
|
||||
bool code_gc,
|
||||
bool growing_data_heap_,
|
||||
CELL requested_bytes)
|
||||
{
|
||||
|
@ -714,17 +713,14 @@ void garbage_collection(CELL gen,
|
|||
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();
|
||||
|
||||
performing_gc = true;
|
||||
collecting_code = code_gc;
|
||||
growing_data_heap = growing_data_heap_;
|
||||
collecting_gen = gen;
|
||||
|
||||
//if(collecting_gen == TENURED) collecting_code = true;
|
||||
|
||||
/* we come back here if a generation is full */
|
||||
if(setjmp(gc_jmp))
|
||||
{
|
||||
|
@ -732,15 +728,10 @@ void garbage_collection(CELL gen,
|
|||
resort to growing the data heap */
|
||||
if(collecting_gen == TENURED)
|
||||
{
|
||||
//if(collecting_code)
|
||||
{
|
||||
growing_data_heap = true;
|
||||
growing_data_heap = true;
|
||||
|
||||
/* see the comment in unmark_marked() */
|
||||
unmark_marked(&code_heap);
|
||||
}
|
||||
//else
|
||||
// collecting_code = true;
|
||||
/* see the comment in unmark_marked() */
|
||||
unmark_marked(&code_heap);
|
||||
}
|
||||
/* we try collecting AGING space twice before going on to
|
||||
collect TENURED */
|
||||
|
@ -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);
|
||||
|
||||
/* initialize chase pointer */
|
||||
|
@ -768,7 +759,7 @@ void garbage_collection(CELL gen,
|
|||
/* collect objects referenced from older generations */
|
||||
collect_cards();
|
||||
|
||||
if(!collecting_code)
|
||||
if(collecting_gen != TENURED)
|
||||
{
|
||||
/* don't scan code heap unless it has pointers to this
|
||||
generation or younger */
|
||||
|
@ -800,7 +791,7 @@ void garbage_collection(CELL gen,
|
|||
|
||||
void data_gc(void)
|
||||
{
|
||||
garbage_collection(TENURED,false,false,0);
|
||||
garbage_collection(TENURED,false,0);
|
||||
}
|
||||
|
||||
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 */
|
||||
bool performing_gc;
|
||||
CELL collecting_gen;
|
||||
bool collecting_code;
|
||||
|
||||
/* if true, we collecting AGING space for the second time, so if it is still
|
||||
full, we go on to collect TENURED */
|
||||
|
@ -222,7 +221,6 @@ CELL heap_scan_ptr;
|
|||
bool gc_off;
|
||||
|
||||
void garbage_collection(volatile CELL gen,
|
||||
bool code_gc,
|
||||
bool growing_data_heap_,
|
||||
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 */
|
||||
#define ALLOT_BUFFER_ZONE 1024
|
||||
|
||||
#define SUFFICIENT_ROOM(a) (nursery->here + ALLOT_BUFFER_ZONE + a <= nursery->end)
|
||||
|
||||
INLINE void maybe_gc(CELL a)
|
||||
{
|
||||
/* If we are requesting a huge object, grow immediately */
|
||||
if(nursery->size - ALLOT_BUFFER_ZONE <= a)
|
||||
garbage_collection(TENURED,false,true,a);
|
||||
/* If we have enough space in the nursery, just return.
|
||||
Otherwise, perform a GC - this may grow the heap if
|
||||
tenured space cannot hold all live objects from the nursery
|
||||
even after a full GC */
|
||||
else if(a + ALLOT_BUFFER_ZONE + nursery->here > nursery->end)
|
||||
garbage_collection(NURSERY,false,false,0);
|
||||
/* There is now sufficient room in the nursery for 'a' */
|
||||
/* If there is enough room, return */
|
||||
if(SUFFICIENT_ROOM(a))
|
||||
return;
|
||||
/* If the object is bigger than the nursery, grow immediately */
|
||||
else if(nursery->size - ALLOT_BUFFER_ZONE <= a)
|
||||
garbage_collection(TENURED,true,a);
|
||||
/* Otherwise, collect the nursery */
|
||||
else
|
||||
{
|
||||
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