[PATCH 2/2] perf map: optimize maps__fixup_overlappings()

From: Konstantin Khlebnikov
Date: Tue Aug 07 2018 - 05:09:14 EST


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@xxxxxxxxxxxxxx>
---
tools/perf/util/map.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 89ac5b5dc218..9b3f4d244ad4 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -675,20 +675,35 @@ 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 where end > map->start, same as find_vma() */
+ 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;
+ break;

if (verbose >= 2) {