mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 00:04:15 +08:00
perf maps: Reduce sorting for overlapping mappings
When an 'after' map is generated the 'new' map must be before it so terminate iterating and don't resort. If the entry 'pos' is entirely overlapped by the 'new' mapping then don't remove and insert the mapping, just replace - again to remove sorting. For a perf report on a perf.data file containing overlapping mappings the time numbers are: Before: real 0m9.856s user 0m9.637s sys 0m0.204s After: real 0m5.894s user 0m5.650s sys 0m0.231s Signed-off-by: Ian Rogers <irogers@google.com> Reviewed-by: James Clark <james.clark@arm.com> Cc: Steinar H . Gunderson <sesse@google.com> Signed-off-by: Namhyung Kim <namhyung@kernel.org> Link: https://lore.kernel.org/r/20240521165109.708593-3-irogers@google.com
This commit is contained in:
parent
0b90dfda22
commit
aeefb04393
@ -744,7 +744,6 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)
|
||||
int err = 0;
|
||||
FILE *fp = debug_file();
|
||||
|
||||
sort_again:
|
||||
if (!maps__maps_by_address_sorted(maps))
|
||||
__maps__sort_by_address(maps);
|
||||
|
||||
@ -820,36 +819,54 @@ sort_again:
|
||||
/* Maps are still ordered, go to next one. */
|
||||
i++;
|
||||
if (after) {
|
||||
err = __maps__insert(maps, after);
|
||||
map__put(after);
|
||||
if (err)
|
||||
goto out_err;
|
||||
if (!maps__maps_by_address_sorted(maps)) {
|
||||
/*
|
||||
* Sorting broken so invariants don't
|
||||
* hold, sort and go again.
|
||||
*/
|
||||
goto sort_again;
|
||||
}
|
||||
/*
|
||||
* Maps are still ordered, skip after and go to
|
||||
* next one (terminate loop).
|
||||
* 'before' and 'after' mean 'new' split the
|
||||
* 'pos' mapping and therefore there are no
|
||||
* later mappings.
|
||||
*/
|
||||
i++;
|
||||
err = __maps__insert(maps, new);
|
||||
if (!err)
|
||||
err = __maps__insert(maps, after);
|
||||
map__put(after);
|
||||
check_invariants(maps);
|
||||
return err;
|
||||
}
|
||||
check_invariants(maps);
|
||||
} else if (after) {
|
||||
/*
|
||||
* 'after' means 'new' split 'pos' and there are no
|
||||
* later mappings.
|
||||
*/
|
||||
map__put(maps_by_address[i]);
|
||||
maps_by_address[i] = after;
|
||||
/* Maps are ordered, go to next one. */
|
||||
i++;
|
||||
maps_by_address[i] = map__get(new);
|
||||
err = __maps__insert(maps, after);
|
||||
map__put(after);
|
||||
check_invariants(maps);
|
||||
return err;
|
||||
} else {
|
||||
struct map *next = NULL;
|
||||
|
||||
if (i + 1 < maps__nr_maps(maps))
|
||||
next = maps_by_address[i + 1];
|
||||
|
||||
if (!next || map__start(next) >= map__end(new)) {
|
||||
/*
|
||||
* Replace existing mapping and end knowing
|
||||
* there aren't later overlapping or any
|
||||
* mappings.
|
||||
*/
|
||||
map__put(maps_by_address[i]);
|
||||
maps_by_address[i] = map__get(new);
|
||||
check_invariants(maps);
|
||||
return err;
|
||||
}
|
||||
__maps__remove(maps, pos);
|
||||
check_invariants(maps);
|
||||
/*
|
||||
* Maps are ordered but no need to increase `i` as the
|
||||
* later maps were moved down.
|
||||
*/
|
||||
}
|
||||
check_invariants(maps);
|
||||
}
|
||||
/* Add the map. */
|
||||
err = __maps__insert(maps, new);
|
||||
|
Loading…
Reference in New Issue
Block a user