/*
         * Free everything to try to do it from the rbtree in the next search
         */
+       for (unsigned int i = 0; i < maps__nr_maps(maps); i++)
+               map__put(maps__maps_by_name(maps)[i]);
+
        zfree(&maps->maps_by_name);
        maps->nr_maps_allocated = 0;
 }
                return -ENOMEM;
 
        RB_CLEAR_NODE(&new_rb_node->rb_node);
-       new_rb_node->map = map;
+       new_rb_node->map = map__get(map);
 
        while (*p != NULL) {
                parent = *p;
 
        rb_link_node(&new_rb_node->rb_node, parent, p);
        rb_insert_color(&new_rb_node->rb_node, maps__entries(maps));
-       map__get(map);
        return 0;
 }
 
                        maps->maps_by_name = maps_by_name;
                        maps->nr_maps_allocated = nr_allocate;
                }
-               maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] = map;
+               maps__maps_by_name(maps)[maps__nr_maps(maps) - 1] = map__get(map);
                __maps__sort_by_name(maps);
        }
  out:
        rb_node = maps__find_node(maps, map);
        assert(rb_node->map == map);
        __maps__remove(maps, rb_node);
-       --maps->nr_maps;
        if (maps__maps_by_name(maps))
                __maps__free_maps_by_name(maps);
+       --maps->nr_maps;
        up_write(maps__lock(maps));
 }
 
 {
        struct map_rb_node *pos, *next;
 
+       if (maps__maps_by_name(maps))
+               __maps__free_maps_by_name(maps);
+
        maps__for_each_entry_safe(maps, pos, next) {
                rb_erase_init(&pos->rb_node,  maps__entries(maps));
                map__put(pos->map);
        }
 
        next = first;
-       while (next) {
+       while (next && !err) {
                struct map_rb_node *pos = rb_entry(next, struct map_rb_node, rb_node);
                next = rb_next(&pos->rb_node);
 
 
                        before->end = map__start(map);
                        err = __maps__insert(maps, before);
-                       if (err)
+                       if (err) {
+                               map__put(before);
                                goto put_map;
+                       }
 
                        if (verbose >= 2 && !use_browser)
                                map__fprintf(before, fp);
                        assert(map__map_ip(pos->map, map__end(map)) ==
                                map__map_ip(after, map__end(map)));
                        err = __maps__insert(maps, after);
-                       if (err)
+                       if (err) {
+                               map__put(after);
                                goto put_map;
-
+                       }
                        if (verbose >= 2 && !use_browser)
                                map__fprintf(after, fp);
                        map__put(after);
                }
 put_map:
                map__put(pos->map);
-
-               if (err)
-                       goto out;
        }
-
-       err = 0;
-out:
        up_write(maps__lock(maps));
        return err;
 }
 
 
 static int map__strcmp(const void *a, const void *b)
 {
-       const struct dso *dso_a = map__dso(*(const struct map **)a);
-       const struct dso *dso_b = map__dso(*(const struct map **)b);
+       const struct map *map_a = *(const struct map **)a;
+       const struct map *map_b = *(const struct map **)b;
+       const struct dso *dso_a = map__dso(map_a);
+       const struct dso *dso_b = map__dso(map_b);
+       int ret = strcmp(dso_a->short_name, dso_b->short_name);
 
-       return strcmp(dso_a->short_name, dso_b->short_name);
+       if (ret == 0 && map_a != map_b) {
+               /*
+                * Ensure distinct but name equal maps have an order in part to
+                * aid reference counting.
+                */
+               ret = (int)map__start(map_a) - (int)map__start(map_b);
+               if (ret == 0)
+                       ret = (int)((intptr_t)map_a - (intptr_t)map_b);
+       }
+
+       return ret;
 }
 
 static int map__strcmp_name(const void *name, const void *b)
        maps->nr_maps_allocated = maps__nr_maps(maps);
 
        maps__for_each_entry(maps, rb_node)
-               maps_by_name[i++] = rb_node->map;
+               maps_by_name[i++] = map__get(rb_node->map);
 
        __maps__sort_by_name(maps);