Commit 6a9405b5 authored by Konstantin Khlebnikov's avatar Konstantin Khlebnikov Committed by Arnaldo Carvalho de Melo

perf map: Optimize maps__fixup_overlappings()

This function splits and removes overlapping areas.

Maps in tree are ordered by start address thus we could find first
overlap and stop if next map does not overlap.
Signed-off-by: default avatarKonstantin Khlebnikov <khlebnikov@yandex-team.ru>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/153365189407.435244.7234821822450484712.stgit@buzzSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent e5adfc3e
...@@ -381,20 +381,6 @@ struct map *map__clone(struct map *from) ...@@ -381,20 +381,6 @@ struct map *map__clone(struct map *from)
return map; return map;
} }
int map__overlap(struct map *l, struct map *r)
{
if (l->start > r->start) {
struct map *t = l;
l = r;
r = t;
}
if (l->end > r->start)
return 1;
return 0;
}
size_t map__fprintf(struct map *map, FILE *fp) size_t map__fprintf(struct map *map, FILE *fp)
{ {
return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
...@@ -675,20 +661,42 @@ static void __map_groups__insert(struct map_groups *mg, struct map *map) ...@@ -675,20 +661,42 @@ static void __map_groups__insert(struct map_groups *mg, struct map *map)
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
{ {
struct rb_root *root; struct rb_root *root;
struct rb_node *next; struct rb_node *next, *first;
int err = 0; int err = 0;
down_write(&maps->lock); down_write(&maps->lock);
root = &maps->entries; root = &maps->entries;
next = rb_first(root);
/*
* Find first map where end > map->start.
* Same as find_vma() in kernel.
*/
next = root->rb_node;
first = NULL;
while (next) {
struct map *pos = rb_entry(next, struct map, rb_node);
if (pos->end > map->start) {
first = next;
if (pos->start <= map->start)
break;
next = next->rb_left;
} else
next = next->rb_right;
}
next = first;
while (next) { while (next) {
struct map *pos = rb_entry(next, struct map, rb_node); struct map *pos = rb_entry(next, struct map, rb_node);
next = rb_next(&pos->rb_node); next = rb_next(&pos->rb_node);
if (!map__overlap(pos, map)) /*
continue; * Stop if current map starts after map->end.
* Maps are ordered by start: next will not overlap for sure.
*/
if (pos->start >= map->end)
break;
if (verbose >= 2) { if (verbose >= 2) {
......
...@@ -166,7 +166,6 @@ static inline void __map__zput(struct map **map) ...@@ -166,7 +166,6 @@ static inline void __map__zput(struct map **map)
#define map__zput(map) __map__zput(&map) #define map__zput(map) __map__zput(&map)
int map__overlap(struct map *l, struct map *r);
size_t map__fprintf(struct map *map, FILE *fp); size_t map__fprintf(struct map *map, FILE *fp);
size_t map__fprintf_dsoname(struct map *map, FILE *fp); size_t map__fprintf_dsoname(struct map *map, FILE *fp);
char *map__srcline(struct map *map, u64 addr, struct symbol *sym); char *map__srcline(struct map *map, u64 addr, struct symbol *sym);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment