From d290f569bfb36039d09ec734b13cbf1e993f2e8e Mon Sep 17 00:00:00 2001 From: Kevin Tew Date: Wed, 5 Nov 2008 21:04:10 +0000 Subject: [PATCH] Split definitions out to header file, beginning of re-entry gc svn: r12248 --- src/mzscheme/gc2/commongc_internal.h | 46 ++++++++++++ src/mzscheme/gc2/compact.c | 90 ++++++++++++++---------- src/mzscheme/gc2/compactgc_internal.h | 1 + src/mzscheme/gc2/newgc.c | 42 +++++------ src/mzscheme/gc2/newgc_parts/backtrace.c | 78 ++++++++++++++++++++ src/mzscheme/gc2/weak.c | 6 +- 6 files changed, 202 insertions(+), 61 deletions(-) create mode 100644 src/mzscheme/gc2/commongc_internal.h create mode 100644 src/mzscheme/gc2/compactgc_internal.h create mode 100644 src/mzscheme/gc2/newgc_parts/backtrace.c diff --git a/src/mzscheme/gc2/commongc_internal.h b/src/mzscheme/gc2/commongc_internal.h new file mode 100644 index 0000000000..24f54799d6 --- /dev/null +++ b/src/mzscheme/gc2/commongc_internal.h @@ -0,0 +1,46 @@ +typedef short Type_Tag; + +typedef struct Roots { + long count; + long size; + /* roots is a array of longs, logically grouped into start and end pairs. + * [ start0, end0, start1, end1, ... ] + */ + unsigned long *roots; + int nothing_new; +} Roots; + +/* The GC_Weak_Array structure is not externally visible, but + clients expect a specific structure. See README for more + information. */ +typedef struct GC_Weak_Array { + Type_Tag type; + short keyex; + long count; + void *replace_val; + struct GC_Weak_Array *next; + void *data[1]; /* must be the 5th longword! */ +} GC_Weak_Array; + +/* The GC_Weak_Box struct is not externally visible, but + first three fields are mandated by the GC interface */ +typedef struct GC_Weak_Box { + Type_Tag type; + short keyex; + void *val; + /* The rest is up to us: */ + void **secondary_erase; + int soffset; + struct GC_Weak_Box *next; +} GC_Weak_Box; + +/* The GC_Ephemeron struct is not externally visible, but + first three fields are mandated by the GC interface */ +typedef struct GC_Ephemeron { + Type_Tag type; + short keyex; + void *key; + void *val; + /* The rest is up to us: */ + struct GC_Ephemeron *next; +} GC_Ephemeron; diff --git a/src/mzscheme/gc2/compact.c b/src/mzscheme/gc2/compact.c index d5e3d4fbeb..a84e94e812 100644 --- a/src/mzscheme/gc2/compact.c +++ b/src/mzscheme/gc2/compact.c @@ -10,6 +10,10 @@ #include #include #include +#include "newgc_internal.h" +#include "../src/schpriv.h" + +static THREAD_LOCAL NewGC *GC; /**************** Configuration ****************/ @@ -79,7 +83,6 @@ #define INCREMENT_CYCLE_COUNT_GROWTH 1048576 -typedef short Type_Tag; #include "gc2.h" #include "gc2_dump.h" @@ -2867,63 +2870,74 @@ static long started, rightnow, old; # define PRINTTIME(x) /* empty */ #endif -static void do_roots(int fixup) +static void mark_roots() { ImmobileBox *ib; int i; - for (i = 0; i < roots_count; i += 2) { - void **s = (void **)roots[i]; - void **e = (void **)roots[i + 1]; - + for (i = 0; i < roots->count; i += 2) { + void **s = (void **)roots->roots[i]; + void **e = (void **)roots->roots[i + 1]; + while (s < e) { - if (fixup) { - gcFIXUP(*s); - } else { #if RECORD_MARK_SRC - mark_src = s; - mark_type = MTYPE_ROOT; + mark_src = s; + mark_type = MTYPE_ROOT; #endif - gcMARK(*s); - } + gcMARK(*s); s++; } } - if (fixup) - GC_fixup_variable_stack(GC_variable_stack, - 0, - (void *)(GC_get_thread_stack_base - ? GC_get_thread_stack_base() - : stack_base), - NULL); - else { #if RECORD_MARK_SRC - record_stack_source = 1; + record_stack_source = 1; #endif - GC_mark_variable_stack(GC_variable_stack, - 0, - (void *)(GC_get_thread_stack_base - ? GC_get_thread_stack_base() - : stack_base), - NULL); + GC_mark_variable_stack(GC_variable_stack, + 0, + (void *)(GC_get_thread_stack_base + ? GC_get_thread_stack_base() + : stack_base), + NULL); #if RECORD_MARK_SRC - record_stack_source = 0; + record_stack_source = 0; #endif - } /* Do immobiles: */ for (ib = immobile; ib; ib = ib->next) { - if (fixup) { - gcFIXUP(ib->p); - } else { #if RECORD_MARK_SRC - mark_src = ib; - mark_type = MTYPE_IMMOBILE; + mark_src = ib; + mark_type = MTYPE_IMMOBILE; #endif - gcMARK(ib->p); + gcMARK(ib->p); + } +} + +static void fixup_roots() +{ + ImmobileBox *ib; + int i; + + for (i = 0; i < roots->count; i += 2) { + void **s = (void **)roots->roots[i]; + void **e = (void **)roots->roots[i + 1]; + + while (s < e) { + gcFIXUP(*s); + s++; } } + + GC_fixup_variable_stack(GC_variable_stack, + 0, + (void *)(GC_get_thread_stack_base + ? GC_get_thread_stack_base() + : stack_base), + NULL); + + /* Do immobiles: */ + for (ib = immobile; ib; ib = ib->next) { + gcFIXUP(ib->p); + } } static void gcollect(int full) @@ -3033,7 +3047,7 @@ static void gcollect(int full) mark_calls = mark_hits = mark_recalls = mark_colors = mark_many = mark_slow = 0; #endif - do_roots(0); + mark_roots(); { Fnl *f; @@ -3392,7 +3406,7 @@ static void gcollect(int full) scanned_pages = 0; - do_roots(1); + fixup_roots(); { Fnl *f; diff --git a/src/mzscheme/gc2/compactgc_internal.h b/src/mzscheme/gc2/compactgc_internal.h new file mode 100644 index 0000000000..67948544ad --- /dev/null +++ b/src/mzscheme/gc2/compactgc_internal.h @@ -0,0 +1 @@ +#include "commongc_internal.h" diff --git a/src/mzscheme/gc2/newgc.c b/src/mzscheme/gc2/newgc.c index 020e31c604..994f3ad93e 100644 --- a/src/mzscheme/gc2/newgc.c +++ b/src/mzscheme/gc2/newgc.c @@ -36,6 +36,8 @@ #include "newgc_internal.h" #include "../src/schpriv.h" +static THREAD_LOCAL NewGC *GC; + #ifdef _WIN32 # include # define bzero(m, s) memset(m, 0, s) @@ -1292,15 +1294,11 @@ inline static void reset_weak_finalizers(void) /* weak boxes and arrays */ /*****************************************************************************/ -static unsigned short weak_array_tag; -static unsigned short weak_box_tag; -static unsigned short ephemeron_tag; - #define is_marked(p) marked(p) - #define weak_box_resolve(p) GC_resolve(p) - #include "weak.c" +#undef is_marked +#undef weak_box_resolve /*****************************************************************************/ /* thread list */ @@ -1317,7 +1315,6 @@ struct gc_thread_info { static Mark_Proc normal_thread_mark = NULL, normal_custodian_mark = NULL, normal_cust_box_mark = NULL; static struct gc_thread_info *threads = NULL; -static unsigned short cust_box_tag; inline static void register_new_thread(void *t, void *c) { @@ -1523,7 +1520,7 @@ inline static void reset_pointer_stack(void) int_top->top = PPTR(int_top) + 4; } -#include "newgc_parts/btc.c" +#include "newgc_parts/blame_the_child.c" int GC_set_account_hook(int type, void *c1, unsigned long b, void *c2) { @@ -1569,14 +1566,18 @@ void GC_init_type_tags(int count, int pair, int mutable_pair, int weakbox, int e { static int initialized = 0; - weak_box_tag = weakbox; - ephemeron_tag = ephemeron; - weak_array_tag = weakarray; -# ifdef NEWGC_BTC_ACCOUNT - cust_box_tag = custbox; -# endif if(!initialized) { + GC = malloc(sizeof(NewGC)); + NewGC_initialize(GC); + + GC->weak_box_tag = weakbox; + GC->ephemeron_tag = ephemeron; + GC->weak_array_tag = weakarray; +# ifdef NEWGC_BTC_ACCOUNT + GC->cust_box_tag = custbox; +# endif + initialized = 1; /* Our best guess at what the OS will let us allocate: */ max_heap_size = determine_max_heap_size(); @@ -1589,18 +1590,19 @@ void GC_init_type_tags(int count, int pair, int mutable_pair, int weakbox, int e resize_gen0(INIT_GEN0_SIZE); - GC_register_traversers(weak_box_tag, size_weak_box, mark_weak_box, - fixup_weak_box, 0, 0); - GC_register_traversers(ephemeron_tag, size_ephemeron, mark_ephemeron, - fixup_ephemeron, 0, 0); - GC_register_traversers(weak_array_tag, size_weak_array, mark_weak_array, - fixup_weak_array, 0, 0); + 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_add_roots(&park, (char *)&park + sizeof(park) + 1); GC_add_roots(&park_save, (char *)&park_save + sizeof(park_save) + 1); initialize_protect_page_ranges(malloc_dirty_pages(APAGE_SIZE, APAGE_SIZE), APAGE_SIZE); } + else { + GCPRINT(GCOUTF, "HEY WHATS UP.\n"); + abort(); + } } void GC_gcollect(void) diff --git a/src/mzscheme/gc2/newgc_parts/backtrace.c b/src/mzscheme/gc2/newgc_parts/backtrace.c new file mode 100644 index 0000000000..8ffd470ec1 --- /dev/null +++ b/src/mzscheme/gc2/newgc_parts/backtrace.c @@ -0,0 +1,78 @@ +/*****************************************************************************/ +/* Backtrace */ +/*****************************************************************************/ + +#if MZ_GC_BACKTRACE + +static void backtrace_new_page(struct mpage *page) +{ + /* This is a little wastefull for big pages, because we'll + only use the first few words: */ + page->backtrace = (void **)malloc_pages(APAGE_SIZE, APAGE_SIZE); +} + +static void free_backtrace(struct mpage *page) +{ + free_pages(page->backtrace, APAGE_SIZE); +} + +static void *bt_source; +static int bt_type; + +static void set_backtrace_source(void *source, int type) +{ + bt_source = source; + bt_type = type; +} + +static void record_backtrace(struct mpage *page, void *ptr) +/* ptr is after objhead */ +{ + unsigned long delta; + + delta = PPTR(ptr) - PPTR(page->addr); + page->backtrace[delta - 1] = bt_source; + ((long *)page->backtrace)[delta] = bt_type; +} + +static void copy_backtrace_source(struct mpage *to_page, void *to_ptr, + struct mpage *from_page, void *from_ptr) +/* ptrs are at objhead */ +{ + unsigned long to_delta, from_delta; + + to_delta = PPTR(to_ptr) - PPTR(to_page->addr); + from_delta = PPTR(from_ptr) - PPTR(from_page->addr); + + to_page->backtrace[to_delta] = from_page->backtrace[from_delta]; + to_page->backtrace[to_delta+1] = from_page->backtrace[from_delta+1]; +} + + +static void *get_backtrace(struct mpage *page, void *ptr) +/* ptr is after objhead */ +{ + unsigned long delta; + + if (page->big_page) + ptr = PTR(page->addr + PREFIX_SIZE + WORD_SIZE); + + delta = PPTR(ptr) - PPTR(page->addr); + return page->backtrace[delta - 1]; +} + + +# define BT_STACK (PAGE_TYPES + 0) +# define BT_ROOT (PAGE_TYPES + 1) +# define BT_FINALIZER (PAGE_TYPES + 2) +# define BT_WEAKLINK (PAGE_TYPES + 3) +# define BT_IMMOBILE (PAGE_TYPES + 4) + +#else +# define backtrace_new_page(page) /* */ +# define free_backtrace(page) /* */ +# define set_backtrace_source(ptr, type) /* */ +# define record_backtrace(page, ptr) /* */ +# define copy_backtrace_source(to_page, to_ptr, from_page, from_ptr) /* */ +#endif + diff --git a/src/mzscheme/gc2/weak.c b/src/mzscheme/gc2/weak.c index 2d63c985e4..1397ae8963 100644 --- a/src/mzscheme/gc2/weak.c +++ b/src/mzscheme/gc2/weak.c @@ -97,7 +97,7 @@ void *GC_malloc_weak_array(size_t size_in_bytes, void *replace_val) replace_val = park[0]; park[0] = NULL; - w->type = weak_array_tag; + w->type = GC->weak_array_tag; w->replace_val = replace_val; w->count = (size_in_bytes >> LOG_WORD_SIZE); @@ -178,7 +178,7 @@ void *GC_malloc_weak_box(void *p, void **secondary, int soffset) secondary = (void **)park[1]; park[1] = NULL; - w->type = weak_box_tag; + w->type = GC->weak_box_tag; w->val = p; w->secondary_erase = secondary; w->soffset = soffset; @@ -272,7 +272,7 @@ void *GC_malloc_ephemeron(void *k, void *v) v = park[1]; park[1] = NULL; - eph->type = ephemeron_tag; + eph->type = GC->ephemeron_tag; eph->key = k; eph->val = v;