From 7e949d55131d54bf9b8499089ceb061c2fcaed13 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 1 Dec 2015 08:14:38 -0700 Subject: [PATCH] GC: skip memory accounting if demand goes away Memory accounting is enabled on demand; if demand goes away --- as approximated by no live custodians having a limit or previously been queried for memory use --- then stop accounting until demand resumes. --- racket/src/racket/gc2/backtrace.c | 3 --- racket/src/racket/gc2/mem_account.c | 21 +++++++++++++++++---- racket/src/racket/gc2/newgc.h | 1 + racket/src/racket/include/schthread.h | 1 - racket/src/racket/src/schpriv.h | 1 + racket/src/racket/src/thread.c | 7 ------- 6 files changed, 19 insertions(+), 15 deletions(-) diff --git a/racket/src/racket/gc2/backtrace.c b/racket/src/racket/gc2/backtrace.c index 0d57afc930..0be2659c1c 100644 --- a/racket/src/racket/gc2/backtrace.c +++ b/racket/src/racket/gc2/backtrace.c @@ -12,7 +12,6 @@ trace_page_type TRACE_PAGE_TAGGED TRACE_PAGE_ARRAY - TRACE_PAGE_TAGGED_ARRAY TRACE_PAGE_ATOMIC TRACE_PAGE_PAIR TRACE_PAGE_MALLOCFREE @@ -73,8 +72,6 @@ static void *print_out_pointer(const char *prefix, void *p, what = NULL; } else if (trace_page_type(page) == TRACE_PAGE_ARRAY) { what = "ARRAY"; - } else if (trace_page_type(page) == TRACE_PAGE_TAGGED_ARRAY) { - what = "TARRAY"; } else if (trace_page_type(page) == TRACE_PAGE_ATOMIC) { what = "ATOMIC"; } else if (trace_page_type(page) == TRACE_PAGE_MALLOCFREE) { diff --git a/racket/src/racket/gc2/mem_account.c b/racket/src/racket/gc2/mem_account.c index fd96b7f691..ea3e8ffbdf 100644 --- a/racket/src/racket/gc2/mem_account.c +++ b/racket/src/racket/gc2/mem_account.c @@ -225,21 +225,27 @@ inline static void clean_up_owner_table(NewGC *gc) { OTEntry **owner_table = gc->owner_table; const int table_size = gc->owner_table_size; - int i; + int i, really_doing_accounting = 0; for(i = 1; i < table_size; i++) if(owner_table[i]) { /* repair or delete the originator */ if(!marked(gc, owner_table[i]->originator)) { owner_table[i]->originator = NULL; - } else + } else { owner_table[i]->originator = GC_resolve2(owner_table[i]->originator, gc); + if (((Scheme_Custodian *)owner_table[i]->originator)->really_doing_accounting) { + really_doing_accounting = 1; + } + } /* potential delete */ if(i != 1) if((owner_table[i]->memory_use == 0) && !owner_table[i]->originator) free_owner_set(gc, i); } + + gc->next_really_doing_accounting |= really_doing_accounting; } inline static uintptr_t custodian_usage(NewGC*gc, void *custodian) @@ -248,11 +254,13 @@ inline static uintptr_t custodian_usage(NewGC*gc, void *custodian) uintptr_t retval = 0; int i; + ((Scheme_Custodian *)custodian)->really_doing_accounting = 1; + if(!gc->really_doing_accounting) { if (!gc->avoid_collection) { CHECK_PARK_UNUSED(gc); gc->park[0] = custodian; - gc->really_doing_accounting = 1; + gc->next_really_doing_accounting = 1; garbage_collect(gc, 1, 0, 0, NULL); custodian = gc->park[0]; gc->park[0] = NULL; @@ -496,6 +504,9 @@ static void BTC_do_accounting(NewGC *gc) const int table_size = gc->owner_table_size; OTEntry **owner_table = gc->owner_table; + gc->really_doing_accounting = gc->next_really_doing_accounting; + gc->next_really_doing_accounting = 0; + if(gc->really_doing_accounting) { Scheme_Custodian *cur = owner_table[current_owner(gc, NULL)]->originator, *last, *parent; Scheme_Custodian_Reference *box = cur->global_next; @@ -584,12 +595,14 @@ inline static void BTC_add_account_hook(int type,void *c1,void *c2,uintptr_t b) NewGC *gc = GC_get_GC(); AccountHook *work; + ((Scheme_Custodian *)c1)->really_doing_accounting = 1; + if(!gc->really_doing_accounting) { if (!gc->avoid_collection) { CHECK_PARK_UNUSED(gc); gc->park[0] = c1; gc->park[1] = c2; - gc->really_doing_accounting = 1; + gc->next_really_doing_accounting = 1; garbage_collect(gc, 1, 0, 0, NULL); c1 = gc->park[0]; gc->park[0] = NULL; c2 = gc->park[1]; gc->park[1] = NULL; diff --git a/racket/src/racket/gc2/newgc.h b/racket/src/racket/gc2/newgc.h index 161cd563a8..5ae5ca5a5f 100644 --- a/racket/src/racket/gc2/newgc.h +++ b/racket/src/racket/gc2/newgc.h @@ -222,6 +222,7 @@ typedef struct NewGC { /* blame the child */ unsigned int doing_memory_accounting :1; unsigned int really_doing_accounting :1; + unsigned int next_really_doing_accounting :1; unsigned int old_btc_mark :1; unsigned int new_btc_mark :1; unsigned int reset_limits :1; diff --git a/racket/src/racket/include/schthread.h b/racket/src/racket/include/schthread.h index e614cf1842..817f6a3c3e 100644 --- a/racket/src/racket/include/schthread.h +++ b/racket/src/racket/include/schthread.h @@ -267,7 +267,6 @@ typedef struct Thread_Local_Variables { intptr_t scheme_current_cont_mark_stack_; intptr_t scheme_current_cont_mark_pos_; struct Scheme_Custodian *main_custodian_; - struct Scheme_Custodian *last_custodian_; struct Scheme_Hash_Table *limited_custodians_; struct Scheme_Plumber *initial_plumber_; struct Scheme_Config *initial_config_; diff --git a/racket/src/racket/src/schpriv.h b/racket/src/racket/src/schpriv.h index 3f7c44a964..a06b2eca72 100644 --- a/racket/src/racket/src/schpriv.h +++ b/racket/src/racket/src/schpriv.h @@ -755,6 +755,7 @@ struct Scheme_Custodian { int gc_owner_set; Scheme_Object *cust_boxes; int num_cust_boxes, checked_cust_boxes; + int really_doing_accounting; #endif }; diff --git a/racket/src/racket/src/thread.c b/racket/src/racket/src/thread.c index 2a20f8517e..6f74a870bf 100644 --- a/racket/src/racket/src/thread.c +++ b/racket/src/racket/src/thread.c @@ -191,7 +191,6 @@ THREAD_LOCAL_DECL(MZ_MARK_POS_TYPE scheme_current_cont_mark_pos); THREAD_LOCAL_DECL(int scheme_semaphore_fd_kqueue); THREAD_LOCAL_DECL(static Scheme_Custodian *main_custodian); -THREAD_LOCAL_DECL(static Scheme_Custodian *last_custodian); THREAD_LOCAL_DECL(static Scheme_Hash_Table *limited_custodians = NULL); READ_ONLY static Scheme_Object *initial_inspector; @@ -1084,8 +1083,6 @@ static void adjust_custodian_family(void *mgr, void *skip_move) /* Remove from global list: */ if (CUSTODIAN_FAM(r->global_next)) CUSTODIAN_FAM(CUSTODIAN_FAM(r->global_next)->global_prev) = CUSTODIAN_FAM(r->global_prev); - else - last_custodian = CUSTODIAN_FAM(r->global_prev); CUSTODIAN_FAM(CUSTODIAN_FAM(r->global_prev)->global_next) = CUSTODIAN_FAM(r->global_next); /* Add children to parent's list: */ @@ -1159,8 +1156,6 @@ void insert_custodian(Scheme_Custodian *m, Scheme_Custodian *parent) CUSTODIAN_FAM(parent->global_next) = m; if (next) CUSTODIAN_FAM(next->global_prev) = m; - else - last_custodian = m; } else { CUSTODIAN_FAM(m->global_next) = NULL; CUSTODIAN_FAM(m->global_prev) = NULL; @@ -7988,13 +7983,11 @@ static void make_initial_config(Scheme_Thread *p) init_param(cells, paramz, MZCONFIG_ERROR_PRINT_SRCLOC, scheme_true); REGISTER_SO(main_custodian); - REGISTER_SO(last_custodian); REGISTER_SO(limited_custodians); main_custodian = scheme_make_custodian(NULL); #ifdef MZ_PRECISE_GC GC_register_root_custodian(main_custodian); #endif - last_custodian = main_custodian; init_param(cells, paramz, MZCONFIG_CUSTODIAN, (Scheme_Object *)main_custodian); REGISTER_SO(initial_plumber);