diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-01-25 02:24:45 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2018-01-25 02:24:45 +0000 |
commit | c0a300a5c79f6f9cc819a72ba71ad4bd693976e0 (patch) | |
tree | b6c670fd5e3baa2ea92271a39300c2b0a26f7074 /libbacktrace | |
parent | 9f0bb9fb23cab2a01a46ae43d7cf0f587543db88 (diff) |
PR other/68239
* mmap.c (backtrace_free_locked): Don't put more than 16 entries
on the free list.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@257039 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libbacktrace')
-rw-r--r-- | libbacktrace/ChangeLog | 6 | ||||
-rw-r--r-- | libbacktrace/mmap.c | 24 |
2 files changed, 29 insertions, 1 deletions
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog index 1fcca776759..2d89ea1dd6c 100644 --- a/libbacktrace/ChangeLog +++ b/libbacktrace/ChangeLog @@ -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. diff --git a/libbacktrace/mmap.c b/libbacktrace/mmap.c index 41bbc71d463..32fcba62399 100644 --- a/libbacktrace/mmap.c +++ b/libbacktrace/mmap.c @@ -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; |