fix O(n^2) behavior in GC accounting

svn: r12892
This commit is contained in:
Matthew Flatt 2008-12-18 21:15:34 +00:00
parent 13e58dc786
commit af45c8ca57

View File

@ -214,7 +214,6 @@ inline static void clean_up_owner_table(NewGC *gc)
inline static unsigned long custodian_usage(NewGC*gc, void *custodian) inline static unsigned long custodian_usage(NewGC*gc, void *custodian)
{ {
OTEntry **owner_table = gc->owner_table; OTEntry **owner_table = gc->owner_table;
const int table_size = gc->owner_table_size;
unsigned long retval = 0; unsigned long retval = 0;
int i; int i;
@ -225,9 +224,13 @@ inline static unsigned long custodian_usage(NewGC*gc, void *custodian)
custodian = gc->park[0]; custodian = gc->park[0];
gc->park[0] = NULL; gc->park[0] = NULL;
} }
for(i = 1; i < table_size; i++)
if(owner_table[i] && custodian_member_owner_set(gc, custodian, i)) i = custodian_to_owner_set(gc, (Scheme_Custodian *)custodian);
retval += owner_table[i]->memory_use; if (owner_table[i])
retval = owner_table[i]->memory_use;
else
retval = 0;
return gcWORDS_TO_BYTES(retval); return gcWORDS_TO_BYTES(retval);
} }
@ -416,7 +419,7 @@ static void BTC_do_accounting(NewGC *gc)
OTEntry **owner_table = gc->owner_table; OTEntry **owner_table = gc->owner_table;
if(gc->really_doing_accounting) { if(gc->really_doing_accounting) {
Scheme_Custodian *cur = owner_table[current_owner(gc, NULL)]->originator; Scheme_Custodian *cur = owner_table[current_owner(gc, NULL)]->originator, *last, *parent;
Scheme_Custodian_Reference *box = cur->global_next; Scheme_Custodian_Reference *box = cur->global_next;
int i; int i;
@ -436,6 +439,7 @@ static void BTC_do_accounting(NewGC *gc)
} }
/* walk forward for the order we want (blame parents instead of children) */ /* walk forward for the order we want (blame parents instead of children) */
last = cur;
while(cur) { while(cur) {
int owner = custodian_to_owner_set(gc, cur); int owner = custodian_to_owner_set(gc, cur);
@ -447,9 +451,25 @@ static void BTC_do_accounting(NewGC *gc)
GCDEBUG((DEBUGOUTF, "Propagating accounting marks\n")); GCDEBUG((DEBUGOUTF, "Propagating accounting marks\n"));
propagate_accounting_marks(gc); propagate_accounting_marks(gc);
last = cur;
box = cur->global_next; cur = box ? SCHEME_PTR1_VAL(box) : NULL; box = cur->global_next; cur = box ? SCHEME_PTR1_VAL(box) : NULL;
} }
/* walk backward folding totals int parent */
cur = last;
while (cur) {
int owner = custodian_to_owner_set(gc, cur);
box = cur->parent; parent = box ? SCHEME_PTR1_VAL(box) : NULL;
if (parent) {
int powner = custodian_to_owner_set(gc, parent);
owner_table[powner]->memory_use += owner_table[owner]->memory_use;
}
box = cur->global_prev; cur = box ? SCHEME_PTR1_VAL(box) : NULL;
}
gc->in_unsafe_allocation_mode = 0; gc->in_unsafe_allocation_mode = 0;
gc->doing_memory_accounting = 0; gc->doing_memory_accounting = 0;
gc->old_btc_mark = gc->new_btc_mark; gc->old_btc_mark = gc->new_btc_mark;