re PR other/68239 (libbacktrace allocation is sometimes very slow)
authorIan Lance Taylor <iant@golang.org>
Thu, 25 Jan 2018 02:24:45 +0000 (02:24 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 25 Jan 2018 02:24:45 +0000 (02:24 +0000)
PR other/68239
* mmap.c (backtrace_free_locked): Don't put more than 16 entries
on the free list.

From-SVN: r257039

libbacktrace/ChangeLog
libbacktrace/mmap.c

index 1fcca776759e51cc623faeb06dd1756e0cc89731..2d89ea1dd6c772a0e537f8a9d274c5b96625e070 100644 (file)
@@ -1,3 +1,9 @@
+2018-01-24  Ian Lance Taylor  <iant@golang.org>
+
+       PR other/68239
+       * mmap.c (backtrace_free_locked): Don't put more than 16 entries
+       on the free list.
+
 2018-01-19  Tony Reix  <tony.reix@atos.net>
 
        * xcoff.c (xcoff_incl_compare): New function.
index 41bbc71d46349f6cf178989ede1d1ca2b574f129..32fcba6239927f19ed36f0f2a4fec63a92457e77 100644 (file)
@@ -69,11 +69,33 @@ struct backtrace_freelist_struct
 static void
 backtrace_free_locked (struct backtrace_state *state, void *addr, size_t size)
 {
-  /* Just leak small blocks.  We don't have to be perfect.  */
+  /* Just leak small blocks.  We don't have to be perfect.  Don't put
+     more than 16 entries on the free list, to avoid wasting time
+     searching when allocating a block.  If we have more than 16
+     entries, leak the smallest entry.  */
+
   if (size >= sizeof (struct backtrace_freelist_struct))
     {
+      size_t c;
+      struct backtrace_freelist_struct **ppsmall;
+      struct backtrace_freelist_struct **pp;
       struct backtrace_freelist_struct *p;
 
+      c = 0;
+      ppsmall = NULL;
+      for (pp = &state->freelist; *pp != NULL; pp = &(*pp)->next)
+       {
+         if (ppsmall == NULL || (*pp)->size < (*ppsmall)->size)
+           ppsmall = pp;
+         ++c;
+       }
+      if (c >= 16)
+       {
+         if (size <= (*ppsmall)->size)
+           return;
+         *ppsmall = (*ppsmall)->next;
+       }
+
       p = (struct backtrace_freelist_struct *) addr;
       p->next = state->freelist;
       p->size = size;