From 440c7918248636637ff709ba15cb2b84fa8df905 Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Mon, 24 Apr 2000 23:52:27 +0000 Subject: [PATCH] Count allocations too; dump nodes ranked by mean allocation size. --- tools/trace-malloc/bloatblame.c | 223 ++++++++++++++++++++++++-------- xpcom/base/bloatblame.c | 223 ++++++++++++++++++++++++-------- 2 files changed, 342 insertions(+), 104 deletions(-) diff --git a/tools/trace-malloc/bloatblame.c b/tools/trace-malloc/bloatblame.c index 64d8b51963bd..4485a1b3997c 100644 --- a/tools/trace-malloc/bloatblame.c +++ b/tools/trace-malloc/bloatblame.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include "prtypes.h" @@ -213,14 +214,20 @@ typedef struct graphedge graphedge; typedef struct graphnode graphnode; typedef struct callsite callsite; +typedef struct counts { + int32 direct; /* things allocated by this node's code */ + int32 total; /* direct + things from all descendents */ +} counts; + struct graphnode { PLHashEntry entry; /* key is serial or name, value must be name */ graphedge *in; graphedge *out; graphnode *up; - int32 direct; /* bytes allocated by this node's code */ - int32 total; /* direct + bytes from all descendents */ int low; /* 0 or lowest current tree walk level */ + counts bytes; /* bytes (direct and total) allocated */ + counts allocs; /* number of allocations */ + double sqsum; /* sum of squared bytes.direct */ }; #define graphnode_name(node) ((char*) (node)->entry.value) @@ -231,8 +238,7 @@ struct graphnode { struct graphedge { graphedge *next; graphnode *node; - int32 direct; - int32 total; + counts bytes; }; struct callsite { @@ -242,8 +248,8 @@ struct callsite { callsite *kids; graphnode *method; uint32 offset; - int32 direct; - int32 total; + counts bytes; + counts allocs; }; #define callsite_serial(site) ((uint32) (site)->entry.key) @@ -261,10 +267,10 @@ static void connect_nodes(graphnode *from, graphnode *to, callsite *site) * lower site's total includes all its kids' totals). */ if (!to->low || to->low < from->low) { - edge[0].direct += site->direct; - edge[1].direct += site->direct; - edge[0].total += site->total; - edge[1].total += site->total; + edge[0].bytes.direct += site->bytes.direct; + edge[1].bytes.direct += site->bytes.direct; + edge[0].bytes.total += site->bytes.total; + edge[1].bytes.total += site->bytes.total; } return; } @@ -280,8 +286,8 @@ static void connect_nodes(graphnode *from, graphnode *to, callsite *site) edge[1].node = from; edge[1].next = to->in; to->in = &edge[1]; - edge[0].direct = edge[1].direct = site->direct; - edge[0].total = edge[1].total = site->total; + edge[0].bytes.direct = edge[1].bytes.direct = site->bytes.direct; + edge[0].bytes.total = edge[1].bytes.total = site->bytes.total; } static void *generic_alloctable(void *pool, PRSize size) @@ -305,8 +311,10 @@ static PLHashEntry *graphnode_allocentry(void *pool, const void *key) if (node) { node->in = node->out = NULL; node->up = NULL; - node->direct = node->total = 0; node->low = 0; + node->bytes.direct = node->bytes.total = 0; + node->allocs.direct = node->allocs.total = 0; + node->sqsum = 0; } return &node->entry; } @@ -362,10 +370,12 @@ static void compute_callsite_totals(callsite *site) { callsite *kid; - site->total += site->direct; + site->bytes.total += site->bytes.direct; + site->allocs.total += site->allocs.direct; for (kid = site->kids; kid; kid = kid->siblings) { compute_callsite_totals(kid); - site->total += kid->total; + site->bytes.total += kid->bytes.total; + site->allocs.total += kid->allocs.total; } } @@ -383,24 +393,30 @@ static void walk_callsite_tree(callsite *site, int level, int kidnum, FILE *fp) if (meth) { pmeth = parent->method; if (pmeth && pmeth != meth) { - if (!meth->low) - meth->total += site->total; + if (!meth->low) { + meth->bytes.total += site->bytes.total; + meth->allocs.total += site->allocs.total; + } connect_nodes(pmeth, meth, site); comp = meth->up; if (comp) { pcomp = pmeth->up; if (pcomp && pcomp != comp) { - if (!comp->low) - comp->total += site->total; + if (!comp->low) { + comp->bytes.total += site->bytes.total; + comp->allocs.total += site->allocs.total; + } connect_nodes(pcomp, comp, site); lib = comp->up; if (lib) { plib = pcomp->up; if (plib && plib != lib) { - if (!lib->low) - lib->total += site->total; + if (!lib->low) { + lib->bytes.total += site->bytes.total; + lib->allocs.total += site->allocs.total; + } connect_nodes(plib, lib, site); } old_lib_low = lib->low; @@ -423,7 +439,7 @@ static void walk_callsite_tree(callsite *site, int level, int kidnum, FILE *fp) fprintf(fp, "%c%*s%3d %3d %s %lu %ld\n", site->kids ? '+' : '-', level, "", level, kidnum, meth ? graphnode_name(meth) : "???", - (unsigned long)site->direct, (long)site->total); + (unsigned long)site->bytes.direct, (long)site->bytes.total); } nkids = 0; for (kid = site->kids; kid; kid = kid->siblings) { @@ -462,15 +478,35 @@ static int node_table_compare(const void *p1, const void *p2) node1 = *(const graphnode**) p1; node2 = *(const graphnode**) p2; if (sort_by_direct) { - key1 = node1->direct; - key2 = node2->direct; + key1 = node1->bytes.direct; + key2 = node2->bytes.direct; } else { - key1 = node1->total; - key2 = node2->total; + key1 = node1->bytes.total; + key2 = node2->bytes.total; } return key2 - key1; } +static int mean_size_compare(const void *p1, const void *p2) +{ + const graphnode *node1, *node2; + double div1, div2, key1, key2; + + node1 = *(const graphnode**) p1; + node2 = *(const graphnode**) p2; + div1 = (double)node1->allocs.direct; + div2 = (double)node2->allocs.direct; + if (div1 == 0 || div2 == 0) + return div2 - div1; + key1 = (double)node1->bytes.direct / div1; + key2 = (double)node2->bytes.direct / div2; + if (key1 < key2) + return 1; + if (key1 > key2) + return -1; + return 0; +} + static const char *prettybig(uint32 num, char *buf, size_t limit) { if (num >= 1000000000) @@ -499,7 +535,7 @@ static void sort_graphedge_list(graphedge **currp) while ((curr = *currp) != NULL && curr->next) { nextp = &curr->next; while ((next = *nextp) != NULL) { - if (curr->total < next->total) { + if (curr->bytes.total < next->bytes.total) { tmp = curr->next; *currp = tmp; if (tmp == next) { @@ -532,14 +568,14 @@ static void dump_graphedge_list(graphedge *list, FILE *fp) fputs("", fp); total = 0; for (edge = list; edge; edge = edge->next) - total += edge->total; + total += edge->bytes.total; for (edge = list; edge; edge = edge->next) { const char *node_name = graphnode_name(edge->node); fprintf(fp, "" "%s (%1.2f%%)\n", node_name, node_name, - prettybig(edge->total, buf, sizeof buf), - percent(edge->total, total)); + prettybig(edge->bytes.total, buf, sizeof buf), + percent(edge->bytes.total, total)); } fputs("", fp); } @@ -547,8 +583,11 @@ static void dump_graphedge_list(graphedge *list, FILE *fp) static void dump_graph(PLHashTable *hashtbl, const char *title, FILE *fp) { uint32 i, count; - graphnode **table; - char buf1[32], buf2[32]; + graphnode **table, *node; + char *name; + size_t namelen; + char buf1[16], buf2[16], buf3[16], buf4[16]; + static char NA[] = "N/A"; count = hashtbl->nentries; table = (graphnode**) malloc(count * sizeof(graphnode*)); @@ -561,21 +600,19 @@ static void dump_graph(PLHashTable *hashtbl, const char *title, FILE *fp) fprintf(fp, "\n" - "" + "" + "" "" + "" "" "" "\n", title); for (i = 0; i < count; i++) { - graphnode *node; - char *name; - int namelen; - /* Don't bother with truly puny nodes. */ node = table[i]; - if (node->total < min_subtotal) + if (node->bytes.total < min_subtotal) break; name = graphnode_name(node); @@ -583,14 +620,19 @@ static void dump_graph(PLHashTable *hashtbl, const char *title, FILE *fp) fprintf(fp, "" "" + "" "", name, - (namelen > 60) ? 60 : namelen, name, - (namelen > 60) ? "..." : "", - prettybig(node->total, buf1, sizeof buf1), - prettybig(node->direct, buf2, sizeof buf2), - percent(node->total, calltree_root.total), - percent(node->direct, calltree_root.total)); + (namelen > 45) ? 45 : (int)namelen, name, + (namelen > 45) ? "..." : "", + prettybig(node->bytes.total, buf1, sizeof buf1), + prettybig(node->bytes.direct, buf2, sizeof buf2), + percent(node->bytes.total, calltree_root.bytes.total), + percent(node->bytes.direct, calltree_root.bytes.total), + prettybig(node->allocs.total, buf3, sizeof buf3), + prettybig(node->allocs.direct, buf4, sizeof buf4), + percent(node->allocs.total, calltree_root.allocs.total), + percent(node->allocs.direct, calltree_root.allocs.total)); sort_graphedge_list(&node->in); dump_graphedge_list(node->in, fp); @@ -600,6 +642,55 @@ static void dump_graph(PLHashTable *hashtbl, const char *title, FILE *fp) fputs("\n", fp); } + fputs("
%s
%sTotal/Direct (percents)AllocationsFan-inFan-out
%.*s%s%s/%s (%1.2f%%/%1.2f%%)%s/%s (%1.2f%%/%1.2f%%)
\n
\n", fp); + + qsort(table, count, sizeof(graphnode*), mean_size_compare); + + fprintf(fp, + "\n" + "\n" + "" + "" + "" + "" + "\n", + title); + + for (i = 0; i < count; i++) { + double allocs, bytes, mean, variance, sigma; + + node = table[i]; + allocs = (double)node->allocs.direct; + if (!allocs) + continue; + + /* Compute direct-size mean and standard deviation. */ + bytes = (double)node->bytes.direct; + mean = bytes / allocs; + variance = allocs * node->sqsum - bytes * bytes; + if (variance < 0 || allocs == 1) + variance = 0; + else + variance /= allocs * (allocs - 1); + sigma = sqrt(variance); + + name = graphnode_name(node); + namelen = strlen(name); + fprintf(fp, + "" + "" + "" + "" + "" + "", + (namelen > 65) ? 45 : (int)namelen, name, + (namelen > 65) ? "..." : "", + prettybig((uint32)mean, buf1, sizeof buf1), + prettybig((uint32)sigma, buf2, sizeof buf2), + prettybig(node->allocs.direct, buf3, sizeof buf3)); + } + fputs("
Direct Allocators
%sMean SizeStandard DeviationAllocations" + "
%.*s%s%s%s%s
\n", fp); free((void*) table); } @@ -813,7 +904,8 @@ int main(int argc, char **argv) meth = (graphnode*) *PL_HashTableRawLookup(methods, mhash, mkey); site->method = meth; site->offset = event.u.site.offset; - site->direct = site->total = 0; + site->bytes.direct = site->bytes.total = 0; + site->allocs.direct = site->allocs.total = 0; break; } @@ -823,8 +915,9 @@ int main(int argc, char **argv) const void *key; PLHashNumber hash; callsite *site; - int32 delta; + int32 size, oldsize, delta; graphnode *meth, *comp, *lib; + double sqdelta, sqszdelta; key = (const void*) event.serial; hash = hash_serial(key); @@ -835,17 +928,43 @@ int main(int argc, char **argv) continue; } - delta = (int32)event.u.alloc.size - (int32)event.u.alloc.oldsize; - site->direct += delta; + size = (int32)event.u.alloc.size; + oldsize = (int32)event.u.alloc.oldsize; + delta = size - oldsize; + site->bytes.direct += delta; + if (event.type != 'R') + site->allocs.direct++; meth = site->method; if (meth) { - meth->direct += delta; + meth->bytes.direct += delta; + sqdelta = delta * delta; + if (event.type == 'R') { + sqszdelta = ((double)size * size) + - ((double)oldsize * oldsize); + meth->sqsum += sqszdelta; + } else { + meth->sqsum += sqdelta; + meth->allocs.direct++; + } comp = meth->up; if (comp) { - comp->direct += delta; + comp->bytes.direct += delta; + if (event.type == 'R') { + comp->sqsum += sqszdelta; + } else { + comp->sqsum += sqdelta; + comp->allocs.direct++; + } lib = comp->up; - if (lib) - lib->direct += delta; + if (lib) { + lib->bytes.direct += delta; + if (event.type == 'R') { + lib->sqsum += sqszdelta; + } else { + lib->sqsum += sqdelta; + lib->allocs.direct++; + } + } } } break; diff --git a/xpcom/base/bloatblame.c b/xpcom/base/bloatblame.c index 64d8b51963bd..4485a1b3997c 100644 --- a/xpcom/base/bloatblame.c +++ b/xpcom/base/bloatblame.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include "prtypes.h" @@ -213,14 +214,20 @@ typedef struct graphedge graphedge; typedef struct graphnode graphnode; typedef struct callsite callsite; +typedef struct counts { + int32 direct; /* things allocated by this node's code */ + int32 total; /* direct + things from all descendents */ +} counts; + struct graphnode { PLHashEntry entry; /* key is serial or name, value must be name */ graphedge *in; graphedge *out; graphnode *up; - int32 direct; /* bytes allocated by this node's code */ - int32 total; /* direct + bytes from all descendents */ int low; /* 0 or lowest current tree walk level */ + counts bytes; /* bytes (direct and total) allocated */ + counts allocs; /* number of allocations */ + double sqsum; /* sum of squared bytes.direct */ }; #define graphnode_name(node) ((char*) (node)->entry.value) @@ -231,8 +238,7 @@ struct graphnode { struct graphedge { graphedge *next; graphnode *node; - int32 direct; - int32 total; + counts bytes; }; struct callsite { @@ -242,8 +248,8 @@ struct callsite { callsite *kids; graphnode *method; uint32 offset; - int32 direct; - int32 total; + counts bytes; + counts allocs; }; #define callsite_serial(site) ((uint32) (site)->entry.key) @@ -261,10 +267,10 @@ static void connect_nodes(graphnode *from, graphnode *to, callsite *site) * lower site's total includes all its kids' totals). */ if (!to->low || to->low < from->low) { - edge[0].direct += site->direct; - edge[1].direct += site->direct; - edge[0].total += site->total; - edge[1].total += site->total; + edge[0].bytes.direct += site->bytes.direct; + edge[1].bytes.direct += site->bytes.direct; + edge[0].bytes.total += site->bytes.total; + edge[1].bytes.total += site->bytes.total; } return; } @@ -280,8 +286,8 @@ static void connect_nodes(graphnode *from, graphnode *to, callsite *site) edge[1].node = from; edge[1].next = to->in; to->in = &edge[1]; - edge[0].direct = edge[1].direct = site->direct; - edge[0].total = edge[1].total = site->total; + edge[0].bytes.direct = edge[1].bytes.direct = site->bytes.direct; + edge[0].bytes.total = edge[1].bytes.total = site->bytes.total; } static void *generic_alloctable(void *pool, PRSize size) @@ -305,8 +311,10 @@ static PLHashEntry *graphnode_allocentry(void *pool, const void *key) if (node) { node->in = node->out = NULL; node->up = NULL; - node->direct = node->total = 0; node->low = 0; + node->bytes.direct = node->bytes.total = 0; + node->allocs.direct = node->allocs.total = 0; + node->sqsum = 0; } return &node->entry; } @@ -362,10 +370,12 @@ static void compute_callsite_totals(callsite *site) { callsite *kid; - site->total += site->direct; + site->bytes.total += site->bytes.direct; + site->allocs.total += site->allocs.direct; for (kid = site->kids; kid; kid = kid->siblings) { compute_callsite_totals(kid); - site->total += kid->total; + site->bytes.total += kid->bytes.total; + site->allocs.total += kid->allocs.total; } } @@ -383,24 +393,30 @@ static void walk_callsite_tree(callsite *site, int level, int kidnum, FILE *fp) if (meth) { pmeth = parent->method; if (pmeth && pmeth != meth) { - if (!meth->low) - meth->total += site->total; + if (!meth->low) { + meth->bytes.total += site->bytes.total; + meth->allocs.total += site->allocs.total; + } connect_nodes(pmeth, meth, site); comp = meth->up; if (comp) { pcomp = pmeth->up; if (pcomp && pcomp != comp) { - if (!comp->low) - comp->total += site->total; + if (!comp->low) { + comp->bytes.total += site->bytes.total; + comp->allocs.total += site->allocs.total; + } connect_nodes(pcomp, comp, site); lib = comp->up; if (lib) { plib = pcomp->up; if (plib && plib != lib) { - if (!lib->low) - lib->total += site->total; + if (!lib->low) { + lib->bytes.total += site->bytes.total; + lib->allocs.total += site->allocs.total; + } connect_nodes(plib, lib, site); } old_lib_low = lib->low; @@ -423,7 +439,7 @@ static void walk_callsite_tree(callsite *site, int level, int kidnum, FILE *fp) fprintf(fp, "%c%*s%3d %3d %s %lu %ld\n", site->kids ? '+' : '-', level, "", level, kidnum, meth ? graphnode_name(meth) : "???", - (unsigned long)site->direct, (long)site->total); + (unsigned long)site->bytes.direct, (long)site->bytes.total); } nkids = 0; for (kid = site->kids; kid; kid = kid->siblings) { @@ -462,15 +478,35 @@ static int node_table_compare(const void *p1, const void *p2) node1 = *(const graphnode**) p1; node2 = *(const graphnode**) p2; if (sort_by_direct) { - key1 = node1->direct; - key2 = node2->direct; + key1 = node1->bytes.direct; + key2 = node2->bytes.direct; } else { - key1 = node1->total; - key2 = node2->total; + key1 = node1->bytes.total; + key2 = node2->bytes.total; } return key2 - key1; } +static int mean_size_compare(const void *p1, const void *p2) +{ + const graphnode *node1, *node2; + double div1, div2, key1, key2; + + node1 = *(const graphnode**) p1; + node2 = *(const graphnode**) p2; + div1 = (double)node1->allocs.direct; + div2 = (double)node2->allocs.direct; + if (div1 == 0 || div2 == 0) + return div2 - div1; + key1 = (double)node1->bytes.direct / div1; + key2 = (double)node2->bytes.direct / div2; + if (key1 < key2) + return 1; + if (key1 > key2) + return -1; + return 0; +} + static const char *prettybig(uint32 num, char *buf, size_t limit) { if (num >= 1000000000) @@ -499,7 +535,7 @@ static void sort_graphedge_list(graphedge **currp) while ((curr = *currp) != NULL && curr->next) { nextp = &curr->next; while ((next = *nextp) != NULL) { - if (curr->total < next->total) { + if (curr->bytes.total < next->bytes.total) { tmp = curr->next; *currp = tmp; if (tmp == next) { @@ -532,14 +568,14 @@ static void dump_graphedge_list(graphedge *list, FILE *fp) fputs("", fp); total = 0; for (edge = list; edge; edge = edge->next) - total += edge->total; + total += edge->bytes.total; for (edge = list; edge; edge = edge->next) { const char *node_name = graphnode_name(edge->node); fprintf(fp, "" "%s (%1.2f%%)\n", node_name, node_name, - prettybig(edge->total, buf, sizeof buf), - percent(edge->total, total)); + prettybig(edge->bytes.total, buf, sizeof buf), + percent(edge->bytes.total, total)); } fputs("", fp); } @@ -547,8 +583,11 @@ static void dump_graphedge_list(graphedge *list, FILE *fp) static void dump_graph(PLHashTable *hashtbl, const char *title, FILE *fp) { uint32 i, count; - graphnode **table; - char buf1[32], buf2[32]; + graphnode **table, *node; + char *name; + size_t namelen; + char buf1[16], buf2[16], buf3[16], buf4[16]; + static char NA[] = "N/A"; count = hashtbl->nentries; table = (graphnode**) malloc(count * sizeof(graphnode*)); @@ -561,21 +600,19 @@ static void dump_graph(PLHashTable *hashtbl, const char *title, FILE *fp) fprintf(fp, "\n" - "" + "" + "" "" + "" "" "" "\n", title); for (i = 0; i < count; i++) { - graphnode *node; - char *name; - int namelen; - /* Don't bother with truly puny nodes. */ node = table[i]; - if (node->total < min_subtotal) + if (node->bytes.total < min_subtotal) break; name = graphnode_name(node); @@ -583,14 +620,19 @@ static void dump_graph(PLHashTable *hashtbl, const char *title, FILE *fp) fprintf(fp, "" "" + "" "", name, - (namelen > 60) ? 60 : namelen, name, - (namelen > 60) ? "..." : "", - prettybig(node->total, buf1, sizeof buf1), - prettybig(node->direct, buf2, sizeof buf2), - percent(node->total, calltree_root.total), - percent(node->direct, calltree_root.total)); + (namelen > 45) ? 45 : (int)namelen, name, + (namelen > 45) ? "..." : "", + prettybig(node->bytes.total, buf1, sizeof buf1), + prettybig(node->bytes.direct, buf2, sizeof buf2), + percent(node->bytes.total, calltree_root.bytes.total), + percent(node->bytes.direct, calltree_root.bytes.total), + prettybig(node->allocs.total, buf3, sizeof buf3), + prettybig(node->allocs.direct, buf4, sizeof buf4), + percent(node->allocs.total, calltree_root.allocs.total), + percent(node->allocs.direct, calltree_root.allocs.total)); sort_graphedge_list(&node->in); dump_graphedge_list(node->in, fp); @@ -600,6 +642,55 @@ static void dump_graph(PLHashTable *hashtbl, const char *title, FILE *fp) fputs("\n", fp); } + fputs("
%s
%sTotal/Direct (percents)AllocationsFan-inFan-out
%.*s%s%s/%s (%1.2f%%/%1.2f%%)%s/%s (%1.2f%%/%1.2f%%)
\n
\n", fp); + + qsort(table, count, sizeof(graphnode*), mean_size_compare); + + fprintf(fp, + "\n" + "\n" + "" + "" + "" + "" + "\n", + title); + + for (i = 0; i < count; i++) { + double allocs, bytes, mean, variance, sigma; + + node = table[i]; + allocs = (double)node->allocs.direct; + if (!allocs) + continue; + + /* Compute direct-size mean and standard deviation. */ + bytes = (double)node->bytes.direct; + mean = bytes / allocs; + variance = allocs * node->sqsum - bytes * bytes; + if (variance < 0 || allocs == 1) + variance = 0; + else + variance /= allocs * (allocs - 1); + sigma = sqrt(variance); + + name = graphnode_name(node); + namelen = strlen(name); + fprintf(fp, + "" + "" + "" + "" + "" + "", + (namelen > 65) ? 45 : (int)namelen, name, + (namelen > 65) ? "..." : "", + prettybig((uint32)mean, buf1, sizeof buf1), + prettybig((uint32)sigma, buf2, sizeof buf2), + prettybig(node->allocs.direct, buf3, sizeof buf3)); + } + fputs("
Direct Allocators
%sMean SizeStandard DeviationAllocations" + "
%.*s%s%s%s%s
\n", fp); free((void*) table); } @@ -813,7 +904,8 @@ int main(int argc, char **argv) meth = (graphnode*) *PL_HashTableRawLookup(methods, mhash, mkey); site->method = meth; site->offset = event.u.site.offset; - site->direct = site->total = 0; + site->bytes.direct = site->bytes.total = 0; + site->allocs.direct = site->allocs.total = 0; break; } @@ -823,8 +915,9 @@ int main(int argc, char **argv) const void *key; PLHashNumber hash; callsite *site; - int32 delta; + int32 size, oldsize, delta; graphnode *meth, *comp, *lib; + double sqdelta, sqszdelta; key = (const void*) event.serial; hash = hash_serial(key); @@ -835,17 +928,43 @@ int main(int argc, char **argv) continue; } - delta = (int32)event.u.alloc.size - (int32)event.u.alloc.oldsize; - site->direct += delta; + size = (int32)event.u.alloc.size; + oldsize = (int32)event.u.alloc.oldsize; + delta = size - oldsize; + site->bytes.direct += delta; + if (event.type != 'R') + site->allocs.direct++; meth = site->method; if (meth) { - meth->direct += delta; + meth->bytes.direct += delta; + sqdelta = delta * delta; + if (event.type == 'R') { + sqszdelta = ((double)size * size) + - ((double)oldsize * oldsize); + meth->sqsum += sqszdelta; + } else { + meth->sqsum += sqdelta; + meth->allocs.direct++; + } comp = meth->up; if (comp) { - comp->direct += delta; + comp->bytes.direct += delta; + if (event.type == 'R') { + comp->sqsum += sqszdelta; + } else { + comp->sqsum += sqdelta; + comp->allocs.direct++; + } lib = comp->up; - if (lib) - lib->direct += delta; + if (lib) { + lib->bytes.direct += delta; + if (event.type == 'R') { + lib->sqsum += sqszdelta; + } else { + lib->sqsum += sqdelta; + lib->allocs.direct++; + } + } } } break;