Fixing GC

db4
Slava Pestov 2008-04-05 02:08:37 -05:00
parent d64921e8a2
commit 6842a2829d
3 changed files with 39 additions and 42 deletions

View File

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

View File

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

View File

@ -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);
}
}
/*