[gc2] share the mark_table

svn: r12813
This commit is contained in:
Kevin Tew 2008-12-12 19:36:10 +00:00
parent 37f104ded0
commit bd5c06750b
4 changed files with 77 additions and 45 deletions

View File

@ -4,6 +4,13 @@
#ifdef NEWGC_BTC_ACCOUNT #ifdef NEWGC_BTC_ACCOUNT
#include "../src/schpriv.h" #include "../src/schpriv.h"
/* BTC_ prefixed functions are called by newgc.c */
/* btc_ prefixed functions are internal to blame_the_child.c */
static const int btc_redirect_thread = 511;
static const int btc_redirect_custodian = 510;
static const int btc_redirect_ephemeron = 509;
static const int btc_redirect_cust_box = 508;
/*****************************************************************************/ /*****************************************************************************/
/* thread list */ /* thread list */
@ -36,11 +43,12 @@ inline static void BTC_register_thread(void *t, void *c)
inline static void mark_threads(NewGC *gc, int owner) inline static void mark_threads(NewGC *gc, int owner)
{ {
GC_Thread_Info *work; GC_Thread_Info *work;
Mark_Proc thread_mark = gc->mark_table[btc_redirect_thread];
for(work = gc->thread_infos; work; work = work->next) for(work = gc->thread_infos; work; work = work->next)
if(work->owner == owner) { if(work->owner == owner) {
if (((Scheme_Thread *)work->thread)->running) { if (((Scheme_Thread *)work->thread)->running) {
gc->normal_thread_mark(work->thread); thread_mark(work->thread);
if (work->thread == scheme_current_thread) { if (work->thread == scheme_current_thread) {
GC_mark_variable_stack(GC_variable_stack, 0, get_stack_base(gc), NULL); GC_mark_variable_stack(GC_variable_stack, 0, get_stack_base(gc), NULL);
} }
@ -249,6 +257,7 @@ inline static void mark_cust_boxes(NewGC *gc, Scheme_Custodian *cur)
{ {
Scheme_Object *pr, *prev = NULL, *next; Scheme_Object *pr, *prev = NULL, *next;
GC_Weak_Box *wb; GC_Weak_Box *wb;
Mark_Proc cust_box_mark = gc->mark_table[btc_redirect_cust_box];
/* cust boxes is a list of weak boxes to cust boxes */ /* cust boxes is a list of weak boxes to cust boxes */
@ -257,7 +266,7 @@ inline static void mark_cust_boxes(NewGC *gc, Scheme_Custodian *cur)
wb = (GC_Weak_Box *)SCHEME_CAR(pr); wb = (GC_Weak_Box *)SCHEME_CAR(pr);
next = SCHEME_CDR(pr); next = SCHEME_CDR(pr);
if (wb->val) { if (wb->val) {
gc->normal_cust_box_mark(wb->val); cust_box_mark(wb->val);
prev = pr; prev = pr;
} else { } else {
if (prev) if (prev)
@ -273,21 +282,32 @@ inline static void mark_cust_boxes(NewGC *gc, Scheme_Custodian *cur)
int BTC_thread_mark(void *p) int BTC_thread_mark(void *p)
{ {
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size; NewGC *gc = GC_get_GC();
if (gc->doing_memory_accounting) {
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size;
}
return gc->mark_table[btc_redirect_thread](p);
} }
int BTC_custodian_mark(void *p) int BTC_custodian_mark(void *p)
{ {
NewGC *gc = GC_get_GC(); NewGC *gc = GC_get_GC();
if(custodian_to_owner_set(gc, p) == gc->current_mark_owner) if (gc->doing_memory_accounting) {
return gc->normal_custodian_mark(p); if(custodian_to_owner_set(gc, p) == gc->current_mark_owner)
else return gc->mark_table[btc_redirect_custodian](p);
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size; else
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size;
}
return gc->mark_table[btc_redirect_custodian](p);
} }
int BTC_cust_box_mark(void *p) int BTC_cust_box_mark(void *p)
{ {
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size; NewGC *gc = GC_get_GC();
if (gc->doing_memory_accounting) {
return ((struct objhead *)(NUM(p) - WORD_SIZE))->size;
}
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, mpage *page, void *ptr)
@ -375,6 +395,21 @@ static void propagate_accounting_marks(NewGC *gc)
reset_pointer_stack(); reset_pointer_stack();
} }
inline static void BTC_initialize_mark_table(NewGC *gc) {
gc->mark_table[scheme_thread_type] = BTC_thread_mark;
gc->mark_table[scheme_custodian_type] = BTC_custodian_mark;
gc->mark_table[gc->ephemeron_tag] = BTC_ephemeron_mark;
gc->mark_table[gc->cust_box_tag] = BTC_cust_box_mark;
}
inline static int BTC_get_redirect_tag(NewGC *gc, int tag) {
if (tag == scheme_thread_type ) { tag = btc_redirect_thread; }
else if (tag == scheme_custodian_type ) { tag = btc_redirect_custodian; }
else if (tag == gc->ephemeron_tag ) { tag = btc_redirect_ephemeron; }
else if (tag == gc->cust_box_tag ) { tag = btc_redirect_cust_box; }
return tag;
}
static void BTC_do_accounting(NewGC *gc) static void BTC_do_accounting(NewGC *gc)
{ {
const int table_size = gc->owner_table_size; const int table_size = gc->owner_table_size;
@ -390,17 +425,6 @@ static void BTC_do_accounting(NewGC *gc)
gc->in_unsafe_allocation_mode = 1; gc->in_unsafe_allocation_mode = 1;
gc->unsafe_allocation_abort = btc_overmem_abort; gc->unsafe_allocation_abort = btc_overmem_abort;
if(!gc->normal_thread_mark) {
gc->normal_thread_mark = gc->mark_table[scheme_thread_type];
gc->normal_custodian_mark = gc->mark_table[scheme_custodian_type];
gc->normal_cust_box_mark = gc->mark_table[gc->cust_box_tag];
}
gc->mark_table[scheme_thread_type] = BTC_thread_mark;
gc->mark_table[scheme_custodian_type] = BTC_custodian_mark;
gc->mark_table[gc->ephemeron_tag] = BTC_ephemeron_mark;
gc->mark_table[gc->cust_box_tag] = BTC_cust_box_mark;
/* clear the memory use numbers out */ /* clear the memory use numbers out */
for(i = 1; i < table_size; i++) for(i = 1; i < table_size; i++)
if(owner_table[i]) if(owner_table[i])
@ -427,11 +451,6 @@ static void BTC_do_accounting(NewGC *gc)
box = cur->global_prev; cur = box ? SCHEME_PTR1_VAL(box) : NULL; box = cur->global_prev; cur = box ? SCHEME_PTR1_VAL(box) : NULL;
} }
gc->mark_table[scheme_thread_type] = gc->normal_thread_mark;
gc->mark_table[scheme_custodian_type] = gc->normal_custodian_mark;
gc->mark_table[gc->ephemeron_tag] = mark_ephemeron;
gc->mark_table[gc->cust_box_tag] = gc->normal_cust_box_mark;
gc->in_unsafe_allocation_mode = 0; gc->in_unsafe_allocation_mode = 0;
gc->doing_memory_accounting = 0; gc->doing_memory_accounting = 0;
gc->old_btc_mark = gc->new_btc_mark; gc->old_btc_mark = gc->new_btc_mark;

View File

@ -1447,16 +1447,16 @@ void GC_write_barrier(void *p)
#include "sighand.c" #include "sighand.c"
void NewGC_initialize(NewGC *newgc, NewGC *parentgc) { void NewGC_initialize(NewGC *newgc, NewGC *parentgc) {
memset(newgc, 0, sizeof(NewGC));
if (parentgc) { if (parentgc) {
newgc->mark_table = ofm_malloc(NUMBER_OF_TAGS * sizeof (Mark_Proc)); newgc->mark_table = parentgc->mark_table;
newgc->fixup_table = ofm_malloc(NUMBER_OF_TAGS * sizeof (Fixup_Proc)); newgc->fixup_table = parentgc->fixup_table;
memcpy(newgc->mark_table, parentgc->mark_table, NUMBER_OF_TAGS * sizeof (Mark_Proc));
memcpy(newgc->fixup_table, parentgc->fixup_table, NUMBER_OF_TAGS * sizeof (Fixup_Proc));
} }
else { else {
newgc->mark_table = ofm_malloc_zero(NUMBER_OF_TAGS * sizeof (Mark_Proc)); newgc->mark_table = ofm_malloc_zero(NUMBER_OF_TAGS * sizeof (Mark_Proc));
newgc->fixup_table = ofm_malloc_zero(NUMBER_OF_TAGS * sizeof (Fixup_Proc)); newgc->fixup_table = ofm_malloc_zero(NUMBER_OF_TAGS * sizeof (Fixup_Proc));
# ifdef NEWGC_BTC_ACCOUNT
BTC_initialize_mark_table(newgc);
#endif
} }
mark_stack_initialize(); mark_stack_initialize();
@ -1480,10 +1480,9 @@ static NewGC *init_type_tags_worker(NewGC *parentgc, int count, int pair, int mu
{ {
NewGC *gc; NewGC *gc;
gc = ofm_malloc(sizeof(NewGC)); gc = ofm_malloc_zero(sizeof(NewGC));
/* NOTE sets the constructed GC as the new Thread Specific GC. */ /* NOTE sets the constructed GC as the new Thread Specific GC. */
GC_set_GC(gc); GC_set_GC(gc);
NewGC_initialize(gc, parentgc);
gc->weak_box_tag = weakbox; gc->weak_box_tag = weakbox;
gc->ephemeron_tag = ephemeron; gc->ephemeron_tag = ephemeron;
@ -1492,6 +1491,9 @@ static NewGC *init_type_tags_worker(NewGC *parentgc, int count, int pair, int mu
gc->cust_box_tag = custbox; gc->cust_box_tag = custbox;
# endif # endif
NewGC_initialize(gc, parentgc);
/* Our best guess at what the OS will let us allocate: */ /* Our best guess at what the OS will let us allocate: */
gc->max_pages_in_heap = determine_max_heap_size() / APAGE_SIZE; gc->max_pages_in_heap = determine_max_heap_size() / APAGE_SIZE;
/* Not all of that memory is available for allocating GCable /* Not all of that memory is available for allocating GCable
@ -1502,9 +1504,11 @@ static NewGC *init_type_tags_worker(NewGC *parentgc, int count, int pair, int mu
resize_gen0(gc, GEN0_INITIAL_SIZE); resize_gen0(gc, GEN0_INITIAL_SIZE);
GC_register_traversers(gc->weak_box_tag, size_weak_box, mark_weak_box, fixup_weak_box, 0, 0); if (!parentgc) {
GC_register_traversers(gc->ephemeron_tag, size_ephemeron, mark_ephemeron, fixup_ephemeron, 0, 0); GC_register_traversers(gc->weak_box_tag, size_weak_box, mark_weak_box, fixup_weak_box, 0, 0);
GC_register_traversers(gc->weak_array_tag, size_weak_array, mark_weak_array, fixup_weak_array, 0, 0); GC_register_traversers(gc->ephemeron_tag, size_ephemeron, mark_ephemeron, fixup_ephemeron, 0, 0);
GC_register_traversers(gc->weak_array_tag, size_weak_array, mark_weak_array, fixup_weak_array, 0, 0);
}
initialize_signal_handler(gc); initialize_signal_handler(gc);
GC_add_roots(&gc->park, (char *)&gc->park + sizeof(gc->park) + 1); GC_add_roots(&gc->park, (char *)&gc->park + sizeof(gc->park) + 1);
GC_add_roots(&gc->park_save, (char *)&gc->park_save + sizeof(gc->park_save) + 1); GC_add_roots(&gc->park_save, (char *)&gc->park_save + sizeof(gc->park_save) + 1);
@ -1579,8 +1583,15 @@ void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark,
Fixup_Proc fixup, int constant_Size, int atomic) Fixup_Proc fixup, int constant_Size, int atomic)
{ {
NewGC *gc = GC_get_GC(); NewGC *gc = GC_get_GC();
gc->mark_table[tag] = atomic ? (Mark_Proc)PAGE_ATOMIC : mark;
gc->fixup_table[tag] = fixup; int mark_tag = tag;
#ifdef NEWGC_BTC_ACCOUNT
mark_tag = BTC_get_redirect_tag(gc, mark_tag);
#endif
gc->mark_table[mark_tag] = atomic ? (Mark_Proc)PAGE_ATOMIC : mark;
gc->fixup_table[tag] = fixup;
} }
long GC_get_memory_use(void *o) long GC_get_memory_use(void *o)

View File

@ -116,10 +116,7 @@ typedef struct NewGC {
void (*unsafe_allocation_abort)(struct NewGC *); void (*unsafe_allocation_abort)(struct NewGC *);
unsigned long memory_in_use; /* the amount of memory in use */ unsigned long memory_in_use; /* the amount of memory in use */
/* blame the child saved off Mark_Proc pointers */ /* blame the child thread infos */
Mark_Proc normal_thread_mark;
Mark_Proc normal_custodian_mark;
Mark_Proc normal_cust_box_mark;
GC_Thread_Info *thread_infos; GC_Thread_Info *thread_infos;
mpage *release_pages; mpage *release_pages;

View File

@ -234,12 +234,17 @@ static int mark_ephemeron(void *p)
#ifdef NEWGC_BTC_ACCOUNT #ifdef NEWGC_BTC_ACCOUNT
static int BTC_ephemeron_mark(void *p) static int BTC_ephemeron_mark(void *p)
{ {
GC_Ephemeron *eph = (GC_Ephemeron *)p; GCTYPE *gc = GC_get_GC();
if (gc->doing_memory_accounting) {
gcMARK(eph->key); GC_Ephemeron *eph = (GC_Ephemeron *)p;
gcMARK(eph->val);
return gcBYTES_TO_WORDS(sizeof(GC_Ephemeron)); gcMARK(eph->key);
gcMARK(eph->val);
return gcBYTES_TO_WORDS(sizeof(GC_Ephemeron));
}
return mark_ephemeron(p);
} }
#endif #endif