From 3464d8ee69ac1b33417f06dd26195e5389f2f014 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Mon, 2 Aug 2010 19:45:23 -0300 Subject: [PATCH] --- yaml --- r: 205367 b: refs/heads/master c: 0a1eae391d0d92b60cff9f55cdaf3861b4e33922 h: refs/heads/master i: 205365: b7f2caf385a1d29b872a8d94d0bc1a4cb6dea4ef 205363: 41f70b73ecb780dcbc996dcfc2e6de867b785edd 205359: 03aae3d21b5a99724ed397a280f4435b228d242b v: v3 --- [refs] | 2 +- trunk/tools/perf/util/hist.c | 2 ++ trunk/tools/perf/util/map.c | 31 +++++++++++++++++++++---------- trunk/tools/perf/util/map.h | 3 ++- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/[refs] b/[refs] index 44c4c1376af7..75d1ad06573c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 70597f21f128b7dd6a2490078bea99d704b6f8c3 +refs/heads/master: 0a1eae391d0d92b60cff9f55cdaf3861b4e33922 diff --git a/trunk/tools/perf/util/hist.c b/trunk/tools/perf/util/hist.c index a6cea2894d12..e7263d49bcf0 100644 --- a/trunk/tools/perf/util/hist.c +++ b/trunk/tools/perf/util/hist.c @@ -93,6 +93,8 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template) if (self != NULL) { *self = *template; self->nr_events = 1; + if (self->ms.map) + self->ms.map->referenced = true; if (symbol_conf.use_callchain) callchain_init(self->callchain); } diff --git a/trunk/tools/perf/util/map.c b/trunk/tools/perf/util/map.c index 801e6962b0a6..3a7eb6ec0eec 100644 --- a/trunk/tools/perf/util/map.c +++ b/trunk/tools/perf/util/map.c @@ -29,6 +29,7 @@ void map__init(struct map *self, enum map_type type, self->unmap_ip = map__unmap_ip; RB_CLEAR_NODE(&self->rb_node); self->groups = NULL; + self->referenced = false; } 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, { struct rb_root *root = &self->maps[map->type]; struct rb_node *next = rb_first(root); + int err = 0; while (next) { struct map *pos = rb_entry(next, struct map, rb_node); @@ -402,12 +404,6 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, } rb_erase(&pos->rb_node, root); - /* - * We may have references to this map, for instance in some - * hist_entry instances, so just move them to a separate - * list. - */ - list_add_tail(&pos->node, &self->removed_maps[map->type]); /* * Now check if we need to create new maps for areas not * overlapped by the new map: @@ -415,8 +411,10 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, if (map->start > pos->start) { struct map *before = map__clone(pos); - if (before == NULL) - return -ENOMEM; + if (before == NULL) { + err = -ENOMEM; + goto move_map; + } before->end = map->start - 1; map_groups__insert(self, before); @@ -427,14 +425,27 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map, if (map->end < pos->end) { struct map *after = map__clone(pos); - if (after == NULL) - return -ENOMEM; + if (after == NULL) { + err = -ENOMEM; + goto move_map; + } after->start = map->end + 1; map_groups__insert(self, after); if (verbose >= 2) map__fprintf(after, fp); } +move_map: + /* + * If we have references, just move them to a separate list. + */ + if (pos->referenced) + list_add_tail(&pos->node, &self->removed_maps[map->type]); + else + map__delete(pos); + + if (err) + return err; } return 0; diff --git a/trunk/tools/perf/util/map.h b/trunk/tools/perf/util/map.h index 5b51bbd2f734..78575796d5f3 100644 --- a/trunk/tools/perf/util/map.h +++ b/trunk/tools/perf/util/map.h @@ -29,7 +29,8 @@ struct map { }; u64 start; u64 end; - enum map_type type; + u8 /* enum map_type */ type; + bool referenced; u32 priv; u64 pgoff;