summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/arena.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/arena.c b/src/arena.c
index 99bdb8e..d11018d 100644
--- a/src/arena.c
+++ b/src/arena.c
@@ -1479,8 +1479,19 @@ arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, size_t binind,
ptr = arena_run_reg_alloc(run, &arena_bin_info[binind]);
else
ptr = arena_bin_malloc_hard(arena, bin);
- if (ptr == NULL)
+ if (ptr == NULL) {
+ /*
+ * OOM. tbin->avail isn't yet filled down to its first
+ * element, so the successful allocations (if any) must
+ * be moved to the base of tbin->avail before bailing
+ * out.
+ */
+ if (i > 0) {
+ memmove(tbin->avail, &tbin->avail[nfill - i],
+ i * sizeof(void *));
+ }
break;
+ }
if (config_fill && opt_junk) {
arena_alloc_junk_small(ptr, &arena_bin_info[binind],
true);