[libbacktrace] Reduce memory usage in build_address_map
authorTom de Vries <tdevries@suse.de>
Fri, 28 Dec 2018 03:43:56 +0000 (03:43 +0000)
committerTom de Vries <vries@gcc.gnu.org>
Fri, 28 Dec 2018 03:43:56 +0000 (03:43 +0000)
In build_address_map we allocate a unit, and then look for addresses in the
unit, which we store in the addrs vector, with the elements pointing to the
unit.  However, if we cannot find addresses in the unit, the allocated unit is
not used.

Fix this by detecting if the allocated unit has been used, and reusing it
otherwise.

Bootstrapped and reg-tested on x86_64.

2018-12-28  Tom de Vries  <tdevries@suse.de>

* dwarf.c (build_address_map): Reuse unused units.

From-SVN: r267445

libbacktrace/ChangeLog
libbacktrace/dwarf.c

index ee31ef0dd5e5f8f6b9542d822e6bd55f0c985b40..c8ddf43c71f61cf7237bf30043e782b59a143c07 100644 (file)
@@ -1,3 +1,7 @@
+2018-12-28  Tom de Vries  <tdevries@suse.de>
+
+       * dwarf.c (build_address_map): Reuse unused units.
+
 2018-12-28  Tom de Vries  <tdevries@suse.de>
 
        * dwarf.c (build_address_map): Simplify by removing local variable
index 7ef99bdd7f2a6ef5007ad61f351289445e47abf0..733da19ebf340dda410d9b9eff9b4ef3a0f9cf3c 100644 (file)
@@ -1436,9 +1436,11 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
   size_t units_count;
   size_t i;
   struct unit **pu;
+  size_t prev_addrs_count;
 
   memset (&addrs->vec, 0, sizeof addrs->vec);
   addrs->count = 0;
+  prev_addrs_count = 0;
 
   /* Read through the .debug_info section.  FIXME: Should we use the
      .debug_aranges section?  gdb and addr2line don't use it, but I'm
@@ -1534,6 +1536,18 @@ build_address_map (struct backtrace_state *state, uintptr_t base_address,
 
       if (unit_buf.reported_underflow)
        goto fail;
+
+      if (addrs->count > prev_addrs_count)
+       prev_addrs_count = addrs->count;
+      else
+       {
+         /* Unit was not used; remove it from the vector.  */
+         --units_count;
+         units.size -= sizeof (u);
+         units.alc += sizeof (u);
+         free_abbrevs (state, &u->abbrevs, error_callback, data);
+         backtrace_free (state, u, sizeof *u, error_callback, data);
+       }
     }
   if (info.reported_underflow)
     goto fail;