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

View File

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

View File

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