memset(&he->stat, 0, sizeof(he->stat));
}
- if (he->ms.map)
- he->ms.map->referenced = true;
+ map__get(he->ms.map);
if (he->branch_info) {
/*
*/
he->branch_info = malloc(sizeof(*he->branch_info));
if (he->branch_info == NULL) {
+ map__zput(he->ms.map);
free(he->stat_acc);
free(he);
return NULL;
memcpy(he->branch_info, template->branch_info,
sizeof(*he->branch_info));
- if (he->branch_info->from.map)
- he->branch_info->from.map->referenced = true;
- if (he->branch_info->to.map)
- he->branch_info->to.map->referenced = true;
+ map__get(he->branch_info->from.map);
+ map__get(he->branch_info->to.map);
}
if (he->mem_info) {
- if (he->mem_info->iaddr.map)
- he->mem_info->iaddr.map->referenced = true;
- if (he->mem_info->daddr.map)
- he->mem_info->daddr.map->referenced = true;
+ map__get(he->mem_info->iaddr.map);
+ map__get(he->mem_info->daddr.map);
}
if (symbol_conf.use_callchain)
* the history counter to increment.
*/
if (he->ms.map != entry->ms.map) {
- he->ms.map = entry->ms.map;
- if (he->ms.map)
- he->ms.map->referenced = true;
+ map__put(he->ms.map);
+ he->ms.map = map__get(entry->ms.map);
}
goto out;
}
void hist_entry__delete(struct hist_entry *he)
{
thread__zput(he->thread);
- zfree(&he->branch_info);
- zfree(&he->mem_info);
+ map__zput(he->ms.map);
+
+ if (he->branch_info) {
+ map__zput(he->branch_info->from.map);
+ map__zput(he->branch_info->to.map);
+ zfree(&he->branch_info);
+ }
+
+ if (he->mem_info) {
+ map__zput(he->mem_info->iaddr.map);
+ map__zput(he->mem_info->daddr.map);
+ zfree(&he->mem_info);
+ }
+
zfree(&he->stat_acc);
free_srcline(he->srcline);
free_callchain(he->callchain);
map->unmap_ip = map__unmap_ip;
RB_CLEAR_NODE(&map->rb_node);
map->groups = NULL;
- map->referenced = false;
map->erange_warned = false;
atomic_set(&map->refcnt, 1);
}
{
maps->entries = RB_ROOT;
pthread_rwlock_init(&maps->lock, NULL);
- INIT_LIST_HEAD(&maps->removed_maps);
}
void map_groups__init(struct map_groups *mg, struct machine *machine)
}
}
-static void __maps__purge_removed_maps(struct maps *maps)
-{
- struct map *pos, *n;
-
- list_for_each_entry_safe(pos, n, &maps->removed_maps, node) {
- list_del_init(&pos->node);
- map__put(pos);
- }
-}
-
static void maps__exit(struct maps *maps)
{
pthread_rwlock_wrlock(&maps->lock);
__maps__purge(maps);
- __maps__purge_removed_maps(maps);
pthread_rwlock_unlock(&maps->lock);
}
for (i = 0; i < MAP__NR_TYPES; ++i) {
if (maps__first(&mg->maps[i]))
return false;
- if (!list_empty(&mg->maps[i].removed_maps))
- return false;
}
return true;
return printed += maps__fprintf(&mg->maps[type], fp);
}
-static size_t map_groups__fprintf_maps(struct map_groups *mg, FILE *fp)
+size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
{
size_t printed = 0, i;
for (i = 0; i < MAP__NR_TYPES; ++i)
return printed;
}
-static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
- enum map_type type, FILE *fp)
-{
- struct map *pos;
- size_t printed = 0;
-
- list_for_each_entry(pos, &mg->maps[type].removed_maps, node) {
- printed += fprintf(fp, "Map:");
- printed += map__fprintf(pos, fp);
- if (verbose > 1) {
- printed += dso__fprintf(pos->dso, type, fp);
- printed += fprintf(fp, "--\n");
- }
- }
- return printed;
-}
-
-static size_t map_groups__fprintf_removed_maps(struct map_groups *mg,
- FILE *fp)
-{
- size_t printed = 0, i;
- for (i = 0; i < MAP__NR_TYPES; ++i)
- printed += __map_groups__fprintf_removed_maps(mg, i, fp);
- return printed;
-}
-
-size_t map_groups__fprintf(struct map_groups *mg, FILE *fp)
-{
- size_t printed = map_groups__fprintf_maps(mg, fp);
- printed += fprintf(fp, "Removed maps:\n");
- return printed + map_groups__fprintf_removed_maps(mg, fp);
-}
-
static int maps__fixup_overlappings(struct maps *maps, struct map *map, FILE *fp)
{
struct rb_root *root;
map__fprintf(after, fp);
}
put_map:
- /*
- * If we have references, just move them to a separate list.
- */
- if (pos->referenced)
- list_add_tail(&pos->node, &maps->removed_maps);
- else
- map__put(pos);
+ map__put(pos);
if (err)
goto out;