From 4557c6cef19b339f14748e749aa38596ffabb54f Mon Sep 17 00:00:00 2001 From: Kevin Tew Date: Wed, 5 Nov 2008 21:06:14 +0000 Subject: [PATCH] Move Mark_Proc Fixup_Proc and memory_in_use to NewGC struct svn: r12268 --- src/mzscheme/gc2/compact.c | 31 ++++---- src/mzscheme/gc2/newgc.c | 78 ++++++++++--------- src/mzscheme/gc2/newgc_internal.h | 6 ++ .../gc2/newgc_parts/blame_the_child.c | 32 ++++---- 4 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/mzscheme/gc2/compact.c b/src/mzscheme/gc2/compact.c index 9e6d44a481..eb6661b0e9 100644 --- a/src/mzscheme/gc2/compact.c +++ b/src/mzscheme/gc2/compact.c @@ -10,6 +10,9 @@ #include #include #include +#include "gc2.h" + +#define NUMBER_OF_TAGS 512 #include "newgc_internal.h" #include "../src/schpriv.h" @@ -84,7 +87,6 @@ static THREAD_LOCAL NewGC *GC; #define INCREMENT_CYCLE_COUNT_GROWTH 1048576 -#include "gc2.h" #include "gc2_dump.h" #define BYTEPTR(x) ((char *)x) @@ -171,11 +173,10 @@ Type_Tag weak_array_tag = 42; /* set by client */ #define gc_on_free_list_tag 511 -#define _num_tags_ 512 -Size_Proc size_table[_num_tags_]; -Mark_Proc mark_table[_num_tags_]; -Fixup_Proc fixup_table[_num_tags_]; +Size_Proc size_table[NUMBER_OF_TAGS]; +Mark_Proc mark_table[NUMBER_OF_TAGS]; +Fixup_Proc fixup_table[NUMBER_OF_TAGS]; /****************** Memory Pages ******************/ @@ -762,7 +763,7 @@ static void init_tagged_mpage(void **p, MPage *page) #endif #if CHECKS - if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) { + if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) { GCPRINT(GCOUTF, "bad tag: %d at %lx\n", tag, (long)p); GCFLUSHOUT(); CRASH(7); @@ -1085,7 +1086,7 @@ void GC_mark(const void *p) #if CHECKS { Type_Tag tag = *(Type_Tag *)p; - if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) { + if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) { GCPRINT(GCOUTF, "bad tag: %d at %lx\n", tag, (long)p); CRASH(11); } @@ -1506,7 +1507,7 @@ static void do_bigblock(void **p, MPage *page, int fixup) tag = *(Type_Tag *)p; #if CHECKS - if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) { + if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) { CRASH(16); } prev_var_stack = GC_variable_stack; @@ -1627,7 +1628,7 @@ static void propagate_all_mpages() #endif #if CHECKS - if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) { + if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) { CRASH(18); } #endif @@ -2325,7 +2326,7 @@ static void fixup_tagged_mpage(void **p, MPage *page) #endif #if CHECKS - if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) { + if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) { GCFLUSHOUT(); CRASH(28); } @@ -2755,7 +2756,7 @@ static void check_ptr(void **a) Type_Tag tag; tag = *(Type_Tag *)p; - if ((tag < 0) || (tag >= _num_tags_) + if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || (!size_table[tag] && (tag != weak_box_tag) && (tag != ephemeron_tag) @@ -3202,7 +3203,7 @@ static void gcollect(int full) if (f->tagged) { Type_Tag tag = *(Type_Tag *)f->p; #if CHECKS - if ((tag < 0) || (tag >= _num_tags_) || !size_table[tag]) { + if ((tag < 0) || (tag >= NUMBER_OF_TAGS) || !size_table[tag]) { CRASH(34); } #endif @@ -4316,7 +4317,7 @@ static long scan_tagged_mpage(void **p, MPage *page, short trace_for_tag, } dump_info_array[tag]++; - dump_info_array[tag + _num_tags_] += size; + dump_info_array[tag + NUMBER_OF_TAGS] += size; if (tag == trace_for_tag) { #if KEEP_BACKPOINTERS @@ -4649,7 +4650,7 @@ void GC_dump_with_traces(int flags, } else { GCPRINT(GCOUTF, "Tag counts and sizes:\n"); GCPRINT(GCOUTF, "Begin MzScheme3m\n"); - for (i = 0; i < _num_tags_; i++) { + for (i = 0; i < NUMBER_OF_TAGS; i++) { if (dump_info_array[i]) { char *tn, buf[256]; switch(i) { @@ -4667,7 +4668,7 @@ void GC_dump_with_traces(int flags, } break; } - GCPRINT(GCOUTF, " %20.20s: %10ld %10ld\n", tn, dump_info_array[i], (dump_info_array[i + _num_tags_]) << LOG_WORD_SIZE); + GCPRINT(GCOUTF, " %20.20s: %10ld %10ld\n", tn, dump_info_array[i], (dump_info_array[i + NUMBER_OF_TAGS]) << LOG_WORD_SIZE); } } GCPRINT(GCOUTF, "End MzScheme3m\n"); diff --git a/src/mzscheme/gc2/newgc.c b/src/mzscheme/gc2/newgc.c index 7de531c2b7..094b774b0e 100644 --- a/src/mzscheme/gc2/newgc.c +++ b/src/mzscheme/gc2/newgc.c @@ -36,6 +36,9 @@ #include "gc2_dump.h" #include "../src/schpriv.h" +/* the number of tags to use for tagged objects */ +#define NUMBER_OF_TAGS 512 + #include "newgc_internal.h" static THREAD_LOCAL NewGC *GC; @@ -74,8 +77,6 @@ static THREAD_LOCAL NewGC *GC; # define LOG_WORD_SIZE 2 #endif -/* the number of tags to use for tagged objects */ -#define NUMBER_OF_TAGS 512 /* the size of a page we use for the internal mark stack */ #define STACK_PART_SIZE (1 * 1024 * 1024) @@ -295,10 +296,6 @@ static struct mpage *pages[PAGE_TYPES]; /* miscellaneous variables */ static const char *zero_sized[4]; /* all 0-sized allocs get this */ -static Mark_Proc mark_table[NUMBER_OF_TAGS]; /* the table of mark procs */ -static Fixup_Proc fixup_table[NUMBER_OF_TAGS]; /* the table of repair procs */ -static unsigned long memory_in_use = 0; /* the amount of memory in use */ -static int avoid_collection; /* These procedures modify or use the page map. The page map provides us very fast mappings from pointers to the page the reside on, if any. The page @@ -666,7 +663,7 @@ inline static void resize_gen0(unsigned long new_size) inline static void reset_nursery(void) { unsigned long new_gen0_size; - new_gen0_size = NUM((GEN0_SIZE_FACTOR * (float)memory_in_use) + GEN0_SIZE_ADDITION); + new_gen0_size = NUM((GEN0_SIZE_FACTOR * (float)GC->memory_in_use) + GEN0_SIZE_ADDITION); if(new_gen0_size > GEN0_MAX_SIZE) new_gen0_size = GEN0_MAX_SIZE; @@ -1086,6 +1083,7 @@ inline static void check_finalizers(int level) inline static void do_ordered_level3(void) { struct finalizer *temp; + Mark_Proc *mark_table = GC->mark_table; for(temp = GC_resolve(finalizers); temp; temp = GC_resolve(temp->next)) if(!marked(temp->p)) { @@ -1495,8 +1493,8 @@ void GC_gcollect(void) void GC_register_traversers(short tag, Size_Proc size, Mark_Proc mark, Fixup_Proc fixup, int constant_Size, int atomic) { - mark_table[tag] = atomic ? (Mark_Proc)PAGE_ATOMIC : mark; - fixup_table[tag] = fixup; + GC->mark_table[tag] = atomic ? (Mark_Proc)PAGE_ATOMIC : mark; + GC->fixup_table[tag] = fixup; } long GC_get_memory_use(void *o) @@ -1511,7 +1509,7 @@ long GC_get_memory_use(void *o) retval = custodian_usage(arg); } } else { - retval = gen0_size_in_use() + memory_in_use; + retval = gen0_size_in_use() + GC->memory_in_use; } return retval; @@ -1530,6 +1528,7 @@ void GC_mark(const void *const_p) { struct mpage *page; void *p = (void*)const_p; + NewGC *gc = GC; if(!p || (NUM(p) & 0x1)) { GCDEBUG((DEBUGOUTF, "Not marking %p (bad ptr)\n", p)); @@ -1606,8 +1605,8 @@ void GC_mark(const void *const_p) /* first check to see if this is an atomic object masquerading as a tagged object; if it is, then convert it */ if(type == PAGE_TAGGED) { - if((unsigned long)mark_table[*(unsigned short*)p] < PAGE_TYPES) - type = ohead->type = (int)(unsigned long)mark_table[*(unsigned short*)p]; + if((unsigned long)gc->mark_table[*(unsigned short*)p] < PAGE_TYPES) + type = ohead->type = (int)(unsigned long)gc->mark_table[*(unsigned short*)p]; } /* now set us up for the search for where to put this thing */ @@ -1682,6 +1681,7 @@ void GC_mark(const void *const_p) inline static void internal_mark(void *p) { struct mpage *page = find_page(p); + NewGC *gc = GC; /* we can assume a lot here -- like it's a valid pointer with a page -- because we vet bad cases out in GC_mark, above */ @@ -1695,10 +1695,10 @@ inline static void internal_mark(void *p) case PAGE_TAGGED: { unsigned short tag = *(unsigned short*)start; - if((unsigned long)mark_table[tag] < PAGE_TYPES) { + if((unsigned long)gc->mark_table[tag] < PAGE_TYPES) { /* atomic */ } else - mark_table[tag](start); break; + gc->mark_table[tag](start); break; } case PAGE_ATOMIC: break; case PAGE_ARRAY: while(start < end) gcMARK(*(start++)); break; @@ -1706,7 +1706,7 @@ inline static void internal_mark(void *p) case PAGE_TARRAY: { unsigned short tag = *(unsigned short *)start; end -= INSET_WORDS; - while(start < end) start += mark_table[tag](start); + while(start < end) start += gc->mark_table[tag](start); break; } } @@ -1716,7 +1716,7 @@ inline static void internal_mark(void *p) set_backtrace_source(p, info->type); switch(info->type) { - case PAGE_TAGGED: mark_table[*(unsigned short*)p](p); break; + case PAGE_TAGGED: gc->mark_table[*(unsigned short*)p](p); break; case PAGE_ATOMIC: break; case PAGE_ARRAY: { void **start = p; @@ -1728,7 +1728,7 @@ inline static void internal_mark(void *p) void **start = p; void **end = PPTR(info) + (info->size - INSET_WORDS); unsigned short tag = *(unsigned short *)start; - while(start < end) start += mark_table[tag](start); + while(start < end) start += gc->mark_table[tag](start); break; } case PAGE_XTAGGED: GC_mark_xtagged(p); break; @@ -2172,6 +2172,7 @@ static void repair_heap(void) { struct mpage *page; int i; + NewGC *gc = GC; for(i = 0; i < PAGE_TYPES; i++) { for(page = pages[i]; page; page = page->next) { @@ -2187,7 +2188,7 @@ static void repair_heap(void) page->big_page = 1; /* remove the mark */ switch(page->page_type) { case PAGE_TAGGED: - fixup_table[*(unsigned short*)start](start); + gc->fixup_table[*(unsigned short*)start](start); break; case PAGE_ATOMIC: break; case PAGE_ARRAY: @@ -2199,7 +2200,7 @@ static void repair_heap(void) case PAGE_TARRAY: { unsigned short tag = *(unsigned short *)start; end -= INSET_WORDS; - while(start < end) start += fixup_table[tag](start); + while(start < end) start += gc->fixup_table[tag](start); break; } } @@ -2216,7 +2217,7 @@ static void repair_heap(void) if(info->mark) { info->mark = 0; - fixup_table[*(unsigned short*)(start+1)](start+1); + gc->fixup_table[*(unsigned short*)(start+1)](start+1); } else { info->dead = 1; } @@ -2254,7 +2255,7 @@ static void repair_heap(void) void **tempend = (start++) + (size - INSET_WORDS); unsigned short tag = *(unsigned short*)start; while(start < tempend) - start += fixup_table[tag](start); + start += gc->fixup_table[tag](start); info->mark = 0; start = PPTR(info) + size; } else { @@ -2279,7 +2280,9 @@ static void repair_heap(void) } } -static inline void cleanup_vacated_pages(mpage *pages) { +static inline void cleanup_vacated_pages(NewGC *gc) { + mpage *pages = gc->release_pages; + /* Free pages vacated by compaction: */ while (pages) { mpage *prev = pages->next; @@ -2289,16 +2292,18 @@ static inline void cleanup_vacated_pages(mpage *pages) { free_mpage(pages); pages = prev; } + gc->release_pages = NULL; } static void clean_up_heap(void) { struct mpage *work, *prev; int i; + NewGC *gc = GC; - memory_in_use = 0; + gc->memory_in_use = 0; /* For the purposes of this little loop, s/prev/next/ */ - for(work = GC->gen0.big_pages; work; work = prev) { + for(work = gc->gen0.big_pages; work; work = prev) { prev = work->next; pagemap_remove(work); free_pages(work->addr, round_to_apage_size(work->size)); @@ -2308,7 +2313,7 @@ static void clean_up_heap(void) for(i = 0; i < PAGE_TYPES; i++) { struct mpage *prev = NULL; - if(GC->gc_full) { + if(gc->gc_full) { work = pages[i]; while(work) { if(!work->marked_on) { @@ -2337,11 +2342,10 @@ static void clean_up_heap(void) /* since we're here anyways, compute the total memory use */ for(work = pages[i]; work; work = work->next) - memory_in_use += work->size; + gc->memory_in_use += work->size; } - cleanup_vacated_pages(GC->release_pages); - GC->release_pages = NULL; + cleanup_vacated_pages(gc); } static void protect_old_pages(void) @@ -2383,23 +2387,23 @@ extern double scheme_get_inexact_milliseconds(void); static void garbage_collect(int force_full) { + NewGC *gc = GC; static unsigned long number = 0; static unsigned int since_last_full = 0; static unsigned int running_finalizers = 0; static unsigned long last_full_mem_use = (20 * 1024 * 1024); - unsigned long old_mem_use = memory_in_use; + unsigned long old_mem_use = gc->memory_in_use; unsigned long old_gen0 = GC->gen0.current_size; int next_gc_full; TIME_DECLS(); - NewGC *gc = GC; /* determine if this should be a full collection or not */ gc->gc_full = force_full || !gc->generations_available - || (since_last_full > 100) || (memory_in_use > (2 * last_full_mem_use)); + || (since_last_full > 100) || (gc->memory_in_use > (2 * last_full_mem_use)); #if 0 printf("Collection %li (full = %i): %i / %i / %i / %i %ld\n", number, gc->gc_full, force_full, !generations_available, - (since_last_full > 100), (memory_in_use > (2 * last_full_mem_use)), + (since_last_full > 100), (gc->memory_in_use > (2 * last_full_mem_use)), last_full_mem_use); #endif @@ -2527,23 +2531,23 @@ static void garbage_collect(int force_full) /* update some statistics */ if(gc->gc_full) gc->num_major_collects++; else gc->num_minor_collects++; - if(gc->peak_memory_use < memory_in_use) gc->peak_memory_use = memory_in_use; + if(gc->peak_memory_use < gc->memory_in_use) gc->peak_memory_use = gc->memory_in_use; if(gc->gc_full) since_last_full = 0; - else if((float)(memory_in_use - old_mem_use) < (0.1 * (float)old_mem_use)) + else if((float)(gc->memory_in_use - old_mem_use) < (0.1 * (float)old_mem_use)) since_last_full += 1; - else if((float)(memory_in_use - old_mem_use) < (0.4 * (float)old_mem_use)) + else if((float)(gc->memory_in_use - old_mem_use) < (0.4 * (float)old_mem_use)) since_last_full += 5; else since_last_full += 10; if(gc->gc_full) - last_full_mem_use = memory_in_use; + last_full_mem_use = gc->memory_in_use; /* inform the system (if it wants us to) that we're done with collection */ if (GC_collect_start_callback) GC_collect_end_callback(); if (GC_collect_inform_callback) - GC_collect_inform_callback(gc->gc_full, old_mem_use + old_gen0, memory_in_use); + GC_collect_inform_callback(gc->gc_full, old_mem_use + old_gen0, gc->memory_in_use); TIME_STEP("ended"); diff --git a/src/mzscheme/gc2/newgc_internal.h b/src/mzscheme/gc2/newgc_internal.h index 49d3f24a87..5e07191dd8 100644 --- a/src/mzscheme/gc2/newgc_internal.h +++ b/src/mzscheme/gc2/newgc_internal.h @@ -73,6 +73,9 @@ typedef struct Gen0 { typedef struct NewGC { Gen0 gen0; + Mark_Proc *mark_table; /* the table of mark procs */ + Fixup_Proc *fixup_table; /* the table of repair procs */ + struct NewGC *primoridal_gc; unsigned long max_heap_size; unsigned long max_pages_in_heap; @@ -81,6 +84,7 @@ typedef struct NewGC { unsigned long actual_pages_size; unsigned long in_unsafe_allocation_mode :1; void (*unsafe_allocation_abort)(); + unsigned long memory_in_use; /* the amount of memory in use */ void *park[2]; void *park_save[2]; @@ -114,6 +118,8 @@ typedef struct NewGC { void NewGC_initialize(NewGC *newgc) { memset(newgc, 0, sizeof(NewGC)); + newgc->mark_table = malloc(NUMBER_OF_TAGS * sizeof (Mark_Proc)); + newgc->fixup_table = malloc(NUMBER_OF_TAGS * sizeof (Fixup_Proc)); newgc->primoridal_gc = NULL; newgc->max_heap_size = 0; newgc->max_pages_in_heap = 0; diff --git a/src/mzscheme/gc2/newgc_parts/blame_the_child.c b/src/mzscheme/gc2/newgc_parts/blame_the_child.c index 4f48956c01..f75ae6d857 100644 --- a/src/mzscheme/gc2/newgc_parts/blame_the_child.c +++ b/src/mzscheme/gc2/newgc_parts/blame_the_child.c @@ -208,7 +208,7 @@ inline static void mark_normal_obj(struct mpage *page, void *ptr) ignore them outright. In the case of custodians, we do need to do the check; those differences are handled by replacing the mark procedure in mark_table. */ - mark_table[*(unsigned short*)ptr](ptr); + GC->mark_table[*(unsigned short*)ptr](ptr); break; } case PAGE_ATOMIC: break; @@ -224,7 +224,7 @@ inline static void mark_normal_obj(struct mpage *page, void *ptr) unsigned short tag = *(unsigned short*)ptr; void **temp = ptr, **end = PPTR(info) + (info->size - INSET_WORDS); - while(temp < end) temp += mark_table[tag](temp); + while(temp < end) temp += GC->mark_table[tag](temp); break; } case PAGE_XTAGGED: GC_mark_xtagged(ptr); break; @@ -240,10 +240,10 @@ inline static void mark_acc_big_page(struct mpage *page) case PAGE_TAGGED: { unsigned short tag = *(unsigned short*)start; - if((unsigned long)mark_table[tag] < PAGE_TYPES) { + if((unsigned long)GC->mark_table[tag] < PAGE_TYPES) { /* atomic */ } else - mark_table[tag](start); break; + GC->mark_table[tag](start); break; } case PAGE_ATOMIC: break; case PAGE_ARRAY: while(start < end) gcMARK(*(start++)); break; @@ -251,7 +251,7 @@ inline static void mark_acc_big_page(struct mpage *page) case PAGE_TARRAY: { unsigned short tag = *(unsigned short *)start; end -= INSET_WORDS; - while(start < end) start += mark_table[tag](start); + while(start < end) start += GC->mark_table[tag](start); break; } } @@ -297,14 +297,14 @@ static void do_btc_accounting(void) GC->unsafe_allocation_abort = btc_overmem_abort; if(!normal_thread_mark) { - normal_thread_mark = mark_table[scheme_thread_type]; - normal_custodian_mark = mark_table[scheme_custodian_type]; - normal_cust_box_mark = mark_table[GC->cust_box_tag]; + normal_thread_mark = GC->mark_table[scheme_thread_type]; + normal_custodian_mark = GC->mark_table[scheme_custodian_type]; + normal_cust_box_mark = GC->mark_table[GC->cust_box_tag]; } - mark_table[scheme_thread_type] = &BTC_thread_mark; - mark_table[scheme_custodian_type] = &BTC_custodian_mark; - mark_table[GC->ephemeron_tag] = btc_mark_ephemeron; - mark_table[GC->cust_box_tag] = BTC_cust_box_mark; + 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_mark_ephemeron; + GC->mark_table[GC->cust_box_tag] = BTC_cust_box_mark; /* clear the memory use numbers out */ for(i = 1; i < owner_table_top; i++) @@ -333,10 +333,10 @@ static void do_btc_accounting(void) box = cur->global_prev; cur = box ? SCHEME_PTR1_VAL(box) : NULL; } - mark_table[scheme_thread_type] = normal_thread_mark; - mark_table[scheme_custodian_type] = normal_custodian_mark; - mark_table[GC->ephemeron_tag] = mark_ephemeron; - mark_table[GC->cust_box_tag] = normal_cust_box_mark; + GC->mark_table[scheme_thread_type] = normal_thread_mark; + GC->mark_table[scheme_custodian_type] = normal_custodian_mark; + GC->mark_table[GC->ephemeron_tag] = mark_ephemeron; + GC->mark_table[GC->cust_box_tag] = normal_cust_box_mark; GC->in_unsafe_allocation_mode = 0; doing_memory_accounting = 0; old_btc_mark = new_btc_mark;