mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-23 01:10:04 +00:00
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: Konstantin Khlebnikov <khlebnikov@yandex-team.ru> Acked-by: Jiri 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@buzz Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
e5adfc3e7e
commit
6a9405b56c
2 changed files with 26 additions and 19 deletions
|
@ -381,20 +381,6 @@ struct map *map__clone(struct map *from)
|
|||
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)
|
||||
{
|
||||
return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n",
|
||||
|
@ -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)
|
||||
{
|
||||
struct rb_root *root;
|
||||
struct rb_node *next;
|
||||
struct rb_node *next, *first;
|
||||
int err = 0;
|
||||
|
||||
down_write(&maps->lock);
|
||||
|
||||
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) {
|
||||
struct map *pos = rb_entry(next, struct map, 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) {
|
||||
|
||||
|
|
|
@ -166,7 +166,6 @@ static inline void __map__zput(struct map **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_dsoname(struct map *map, FILE *fp);
|
||||
char *map__srcline(struct map *map, u64 addr, struct symbol *sym);
|
||||
|
|
Loading…
Reference in a new issue