diff options
Diffstat (limited to 'tools/perf/util/map.c')
-rw-r--r-- | tools/perf/util/map.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 801e6962b0a6..3a7eb6ec0eec 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -29,6 +29,7 @@ void map__init(struct map *self, enum map_type type, | |||
29 | self->unmap_ip = map__unmap_ip; | 29 | self->unmap_ip = map__unmap_ip; |
30 | RB_CLEAR_NODE(&self->rb_node); | 30 | RB_CLEAR_NODE(&self->rb_node); |
31 | self->groups = NULL; | 31 | self->groups = NULL; |
32 | self->referenced = false; | ||
32 | } | 33 | } |
33 | 34 | ||
34 | struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, | 35 | struct map *map__new(struct list_head *dsos__list, u64 start, u64 len, |
@@ -387,6 +388,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, | |||
387 | { | 388 | { |
388 | struct rb_root *root = &self->maps[map->type]; | 389 | struct rb_root *root = &self->maps[map->type]; |
389 | struct rb_node *next = rb_first(root); | 390 | struct rb_node *next = rb_first(root); |
391 | int err = 0; | ||
390 | 392 | ||
391 | while (next) { | 393 | while (next) { |
392 | struct map *pos = rb_entry(next, struct map, rb_node); | 394 | struct map *pos = rb_entry(next, struct map, rb_node); |
@@ -403,20 +405,16 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, | |||
403 | 405 | ||
404 | rb_erase(&pos->rb_node, root); | 406 | rb_erase(&pos->rb_node, root); |
405 | /* | 407 | /* |
406 | * We may have references to this map, for instance in some | ||
407 | * hist_entry instances, so just move them to a separate | ||
408 | * list. | ||
409 | */ | ||
410 | list_add_tail(&pos->node, &self->removed_maps[map->type]); | ||
411 | /* | ||
412 | * Now check if we need to create new maps for areas not | 408 | * Now check if we need to create new maps for areas not |
413 | * overlapped by the new map: | 409 | * overlapped by the new map: |
414 | */ | 410 | */ |
415 | if (map->start > pos->start) { | 411 | if (map->start > pos->start) { |
416 | struct map *before = map__clone(pos); | 412 | struct map *before = map__clone(pos); |
417 | 413 | ||
418 | if (before == NULL) | 414 | if (before == NULL) { |
419 | return -ENOMEM; | 415 | err = -ENOMEM; |
416 | goto move_map; | ||
417 | } | ||
420 | 418 | ||
421 | before->end = map->start - 1; | 419 | before->end = map->start - 1; |
422 | map_groups__insert(self, before); | 420 | map_groups__insert(self, before); |
@@ -427,14 +425,27 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, | |||
427 | if (map->end < pos->end) { | 425 | if (map->end < pos->end) { |
428 | struct map *after = map__clone(pos); | 426 | struct map *after = map__clone(pos); |
429 | 427 | ||
430 | if (after == NULL) | 428 | if (after == NULL) { |
431 | return -ENOMEM; | 429 | err = -ENOMEM; |
430 | goto move_map; | ||
431 | } | ||
432 | 432 | ||
433 | after->start = map->end + 1; | 433 | after->start = map->end + 1; |
434 | map_groups__insert(self, after); | 434 | map_groups__insert(self, after); |
435 | if (verbose >= 2) | 435 | if (verbose >= 2) |
436 | map__fprintf(after, fp); | 436 | map__fprintf(after, fp); |
437 | } | 437 | } |
438 | move_map: | ||
439 | /* | ||
440 | * If we have references, just move them to a separate list. | ||
441 | */ | ||
442 | if (pos->referenced) | ||
443 | list_add_tail(&pos->node, &self->removed_maps[map->type]); | ||
444 | else | ||
445 | map__delete(pos); | ||
446 | |||
447 | if (err) | ||
448 | return err; | ||
438 | } | 449 | } |
439 | 450 | ||
440 | return 0; | 451 | return 0; |