Revise connect_nodes to be tmgraphnode_connect, reusable via tmreader.[ch].

git-svn-id: svn://10.0.0.236/trunk@74793 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
brendan%mozilla.org
2000-07-26 02:19:27 +00:00
parent 65a4138aa9
commit b54049c74b
6 changed files with 148 additions and 84 deletions

View File

@@ -62,45 +62,6 @@ static int unified_output = 0;
static char *function_dump = NULL;
static uint32 min_subtotal = 0;
static void connect_nodes(tmgraphnode *from, tmgraphnode *to, tmcallsite *site)
{
tmgraphlink *link;
tmgraphedge *edge;
for (link = from->out; link; link = link->next) {
if (link->node == to) {
/*
* Say the stack looks like this: ... => JS => js => JS => js.
* We must avoid overcounting JS=>js because the first edge total
* includes the second JS=>js edge's total (which is because the
* lower site's total includes all its kids' totals).
*/
edge = TM_LINK_TO_EDGE(link, TM_EDGE_OUT_LINK);
if (!to->low || to->low < from->low) {
/* Add the direct and total counts to edge->allocs. */
edge->allocs.bytes.direct += site->allocs.bytes.direct;
edge->allocs.bytes.total += site->allocs.bytes.total;
edge->allocs.calls.direct += site->allocs.calls.direct;
edge->allocs.calls.total += site->allocs.calls.total;
}
return;
}
}
edge = (tmgraphedge*) malloc(sizeof(tmgraphedge));
if (!edge) {
perror(program);
exit(1);
}
edge->links[TM_EDGE_OUT_LINK].node = to;
edge->links[TM_EDGE_OUT_LINK].next = from->out;
from->out = &edge->links[TM_EDGE_OUT_LINK];
edge->links[TM_EDGE_IN_LINK].node = from;
edge->links[TM_EDGE_IN_LINK].next = to->in;
to->in = &edge->links[TM_EDGE_IN_LINK];
edge->allocs = site->allocs;
}
static void compute_callsite_totals(tmcallsite *site)
{
tmcallsite *kid;
@@ -132,7 +93,8 @@ static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp
meth->allocs.bytes.total += site->allocs.bytes.total;
meth->allocs.calls.total += site->allocs.calls.total;
}
connect_nodes(pmeth, meth, site);
if (!tmgraphnode_connect(pmeth, meth, site))
goto bad;
comp = meth->up;
if (comp) {
@@ -144,7 +106,8 @@ static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp
comp->allocs.calls.total
+= site->allocs.calls.total;
}
connect_nodes(pcomp, comp, site);
if (!tmgraphnode_connect(pcomp, comp, site))
goto bad;
lib = comp->up;
if (lib) {
@@ -156,7 +119,8 @@ static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp
lib->allocs.calls.total
+= site->allocs.calls.total;
}
connect_nodes(plib, lib, site);
if (!tmgraphnode_connect(plib, lib, site))
goto bad;
}
old_lib_low = lib->low;
if (!old_lib_low)
@@ -200,6 +164,11 @@ static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp
}
}
}
return;
bad:
perror(program);
exit(1);
}
/*

View File

@@ -653,3 +653,48 @@ tmcallsite *tmreader_callsite(tmreader *tmr, uint32 serial)
hash = hash_serial(key);
return (tmcallsite*) *PL_HashTableRawLookup(tmr->callsites, hash, key);
}
int tmgraphnode_connect(tmgraphnode *from, tmgraphnode *to, tmcallsite *site)
{
tmgraphlink *outlink;
tmgraphedge *edge;
for (outlink = from->out; outlink; outlink = outlink->next) {
if (outlink->node == to) {
/*
* Say the stack looks like this: ... => JS => js => JS => js.
* We must avoid overcounting JS=>js because the first edge total
* includes the second JS=>js edge's total (which is because the
* lower site's total includes all its kids' totals).
*/
edge = TM_LINK_TO_EDGE(outlink, TM_EDGE_OUT_LINK);
if (!to->low || to->low < from->low) {
/* Add the direct and total counts to edge->allocs. */
edge->allocs.bytes.direct += site->allocs.bytes.direct;
edge->allocs.bytes.total += site->allocs.bytes.total;
edge->allocs.calls.direct += site->allocs.calls.direct;
edge->allocs.calls.total += site->allocs.calls.total;
/* Now update the free counts. */
edge->frees.bytes.direct += site->frees.bytes.direct;
edge->frees.bytes.total += site->frees.bytes.total;
edge->frees.calls.direct += site->frees.calls.direct;
edge->frees.calls.total += site->frees.calls.total;
}
return 1;
}
}
edge = (tmgraphedge*) malloc(sizeof(tmgraphedge));
if (!edge)
return 0;
edge->links[TM_EDGE_OUT_LINK].node = to;
edge->links[TM_EDGE_OUT_LINK].next = from->out;
from->out = &edge->links[TM_EDGE_OUT_LINK];
edge->links[TM_EDGE_IN_LINK].node = from;
edge->links[TM_EDGE_IN_LINK].next = to->in;
to->in = &edge->links[TM_EDGE_IN_LINK];
edge->allocs = site->allocs;
edge->frees = site->frees;
return 1;
}

View File

@@ -169,6 +169,24 @@ extern tmgraphnode *tmreader_component(tmreader *tmr, const char *name);
extern tmgraphnode *tmreader_method(tmreader *tmr, uint32 serial);
extern tmcallsite *tmreader_callsite(tmreader *tmr, uint32 serial);
/*
* Connect node 'from' to node 'to' with an edge, if there isn't one already
* connecting the nodes. Add site's allocation stats to the edge only if we
* create the edge, or if we find that it exists, but that to->low is zero or
* less than from->low.
*
* If the callsite tree already totals allocation costs (tmcounts.total for
* each site includes tmcounts.direct for that site, plus tmcounts.total for
* all kid sites), then the node->low watermarks should be set from the tree
* level when walking the callsite tree, and should be set to non-zero values
* only if zero (the root is at level 0). A low watermark should be cleared
* when the tree walk unwinds past the level at which it was set non-zero.
*
* Return 0 on error (malloc failure) and 1 on success.
*/
extern int tmgraphnode_connect(tmgraphnode *from, tmgraphnode *to,
tmcallsite *site);
PR_END_EXTERN_C
#endif /* tmreader_h___ */

View File

@@ -62,45 +62,6 @@ static int unified_output = 0;
static char *function_dump = NULL;
static uint32 min_subtotal = 0;
static void connect_nodes(tmgraphnode *from, tmgraphnode *to, tmcallsite *site)
{
tmgraphlink *link;
tmgraphedge *edge;
for (link = from->out; link; link = link->next) {
if (link->node == to) {
/*
* Say the stack looks like this: ... => JS => js => JS => js.
* We must avoid overcounting JS=>js because the first edge total
* includes the second JS=>js edge's total (which is because the
* lower site's total includes all its kids' totals).
*/
edge = TM_LINK_TO_EDGE(link, TM_EDGE_OUT_LINK);
if (!to->low || to->low < from->low) {
/* Add the direct and total counts to edge->allocs. */
edge->allocs.bytes.direct += site->allocs.bytes.direct;
edge->allocs.bytes.total += site->allocs.bytes.total;
edge->allocs.calls.direct += site->allocs.calls.direct;
edge->allocs.calls.total += site->allocs.calls.total;
}
return;
}
}
edge = (tmgraphedge*) malloc(sizeof(tmgraphedge));
if (!edge) {
perror(program);
exit(1);
}
edge->links[TM_EDGE_OUT_LINK].node = to;
edge->links[TM_EDGE_OUT_LINK].next = from->out;
from->out = &edge->links[TM_EDGE_OUT_LINK];
edge->links[TM_EDGE_IN_LINK].node = from;
edge->links[TM_EDGE_IN_LINK].next = to->in;
to->in = &edge->links[TM_EDGE_IN_LINK];
edge->allocs = site->allocs;
}
static void compute_callsite_totals(tmcallsite *site)
{
tmcallsite *kid;
@@ -132,7 +93,8 @@ static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp
meth->allocs.bytes.total += site->allocs.bytes.total;
meth->allocs.calls.total += site->allocs.calls.total;
}
connect_nodes(pmeth, meth, site);
if (!tmgraphnode_connect(pmeth, meth, site))
goto bad;
comp = meth->up;
if (comp) {
@@ -144,7 +106,8 @@ static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp
comp->allocs.calls.total
+= site->allocs.calls.total;
}
connect_nodes(pcomp, comp, site);
if (!tmgraphnode_connect(pcomp, comp, site))
goto bad;
lib = comp->up;
if (lib) {
@@ -156,7 +119,8 @@ static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp
lib->allocs.calls.total
+= site->allocs.calls.total;
}
connect_nodes(plib, lib, site);
if (!tmgraphnode_connect(plib, lib, site))
goto bad;
}
old_lib_low = lib->low;
if (!old_lib_low)
@@ -200,6 +164,11 @@ static void walk_callsite_tree(tmcallsite *site, int level, int kidnum, FILE *fp
}
}
}
return;
bad:
perror(program);
exit(1);
}
/*

View File

@@ -653,3 +653,48 @@ tmcallsite *tmreader_callsite(tmreader *tmr, uint32 serial)
hash = hash_serial(key);
return (tmcallsite*) *PL_HashTableRawLookup(tmr->callsites, hash, key);
}
int tmgraphnode_connect(tmgraphnode *from, tmgraphnode *to, tmcallsite *site)
{
tmgraphlink *outlink;
tmgraphedge *edge;
for (outlink = from->out; outlink; outlink = outlink->next) {
if (outlink->node == to) {
/*
* Say the stack looks like this: ... => JS => js => JS => js.
* We must avoid overcounting JS=>js because the first edge total
* includes the second JS=>js edge's total (which is because the
* lower site's total includes all its kids' totals).
*/
edge = TM_LINK_TO_EDGE(outlink, TM_EDGE_OUT_LINK);
if (!to->low || to->low < from->low) {
/* Add the direct and total counts to edge->allocs. */
edge->allocs.bytes.direct += site->allocs.bytes.direct;
edge->allocs.bytes.total += site->allocs.bytes.total;
edge->allocs.calls.direct += site->allocs.calls.direct;
edge->allocs.calls.total += site->allocs.calls.total;
/* Now update the free counts. */
edge->frees.bytes.direct += site->frees.bytes.direct;
edge->frees.bytes.total += site->frees.bytes.total;
edge->frees.calls.direct += site->frees.calls.direct;
edge->frees.calls.total += site->frees.calls.total;
}
return 1;
}
}
edge = (tmgraphedge*) malloc(sizeof(tmgraphedge));
if (!edge)
return 0;
edge->links[TM_EDGE_OUT_LINK].node = to;
edge->links[TM_EDGE_OUT_LINK].next = from->out;
from->out = &edge->links[TM_EDGE_OUT_LINK];
edge->links[TM_EDGE_IN_LINK].node = from;
edge->links[TM_EDGE_IN_LINK].next = to->in;
to->in = &edge->links[TM_EDGE_IN_LINK];
edge->allocs = site->allocs;
edge->frees = site->frees;
return 1;
}

View File

@@ -169,6 +169,24 @@ extern tmgraphnode *tmreader_component(tmreader *tmr, const char *name);
extern tmgraphnode *tmreader_method(tmreader *tmr, uint32 serial);
extern tmcallsite *tmreader_callsite(tmreader *tmr, uint32 serial);
/*
* Connect node 'from' to node 'to' with an edge, if there isn't one already
* connecting the nodes. Add site's allocation stats to the edge only if we
* create the edge, or if we find that it exists, but that to->low is zero or
* less than from->low.
*
* If the callsite tree already totals allocation costs (tmcounts.total for
* each site includes tmcounts.direct for that site, plus tmcounts.total for
* all kid sites), then the node->low watermarks should be set from the tree
* level when walking the callsite tree, and should be set to non-zero values
* only if zero (the root is at level 0). A low watermark should be cleared
* when the tree walk unwinds past the level at which it was set non-zero.
*
* Return 0 on error (malloc failure) and 1 on success.
*/
extern int tmgraphnode_connect(tmgraphnode *from, tmgraphnode *to,
tmcallsite *site);
PR_END_EXTERN_C
#endif /* tmreader_h___ */