/* 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
#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. */
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;
backtrace_free (state, (char *) vec->base + aligned, alc,
error_callback, data);
vec->alc = 0;
+ if (vec->size == 0)
+ vec->base = NULL;
return 1;
}