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:
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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___ */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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___ */
|
||||
|
||||
Reference in New Issue
Block a user