[Ada] Refactor repeated code for real type attributes returning integers
[gcc.git] / libbacktrace / mmap.c
index cfa50e27d8c66aec3fee381e9426a74a17aa70c7..6c8bd5d4a194019051933a8235034bfc9050a068 100644 (file)
@@ -1,5 +1,5 @@
 /* mmap.c -- Memory allocation with mmap.
-   Copyright (C) 2012-2017 Free Software Foundation, Inc.
+   Copyright (C) 2012-2020 Free Software Foundation, Inc.
    Written by Ian Lance Taylor, Google.
 
 Redistribution and use in source and binary forms, with or without
@@ -42,6 +42,10 @@ POSSIBILITY OF SUCH DAMAGE.  */
 #include "backtrace.h"
 #include "internal.h"
 
+#ifndef HAVE_DECL_GETPAGESIZE
+extern int getpagesize (void);
+#endif
+
 /* Memory allocation on systems that provide anonymous mmap.  This
    permits the backtrace functions to be invoked from a signal
    handler, assuming that mmap is async-signal safe.  */
@@ -69,11 +73,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;
@@ -299,5 +325,7 @@ backtrace_vector_release (struct backtrace_state *state,
   backtrace_free (state, (char *) vec->base + aligned, alc,
                  error_callback, data);
   vec->alc = 0;
+  if (vec->size == 0)
+    vec->base = NULL;
   return 1;
 }