diff --git a/src/mzscheme/gc2/blame_the_child.c b/src/mzscheme/gc2/blame_the_child.c index 21fb5c08bf..5b8a21e8c7 100644 --- a/src/mzscheme/gc2/blame_the_child.c +++ b/src/mzscheme/gc2/blame_the_child.c @@ -4,6 +4,13 @@ #ifdef NEWGC_BTC_ACCOUNT #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 */ @@ -36,11 +43,12 @@ inline static void BTC_register_thread(void *t, void *c) inline static void mark_threads(NewGC *gc, int owner) { GC_Thread_Info *work; + Mark_Proc thread_mark = gc->mark_table[btc_redirect_thread]; for(work = gc->thread_infos; work; work = work->next) if(work->owner == owner) { if (((Scheme_Thread *)work->thread)->running) { - gc->normal_thread_mark(work->thread); + thread_mark(work->thread); if (work->thread == scheme_current_thread) { 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; 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 */ @@ -257,7 +266,7 @@ inline static void mark_cust_boxes(NewGC *gc, Scheme_Custodian *cur) wb = (GC_Weak_Box *)SCHEME_CAR(pr); next = SCHEME_CDR(pr); if (wb->val) { - gc->normal_cust_box_mark(wb->val); + cust_box_mark(wb->val); prev = pr; } else { if (prev) @@ -273,21 +282,32 @@ inline static void mark_cust_boxes(NewGC *gc, Scheme_Custodian *cur) 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) { NewGC *gc = GC_get_GC(); - if(custodian_to_owner_set(gc, p) == gc->current_mark_owner) - return gc->normal_custodian_mark(p); - else - return ((struct objhead *)(NUM(p) - WORD_SIZE))->size; + if (gc->doing_memory_accounting) { + if(custodian_to_owner_set(gc, p) == gc->current_mark_owner) + return gc->mark_table[btc_redirect_custodian](p); + else + return ((struct objhead *)(NUM(p) - WORD_SIZE))->size; + } + return gc->mark_table[btc_redirect_custodian](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) @@ -375,6 +395,21 @@ static void propagate_accounting_marks(NewGC *gc) 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) { 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->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 */ for(i = 1; i < table_size; 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; } - 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->doing_memory_accounting = 0; gc->old_btc_mark = gc->new_btc_mark; diff --git a/src/mzscheme/gc2/newgc.c b/src/mzscheme/gc2/newgc.c index c6bce7a3cf..6af7710f8f 100644 --- a/src/mzscheme/gc2/newgc.c +++ b/src/mzscheme/gc2/newgc.c @@ -1447,16 +1447,16 @@ void GC_write_barrier(void *p) #include "sighand.c" void NewGC_initialize(NewGC *newgc, NewGC *parentgc) { - memset(newgc, 0, sizeof(NewGC)); if (parentgc) { - newgc->mark_table = ofm_malloc(NUMBER_OF_TAGS * sizeof (Mark_Proc)); - newgc->fixup_table = ofm_malloc(NUMBER_OF_TAGS * sizeof (Fixup_Proc)); - 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)); + newgc->mark_table = parentgc->mark_table; + newgc->fixup_table = parentgc->fixup_table; } else { newgc->mark_table = ofm_malloc_zero(NUMBER_OF_TAGS * sizeof (Mark_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(); @@ -1480,10 +1480,9 @@ static NewGC *init_type_tags_worker(NewGC *parentgc, int count, int pair, int mu { NewGC *gc; - gc = ofm_malloc(sizeof(NewGC)); + gc = ofm_malloc_zero(sizeof(NewGC)); /* NOTE sets the constructed GC as the new Thread Specific GC. */ GC_set_GC(gc); - NewGC_initialize(gc, parentgc); gc->weak_box_tag = weakbox; 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; # endif + NewGC_initialize(gc, parentgc); + + /* Our best guess at what the OS will let us allocate: */ gc->max_pages_in_heap = determine_max_heap_size() / APAGE_SIZE; /* 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); - GC_register_traversers(gc->weak_box_tag, size_weak_box, mark_weak_box, fixup_weak_box, 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); + if (!parentgc) { + GC_register_traversers(gc->weak_box_tag, size_weak_box, mark_weak_box, fixup_weak_box, 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); 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); @@ -1579,8 +1583,15 @@ void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark, Fixup_Proc fixup, int constant_Size, int atomic) { 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) diff --git a/src/mzscheme/gc2/newgc.h b/src/mzscheme/gc2/newgc.h index 0c33f0bd18..435dae0d11 100644 --- a/src/mzscheme/gc2/newgc.h +++ b/src/mzscheme/gc2/newgc.h @@ -116,10 +116,7 @@ typedef struct NewGC { void (*unsafe_allocation_abort)(struct NewGC *); unsigned long memory_in_use; /* the amount of memory in use */ - /* blame the child saved off Mark_Proc pointers */ - Mark_Proc normal_thread_mark; - Mark_Proc normal_custodian_mark; - Mark_Proc normal_cust_box_mark; + /* blame the child thread infos */ GC_Thread_Info *thread_infos; mpage *release_pages; diff --git a/src/mzscheme/gc2/weak.c b/src/mzscheme/gc2/weak.c index 719d5cceef..da95fb12a7 100644 --- a/src/mzscheme/gc2/weak.c +++ b/src/mzscheme/gc2/weak.c @@ -234,12 +234,17 @@ static int mark_ephemeron(void *p) #ifdef NEWGC_BTC_ACCOUNT static int BTC_ephemeron_mark(void *p) { - GC_Ephemeron *eph = (GC_Ephemeron *)p; - - gcMARK(eph->key); - gcMARK(eph->val); + GCTYPE *gc = GC_get_GC(); + if (gc->doing_memory_accounting) { - return gcBYTES_TO_WORDS(sizeof(GC_Ephemeron)); + GC_Ephemeron *eph = (GC_Ephemeron *)p; + + gcMARK(eph->key); + gcMARK(eph->val); + + return gcBYTES_TO_WORDS(sizeof(GC_Ephemeron)); + } + return mark_ephemeron(p); } #endif