diff options
Diffstat (limited to 'tools/perf/util/hist.c')
| -rw-r--r-- | tools/perf/util/hist.c | 79 | 
1 files changed, 63 insertions, 16 deletions
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 82df1b26f0d4..8170a3d11ffa 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c @@ -82,6 +82,9 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)  		hists__new_col_len(hists, HISTC_DSO, len);  	} +	if (h->parent) +		hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen); +  	if (h->branch_info) {  		int symlen;  		/* @@ -242,6 +245,14 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)  		if (he->ms.map)  			he->ms.map->referenced = true; + +		if (he->branch_info) { +			if (he->branch_info->from.map) +				he->branch_info->from.map->referenced = true; +			if (he->branch_info->to.map) +				he->branch_info->to.map->referenced = true; +		} +  		if (symbol_conf.use_callchain)  			callchain_init(he->callchain); @@ -251,7 +262,7 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)  	return he;  } -static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h) +void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h)  {  	if (!h->filtered) {  		hists__calc_col_len(hists, h); @@ -285,7 +296,13 @@ static struct hist_entry *add_hist_entry(struct hists *hists,  		parent = *p;  		he = rb_entry(parent, struct hist_entry, rb_node_in); -		cmp = hist_entry__cmp(entry, he); +		/* +		 * Make sure that it receives arguments in a same order as +		 * hist_entry__collapse() so that we can use an appropriate +		 * function when searching an entry regardless which sort +		 * keys were used. +		 */ +		cmp = hist_entry__cmp(he, entry);  		if (!cmp) {  			he_stat__add_period(&he->stat, period); @@ -711,25 +728,38 @@ int hist_entry__annotate(struct hist_entry *he, size_t privsize)  	return symbol__annotate(he->ms.sym, he->ms.map, privsize);  } +void events_stats__inc(struct events_stats *stats, u32 type) +{ +	++stats->nr_events[0]; +	++stats->nr_events[type]; +} +  void hists__inc_nr_events(struct hists *hists, u32 type)  { -	++hists->stats.nr_events[0]; -	++hists->stats.nr_events[type]; +	events_stats__inc(&hists->stats, type);  }  static struct hist_entry *hists__add_dummy_entry(struct hists *hists,  						 struct hist_entry *pair)  { -	struct rb_node **p = &hists->entries.rb_node; +	struct rb_root *root; +	struct rb_node **p;  	struct rb_node *parent = NULL;  	struct hist_entry *he;  	int cmp; +	if (sort__need_collapse) +		root = &hists->entries_collapsed; +	else +		root = hists->entries_in; + +	p = &root->rb_node; +  	while (*p != NULL) {  		parent = *p; -		he = rb_entry(parent, struct hist_entry, rb_node); +		he = rb_entry(parent, struct hist_entry, rb_node_in); -		cmp = hist_entry__cmp(pair, he); +		cmp = hist_entry__collapse(he, pair);  		if (!cmp)  			goto out; @@ -744,8 +774,8 @@ static struct hist_entry *hists__add_dummy_entry(struct hists *hists,  	if (he) {  		memset(&he->stat, 0, sizeof(he->stat));  		he->hists = hists; -		rb_link_node(&he->rb_node, parent, p); -		rb_insert_color(&he->rb_node, &hists->entries); +		rb_link_node(&he->rb_node_in, parent, p); +		rb_insert_color(&he->rb_node_in, root);  		hists__inc_nr_entries(hists, he);  	}  out: @@ -755,11 +785,16 @@ out:  static struct hist_entry *hists__find_entry(struct hists *hists,  					    struct hist_entry *he)  { -	struct rb_node *n = hists->entries.rb_node; +	struct rb_node *n; + +	if (sort__need_collapse) +		n = hists->entries_collapsed.rb_node; +	else +		n = hists->entries_in->rb_node;  	while (n) { -		struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node); -		int64_t cmp = hist_entry__cmp(he, iter); +		struct hist_entry *iter = rb_entry(n, struct hist_entry, rb_node_in); +		int64_t cmp = hist_entry__collapse(iter, he);  		if (cmp < 0)  			n = n->rb_left; @@ -777,11 +812,17 @@ static struct hist_entry *hists__find_entry(struct hists *hists,   */  void hists__match(struct hists *leader, struct hists *other)  { +	struct rb_root *root;  	struct rb_node *nd;  	struct hist_entry *pos, *pair; -	for (nd = rb_first(&leader->entries); nd; nd = rb_next(nd)) { -		pos  = rb_entry(nd, struct hist_entry, rb_node); +	if (sort__need_collapse) +		root = &leader->entries_collapsed; +	else +		root = leader->entries_in; + +	for (nd = rb_first(root); nd; nd = rb_next(nd)) { +		pos  = rb_entry(nd, struct hist_entry, rb_node_in);  		pair = hists__find_entry(other, pos);  		if (pair) @@ -796,11 +837,17 @@ void hists__match(struct hists *leader, struct hists *other)   */  int hists__link(struct hists *leader, struct hists *other)  { +	struct rb_root *root;  	struct rb_node *nd;  	struct hist_entry *pos, *pair; -	for (nd = rb_first(&other->entries); nd; nd = rb_next(nd)) { -		pos = rb_entry(nd, struct hist_entry, rb_node); +	if (sort__need_collapse) +		root = &other->entries_collapsed; +	else +		root = other->entries_in; + +	for (nd = rb_first(root); nd; nd = rb_next(nd)) { +		pos = rb_entry(nd, struct hist_entry, rb_node_in);  		if (!hist_entry__has_pairs(pos)) {  			pair = hists__add_dummy_entry(leader, pos);  | 
