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.
This commit is contained in:
Matthew Flatt 2015-12-01 08:14:38 -07:00
parent bef34606cb
commit 7e949d5513
6 changed files with 19 additions and 15 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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;

View File

@ -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_;

View File

@ -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
};

View File

@ -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);