diff options
author | Konstantin Khlebnikov <khlebnikov@yandex-team.ru> | 2018-08-07 10:24:54 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2018-08-08 14:56:00 -0400 |
commit | 6a9405b56c274024564f9014bba97b92c91b34d6 (patch) | |
tree | b0ea4a8e47bd597333ce636c7e89a9c9a026101a | |
parent | e5adfc3e7e774ba86f7bb725c6eef5f32df8630e (diff) |
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>
-rw-r--r-- | tools/perf/util/map.c | 44 | ||||
-rw-r--r-- | tools/perf/util/map.h | 1 |
2 files changed, 26 insertions, 19 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 89ac5b5dc218..36d0763311ef 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -381,20 +381,6 @@ struct map *map__clone(struct map *from) | |||
381 | return map; | 381 | return map; |
382 | } | 382 | } |
383 | 383 | ||
384 | int map__overlap(struct map *l, struct map *r) | ||
385 | { | ||
386 | if (l->start > r->start) { | ||
387 | struct map *t = l; | ||
388 | l = r; | ||
389 | r = t; | ||
390 | } | ||
391 | |||
392 | if (l->end > r->start) | ||
393 | return 1; | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | size_t map__fprintf(struct map *map, FILE *fp) | 384 | size_t map__fprintf(struct map *map, FILE *fp) |
399 | { | 385 | { |
400 | return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %" PRIx64 " %s\n", | 386 | 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 | static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) | 661 | static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp) |
676 | { | 662 | { |
677 | struct rb_root *root; | 663 | struct rb_root *root; |
678 | struct rb_node *next; | 664 | struct rb_node *next, *first; |
679 | int err = 0; | 665 | int err = 0; |
680 | 666 | ||
681 | down_write(&maps->lock); | 667 | down_write(&maps->lock); |
682 | 668 | ||
683 | root = &maps->entries; | 669 | root = &maps->entries; |
684 | next = rb_first(root); | ||
685 | 670 | ||
671 | /* | ||
672 | * Find first map where end > map->start. | ||
673 | * Same as find_vma() in kernel. | ||
674 | */ | ||
675 | next = root->rb_node; | ||
676 | first = NULL; | ||
677 | while (next) { | ||
678 | struct map *pos = rb_entry(next, struct map, rb_node); | ||
679 | |||
680 | if (pos->end > map->start) { | ||
681 | first = next; | ||
682 | if (pos->start <= map->start) | ||
683 | break; | ||
684 | next = next->rb_left; | ||
685 | } else | ||
686 | next = next->rb_right; | ||
687 | } | ||
688 | |||
689 | next = first; | ||
686 | while (next) { | 690 | while (next) { |
687 | struct map *pos = rb_entry(next, struct map, rb_node); | 691 | struct map *pos = rb_entry(next, struct map, rb_node); |
688 | next = rb_next(&pos->rb_node); | 692 | next = rb_next(&pos->rb_node); |
689 | 693 | ||
690 | if (!map__overlap(pos, map)) | 694 | /* |
691 | continue; | 695 | * Stop if current map starts after map->end. |
696 | * Maps are ordered by start: next will not overlap for sure. | ||
697 | */ | ||
698 | if (pos->start >= map->end) | ||
699 | break; | ||
692 | 700 | ||
693 | if (verbose >= 2) { | 701 | if (verbose >= 2) { |
694 | 702 | ||
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 4cb90f242bed..e0f327b51e66 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h | |||
@@ -166,7 +166,6 @@ static inline void __map__zput(struct map **map) | |||
166 | 166 | ||
167 | #define map__zput(map) __map__zput(&map) | 167 | #define map__zput(map) __map__zput(&map) |
168 | 168 | ||
169 | int map__overlap(struct map *l, struct map *r); | ||
170 | size_t map__fprintf(struct map *map, FILE *fp); | 169 | size_t map__fprintf(struct map *map, FILE *fp); |
171 | size_t map__fprintf_dsoname(struct map *map, FILE *fp); | 170 | size_t map__fprintf_dsoname(struct map *map, FILE *fp); |
172 | char *map__srcline(struct map *map, u64 addr, struct symbol *sym); | 171 | char *map__srcline(struct map *map, u64 addr, struct symbol *sym); |