better GC support for medium-sized immobile objects

svn: r14560
This commit is contained in:
Matthew Flatt 2009-04-19 15:47:52 +00:00
parent 434ec53b88
commit 5a4f15f5f9
4 changed files with 507 additions and 204 deletions

View File

@ -239,13 +239,26 @@ inline static unsigned long custodian_usage(NewGC*gc, void *custodian)
inline static void BTC_memory_account_mark(NewGC *gc, mpage *page, void *ptr) inline static void BTC_memory_account_mark(NewGC *gc, mpage *page, void *ptr)
{ {
GCDEBUG((DEBUGOUTF, "BTC_memory_account_mark: %p/%p\n", page, ptr)); GCDEBUG((DEBUGOUTF, "BTC_memory_account_mark: %p/%p\n", page, ptr));
if(page->big_page) { if(page->size_class) {
struct objhead *info = (struct objhead *)(NUM(page->addr) + PREFIX_SIZE); if(page->size_class > 1) {
/* big page */
struct objhead *info = (struct objhead *)(NUM(page->addr) + PREFIX_SIZE);
if(info->btc_mark == gc->old_btc_mark) {
info->btc_mark = gc->new_btc_mark;
account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(page->size));
push_ptr(ptr);
}
} else {
/* medium page */
struct objhead *info = MED_OBJHEAD(ptr, page->size);
if(info->btc_mark == gc->old_btc_mark) { if(info->btc_mark == gc->old_btc_mark) {
info->btc_mark = gc->new_btc_mark; info->btc_mark = gc->new_btc_mark;
account_memory(gc, gc->current_mark_owner, gcBYTES_TO_WORDS(page->size)); account_memory(gc, gc->current_mark_owner, info->size);
push_ptr(ptr); ptr = PTR(NUM(info) + WORD_SIZE);
push_ptr(ptr);
}
} }
} else { } else {
struct objhead *info = (struct objhead *)((char*)ptr - WORD_SIZE); struct objhead *info = (struct objhead *)((char*)ptr - WORD_SIZE);
@ -315,9 +328,9 @@ int BTC_cust_box_mark(void *p)
return gc->mark_table[btc_redirect_cust_box](p); return gc->mark_table[btc_redirect_cust_box](p);
} }
inline static void mark_normal_obj(NewGC *gc, mpage *page, void *ptr) inline static void mark_normal_obj(NewGC *gc, int type, void *ptr)
{ {
switch(page->page_type) { switch(type) {
case PAGE_TAGGED: { case PAGE_TAGGED: {
/* we do not want to mark the pointers in a thread or custodian /* we do not want to mark the pointers in a thread or custodian
unless the object's owner is the current owner. In the case unless the object's owner is the current owner. In the case
@ -374,7 +387,6 @@ inline static void mark_acc_big_page(NewGC *gc, mpage *page)
} }
} }
static void btc_overmem_abort(NewGC *gc) static void btc_overmem_abort(NewGC *gc)
{ {
gc->kill_propagation_loop = 1; gc->kill_propagation_loop = 1;
@ -391,10 +403,16 @@ static void propagate_accounting_marks(NewGC *gc)
page = pagemap_find_page(pagemap, p); page = pagemap_find_page(pagemap, p);
set_backtrace_source(p, page->page_type); set_backtrace_source(p, page->page_type);
GCDEBUG((DEBUGOUTF, "btc_account: popped off page %p:%p, ptr %p\n", page, page->addr, p)); GCDEBUG((DEBUGOUTF, "btc_account: popped off page %p:%p, ptr %p\n", page, page->addr, p));
if(page->big_page) if(page->size_class) {
mark_acc_big_page(gc, page); if (page->size_class > 1)
else mark_acc_big_page(gc, page);
mark_normal_obj(gc, page, p); else {
struct objhead *info = MED_OBJHEAD(p, page->size);
p = PTR(NUM(info) + WORD_SIZE);
mark_normal_obj(gc, info->type, p);
}
} else
mark_normal_obj(gc, page->page_type, p);
} }
if(gc->kill_propagation_loop) if(gc->kill_propagation_loop)
reset_pointer_stack(); reset_pointer_stack();

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@ typedef struct mpage {
struct mpage *next; struct mpage *next;
struct mpage *prev; struct mpage *prev;
void *addr; void *addr;
unsigned long previous_size; unsigned long previous_size; /* for med page, points to place to search for available block */
unsigned long size; unsigned long size; /* big page size or med page element size */
unsigned char generation; unsigned char generation;
/* /*
unsigned char back_pointers :1; unsigned char back_pointers :1;
@ -17,7 +17,7 @@ typedef struct mpage {
unsigned char mprotected :1; unsigned char mprotected :1;
*/ */
unsigned char back_pointers ; unsigned char back_pointers ;
unsigned char big_page ; unsigned char size_class ; /* 1 => med; 2 => big; 3 => big marked */
unsigned char page_type ; unsigned char page_type ;
unsigned char marked_on ; unsigned char marked_on ;
unsigned char has_new ; unsigned char has_new ;
@ -92,6 +92,8 @@ typedef mpage ****PageMap;
typedef mpage **PageMap; typedef mpage **PageMap;
#endif #endif
#define NUM_MED_PAGE_SIZES (((LOG_APAGE_SIZE - 1) - 3) + 1)
typedef struct NewGC { typedef struct NewGC {
Gen0 gen0; Gen0 gen0;
Mark_Proc *mark_table; /* the table of mark procs */ Mark_Proc *mark_table; /* the table of mark procs */
@ -101,6 +103,8 @@ typedef struct NewGC {
struct mpage *gen1_pages[PAGE_TYPES]; struct mpage *gen1_pages[PAGE_TYPES];
Page_Range *protect_range; Page_Range *protect_range;
struct mpage *med_pages[NUM_MED_PAGE_SIZES];
struct mpage *med_freelist_pages[NUM_MED_PAGE_SIZES];
/* Finalization */ /* Finalization */
Fnl *run_queue; Fnl *run_queue;

View File

@ -1140,7 +1140,7 @@ typedef struct Scheme_Cont_Mark_Set {
Scheme_Object *native_stack_trace; Scheme_Object *native_stack_trace;
} Scheme_Cont_Mark_Set; } Scheme_Cont_Mark_Set;
#define SCHEME_LOG_MARK_SEGMENT_SIZE 8 #define SCHEME_LOG_MARK_SEGMENT_SIZE 6
#define SCHEME_MARK_SEGMENT_SIZE (1 << SCHEME_LOG_MARK_SEGMENT_SIZE) #define SCHEME_MARK_SEGMENT_SIZE (1 << SCHEME_LOG_MARK_SEGMENT_SIZE)
#define SCHEME_MARK_SEGMENT_MASK (SCHEME_MARK_SEGMENT_SIZE - 1) #define SCHEME_MARK_SEGMENT_MASK (SCHEME_MARK_SEGMENT_SIZE - 1)