neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

memory.c (27649B)


      1 // Various routines dealing with allocation and deallocation of memory.
      2 
      3 #include <assert.h>
      4 #include <inttypes.h>
      5 #include <stdbool.h>
      6 #include <stdint.h>
      7 #include <stdlib.h>
      8 #include <string.h>
      9 #include <time.h>
     10 
     11 #include "nvim/api/extmark.h"
     12 #include "nvim/api/private/helpers.h"
     13 #include "nvim/api/ui.h"
     14 #include "nvim/arglist.h"
     15 #include "nvim/ascii_defs.h"
     16 #include "nvim/buffer_defs.h"
     17 #include "nvim/buffer_updates.h"
     18 #include "nvim/channel.h"
     19 #include "nvim/context.h"
     20 #include "nvim/decoration_provider.h"
     21 #include "nvim/drawline.h"
     22 #include "nvim/errors.h"
     23 #include "nvim/eval.h"
     24 #include "nvim/gettext_defs.h"
     25 #include "nvim/globals.h"
     26 #include "nvim/highlight.h"
     27 #include "nvim/highlight_group.h"
     28 #include "nvim/insexpand.h"
     29 #include "nvim/lua/executor.h"
     30 #include "nvim/main.h"
     31 #include "nvim/map_defs.h"
     32 #include "nvim/mapping.h"
     33 #include "nvim/memfile.h"
     34 #include "nvim/memory.h"
     35 #include "nvim/message.h"
     36 #include "nvim/option_vars.h"
     37 #include "nvim/sign.h"
     38 #include "nvim/state_defs.h"
     39 #include "nvim/statusline.h"
     40 #include "nvim/types_defs.h"
     41 #include "nvim/ui.h"
     42 #include "nvim/ui_client.h"
     43 #include "nvim/ui_compositor.h"
     44 #include "nvim/usercmd.h"
     45 
     46 #ifdef UNIT_TESTING
     47 # define malloc(size) mem_malloc(size)
     48 # define calloc(count, size) mem_calloc(count, size)
     49 # define realloc(ptr, size) mem_realloc(ptr, size)
     50 # define free(ptr) mem_free(ptr)
     51 MemMalloc mem_malloc = &malloc;
     52 MemFree mem_free = &free;
     53 MemCalloc mem_calloc = &calloc;
     54 MemRealloc mem_realloc = &realloc;
     55 #endif
     56 
     57 #include "memory.c.generated.h"
     58 
     59 #ifdef EXITFREE
     60 bool entered_free_all_mem = false;
     61 #endif
     62 
     63 /// Try to free memory. Used when trying to recover from out of memory errors.
     64 /// @see {xmalloc}
     65 static void try_to_free_memory(void)
     66 {
     67  static bool trying_to_free = false;
     68  // avoid recursive calls
     69  if (trying_to_free) {
     70    return;
     71  }
     72  trying_to_free = true;
     73 
     74  // free any scrollback text
     75  clear_sb_text(true);
     76  // Try to save all buffers and release as many blocks as possible
     77  mf_release_all();
     78 
     79  arena_free_reuse_blks();
     80 
     81  trying_to_free = false;
     82 }
     83 
     84 /// Avoid repeating the error message many times (they take 1 second each).
     85 /// `did_outofmem_msg` is reset when a character is read.
     86 static void do_outofmem_msg(size_t size)
     87 {
     88  if (did_outofmem_msg) {
     89    return;
     90  }
     91 
     92  // Don't hide this message
     93  emsg_silent = 0;
     94 
     95  // Must come first to avoid coming back here when printing the error
     96  // message fails, e.g. when setting v:errmsg.
     97  did_outofmem_msg = true;
     98 
     99  semsg(_("E342: Out of memory!  (allocating %" PRIu64 " bytes)"), (uint64_t)size);
    100 }
    101 
    102 /// malloc() wrapper
    103 ///
    104 /// try_malloc() is a malloc() wrapper that tries to free some memory before
    105 /// trying again.
    106 ///
    107 /// @see {try_to_free_memory}
    108 /// @param size
    109 /// @return pointer to allocated space. NULL if out of memory
    110 void *try_malloc(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1)
    111 {
    112  size_t allocated_size = size ? size : 1;
    113  void *ret = malloc(allocated_size);
    114  if (!ret) {
    115    try_to_free_memory();
    116    ret = malloc(allocated_size);
    117  }
    118  return ret;
    119 }
    120 
    121 /// try_malloc() wrapper that shows an out-of-memory error message to the user
    122 /// before returning NULL
    123 ///
    124 /// @see {try_malloc}
    125 /// @param size
    126 /// @return pointer to allocated space. NULL if out of memory
    127 void *verbose_try_malloc(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1)
    128 {
    129  void *ret = try_malloc(size);
    130  if (!ret) {
    131    do_outofmem_msg(size);
    132  }
    133  return ret;
    134 }
    135 
    136 /// malloc() wrapper that never returns NULL
    137 ///
    138 /// xmalloc() succeeds or gracefully aborts when out of memory.
    139 /// Before aborting try to free some memory and call malloc again.
    140 ///
    141 /// @see {try_to_free_memory}
    142 /// @param size
    143 /// @return pointer to allocated space. Never NULL
    144 void *xmalloc(size_t size)
    145  FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1) FUNC_ATTR_NONNULL_RET
    146 {
    147  void *ret = try_malloc(size);
    148  if (!ret) {
    149    preserve_exit(e_outofmem);
    150  }
    151  return ret;
    152 }
    153 
    154 /// free() wrapper that delegates to the backing memory manager
    155 ///
    156 /// @note Use XFREE_CLEAR() instead, if possible.
    157 void xfree(void *ptr)
    158 {
    159  free(ptr);
    160 }
    161 
    162 /// calloc() wrapper
    163 ///
    164 /// @see {xmalloc}
    165 /// @param count
    166 /// @param size
    167 /// @return pointer to allocated space. Never NULL
    168 void *xcalloc(size_t count, size_t size)
    169  FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE_PROD(1, 2) FUNC_ATTR_NONNULL_RET
    170 {
    171  size_t allocated_count = count && size ? count : 1;
    172  size_t allocated_size = count && size ? size : 1;
    173  void *ret = calloc(allocated_count, allocated_size);
    174  if (!ret) {
    175    try_to_free_memory();
    176    ret = calloc(allocated_count, allocated_size);
    177    if (!ret) {
    178      preserve_exit(e_outofmem);
    179    }
    180  }
    181  return ret;
    182 }
    183 
    184 /// realloc() wrapper
    185 ///
    186 /// @see {xmalloc}
    187 /// @param size
    188 /// @return pointer to reallocated space. Never NULL
    189 void *xrealloc(void *ptr, size_t size)
    190  FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_ALLOC_SIZE(2) FUNC_ATTR_NONNULL_RET
    191 {
    192  size_t allocated_size = size ? size : 1;
    193  void *ret = realloc(ptr, allocated_size);
    194  if (!ret) {
    195    try_to_free_memory();
    196    ret = realloc(ptr, allocated_size);
    197    if (!ret) {
    198      preserve_exit(e_outofmem);
    199    }
    200  }
    201  return ret;
    202 }
    203 
    204 /// xmalloc() wrapper that allocates size + 1 bytes and zeroes the last byte
    205 ///
    206 /// Commonly used to allocate strings, e.g. `char *s = xmallocz(len)`.
    207 ///
    208 /// @see {xmalloc}
    209 /// @param size
    210 /// @return pointer to allocated space. Never NULL
    211 void *xmallocz(size_t size)
    212  FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
    213 {
    214  size_t total_size = size + 1;
    215  if (total_size < size) {
    216    preserve_exit(_("Nvim: Data too large to fit into virtual memory space\n"));
    217  }
    218 
    219  void *ret = xmalloc(total_size);
    220  ((char *)ret)[size] = NUL;
    221 
    222  return ret;
    223 }
    224 
    225 /// Allocates (len + 1) bytes of memory, duplicates `len` bytes of
    226 /// `data` to the allocated memory, zero terminates the allocated memory,
    227 /// and returns a pointer to the allocated memory. If the allocation fails,
    228 /// the program dies.
    229 ///
    230 /// @see {xmalloc}
    231 /// @param data Pointer to the data that will be copied
    232 /// @param len number of bytes that will be copied
    233 void *xmemdupz(const void *data, size_t len)
    234  FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
    235  FUNC_ATTR_NONNULL_ALL
    236 {
    237  return memcpy(xmallocz(len), data, len);
    238 }
    239 
    240 /// Copies `len` bytes of `src` to `dst` and zero terminates it.
    241 ///
    242 /// @see {xstrlcpy}
    243 /// @param[out]  dst  Buffer to store the result.
    244 /// @param[in]  src  Buffer to be copied.
    245 /// @param[in]  len  Number of bytes to be copied.
    246 void *xmemcpyz(void *dst, const void *src, size_t len)
    247  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET
    248 {
    249  memcpy(dst, src, len);
    250  ((char *)dst)[len] = NUL;
    251  return dst;
    252 }
    253 
    254 #ifndef HAVE_STRNLEN
    255 size_t xstrnlen(const char *s, size_t n)
    256  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
    257 {
    258  const char *end = memchr(s, NUL, n);
    259  if (end == NULL) {
    260    return n;
    261  }
    262  return (size_t)(end - s);
    263 }
    264 #endif
    265 
    266 /// A version of strchr() that returns a pointer to the terminating NUL if it
    267 /// doesn't find `c`.
    268 ///
    269 /// @param str The string to search.
    270 /// @param c   The char to look for.
    271 /// @returns a pointer to the first instance of `c`, or to the NUL terminator
    272 ///          if not found.
    273 char *xstrchrnul(const char *str, char c)
    274  FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
    275 {
    276  const char *p = strchr(str, c);
    277  return p ? (char *)p : (char *)(str + strlen(str));
    278 }
    279 
    280 /// A version of memchr() that returns a pointer one past the end
    281 /// if it doesn't find `c`.
    282 ///
    283 /// @param addr The address of the memory object.
    284 /// @param c    The char to look for.
    285 /// @param size The size of the memory object.
    286 /// @returns a pointer to the first instance of `c`, or one past the end if not
    287 ///          found.
    288 void *xmemscan(const void *addr, char c, size_t size)
    289  FUNC_ATTR_NONNULL_RET FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
    290 {
    291  const char *p = memchr(addr, c, size);
    292  return p ? (char *)p : (char *)addr + size;
    293 }
    294 
    295 /// Replaces every instance of `c` with `x`.
    296 ///
    297 /// @warning Will read past `str + strlen(str)` if `c == NUL`.
    298 ///
    299 /// @param str A NUL-terminated string.
    300 /// @param c   The unwanted byte.
    301 /// @param x   The replacement.
    302 void strchrsub(char *str, char c, char x)
    303  FUNC_ATTR_NONNULL_ALL
    304 {
    305  assert(c != NUL);
    306  while ((str = strchr(str, c))) {
    307    *str++ = x;
    308  }
    309 }
    310 
    311 /// Replaces every instance of `c` with `x`.
    312 ///
    313 /// @param data An object in memory. May contain NULs.
    314 /// @param c    The unwanted byte.
    315 /// @param x    The replacement.
    316 /// @param len  The length of data.
    317 void memchrsub(void *data, char c, char x, size_t len)
    318  FUNC_ATTR_NONNULL_ALL
    319 {
    320  char *p = data;
    321  char *end = (char *)data + len;
    322  while ((p = memchr(p, c, (size_t)(end - p)))) {
    323    *p++ = x;
    324  }
    325 }
    326 
    327 /// Counts the number of occurrences of `c` in `str`.
    328 ///
    329 /// @warning Unsafe if `c == NUL`.
    330 ///
    331 /// @param str Pointer to the string to search.
    332 /// @param c   The byte to search for.
    333 /// @returns the number of occurrences of `c` in `str`.
    334 size_t strcnt(const char *str, char c)
    335  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
    336 {
    337  assert(c != 0);
    338  size_t cnt = 0;
    339  while ((str = strchr(str, c))) {
    340    cnt++;
    341    str++;  // Skip the instance of c.
    342  }
    343  return cnt;
    344 }
    345 
    346 /// Counts the number of occurrences of byte `c` in `data[len]`.
    347 ///
    348 /// @param data Pointer to the data to search.
    349 /// @param c    The byte to search for.
    350 /// @param len  The length of `data`.
    351 /// @returns the number of occurrences of `c` in `data[len]`.
    352 size_t memcnt(const void *data, char c, size_t len)
    353  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
    354 {
    355  size_t cnt = 0;
    356  const char *ptr = data;
    357  const char *end = ptr + len;
    358  while ((ptr = memchr(ptr, c, (size_t)(end - ptr))) != NULL) {
    359    cnt++;
    360    ptr++;  // Skip the instance of c.
    361  }
    362  return cnt;
    363 }
    364 
    365 /// Copies the string pointed to by src (including the terminating NUL
    366 /// character) into the array pointed to by dst.
    367 ///
    368 /// @returns pointer to the terminating NUL char copied into the dst buffer.
    369 ///          This is the only difference with strcpy(), which returns dst.
    370 ///
    371 /// WARNING: If copying takes place between objects that overlap, the behavior
    372 /// is undefined.
    373 ///
    374 /// Nvim version of POSIX 2008 stpcpy(3). We do not require POSIX 2008, so
    375 /// implement our own version.
    376 ///
    377 /// @param dst
    378 /// @param src
    379 char *xstpcpy(char *restrict dst, const char *restrict src)
    380  FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
    381 {
    382  const size_t len = strlen(src);
    383  return (char *)memcpy(dst, src, len + 1) + len;
    384 }
    385 
    386 /// Copies not more than n bytes (bytes that follow a NUL character are not
    387 /// copied) from the array pointed to by src to the array pointed to by dst.
    388 ///
    389 /// If a NUL character is written to the destination, xstpncpy() returns the
    390 /// address of the first such NUL character. Otherwise, it shall return
    391 /// &dst[maxlen].
    392 ///
    393 /// WARNING: If copying takes place between objects that overlap, the behavior
    394 /// is undefined.
    395 ///
    396 /// WARNING: xstpncpy will ALWAYS write maxlen bytes. If src is shorter than
    397 /// maxlen, zeroes will be written to the remaining bytes.
    398 ///
    399 /// @param dst
    400 /// @param src
    401 /// @param maxlen
    402 char *xstpncpy(char *restrict dst, const char *restrict src, size_t maxlen)
    403  FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
    404 {
    405  const char *p = memchr(src, NUL, maxlen);
    406  if (p) {
    407    size_t srclen = (size_t)(p - src);
    408    memcpy(dst, src, srclen);
    409    memset(dst + srclen, 0, maxlen - srclen);
    410    return dst + srclen;
    411  } else {
    412    memcpy(dst, src, maxlen);
    413    return dst + maxlen;
    414  }
    415 }
    416 
    417 /// xstrlcpy - Copy a NUL-terminated string into a sized buffer
    418 ///
    419 /// Compatible with *BSD strlcpy: the result is always a valid NUL-terminated
    420 /// string that fits in the buffer (unless, of course, the buffer size is
    421 /// zero). It does not pad out the result like strncpy() does.
    422 ///
    423 /// @param[out]  dst  Buffer to store the result.
    424 /// @param[in]  src  String to be copied.
    425 /// @param[in]  dsize  Size of `dst`.
    426 ///
    427 /// @return Length of `src`. May be greater than `dsize - 1`, which would mean
    428 ///         that string was truncated.
    429 size_t xstrlcpy(char *restrict dst, const char *restrict src, size_t dsize)
    430  FUNC_ATTR_NONNULL_ALL
    431 {
    432  size_t slen = strlen(src);
    433 
    434  if (dsize) {
    435    size_t len = MIN(slen, dsize - 1);
    436    memcpy(dst, src, len);
    437    dst[len] = NUL;
    438  }
    439 
    440  return slen;  // Does not include NUL.
    441 }
    442 
    443 /// Appends `src` to string `dst` of size `dsize` (unlike strncat, dsize is the
    444 /// full size of `dst`, not space left).  At most dsize-1 characters
    445 /// will be copied.  Always NUL terminates. `src` and `dst` may overlap.
    446 ///
    447 /// @see vim_strcat from Vim.
    448 /// @see strlcat from OpenBSD.
    449 ///
    450 /// @param[in,out]  dst  Buffer to be appended-to. Must have a NUL byte.
    451 /// @param[in]  src  String to put at the end of `dst`.
    452 /// @param[in]  dsize  Size of `dst` including NUL byte. Must be greater than 0.
    453 ///
    454 /// @return Length of the resulting string as if destination size was #SIZE_MAX.
    455 ///         May be greater than `dsize - 1`, which would mean that string was
    456 ///         truncated.
    457 size_t xstrlcat(char *const dst, const char *const src, const size_t dsize)
    458  FUNC_ATTR_NONNULL_ALL
    459 {
    460  assert(dsize > 0);
    461  const size_t dlen = strlen(dst);
    462  assert(dlen < dsize);
    463  const size_t slen = strlen(src);
    464 
    465  if (slen > dsize - dlen - 1) {
    466    memmove(dst + dlen, src, dsize - dlen - 1);
    467    dst[dsize - 1] = NUL;
    468  } else {
    469    memmove(dst + dlen, src, slen + 1);
    470  }
    471 
    472  return slen + dlen;  // Does not include NUL.
    473 }
    474 
    475 /// strdup() wrapper
    476 ///
    477 /// @see {xmalloc}
    478 /// @param str 0-terminated string that will be copied
    479 /// @return pointer to a copy of the string
    480 char *xstrdup(const char *str)
    481  FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
    482  FUNC_ATTR_NONNULL_ALL
    483 {
    484  return xmemdupz(str, strlen(str));
    485 }
    486 
    487 /// strdup() wrapper
    488 ///
    489 /// Unlike xstrdup() allocates a new empty string if it receives NULL.
    490 char *xstrdupnul(const char *const str)
    491  FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
    492 {
    493  if (str == NULL) {
    494    return xmallocz(0);
    495  }
    496  return xstrdup(str);
    497 }
    498 
    499 /// A version of memchr that starts the search at `src + len`.
    500 ///
    501 /// Based on glibc's memrchr.
    502 ///
    503 /// @param src The source memory object.
    504 /// @param c   The byte to search for.
    505 /// @param len The length of the memory object.
    506 /// @returns a pointer to the found byte in src[len], or NULL.
    507 void *xmemrchr(const void *src, uint8_t c, size_t len)
    508  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE
    509 {
    510  while (len--) {
    511    if (((uint8_t *)src)[len] == c) {
    512      return (uint8_t *)src + len;
    513    }
    514  }
    515  return NULL;
    516 }
    517 
    518 /// strndup() wrapper
    519 ///
    520 /// @see {xmalloc}
    521 /// @param str 0-terminated string that will be copied
    522 /// @return pointer to a copy of the string
    523 char *xstrndup(const char *str, size_t len)
    524  FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
    525  FUNC_ATTR_NONNULL_ALL
    526 {
    527  const char *p = memchr(str, NUL, len);
    528  return xmemdupz(str, p ? (size_t)(p - str) : len);
    529 }
    530 
    531 /// Duplicates a chunk of memory using xmalloc
    532 ///
    533 /// @see {xmalloc}
    534 /// @param data pointer to the chunk
    535 /// @param len size of the chunk
    536 /// @return a pointer
    537 void *xmemdup(const void *data, size_t len)
    538  FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(2) FUNC_ATTR_NONNULL_RET
    539  FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
    540 {
    541  return memcpy(xmalloc(len), data, len);
    542 }
    543 
    544 /// Returns true if strings `a` and `b` are equal. Arguments may be NULL.
    545 bool strequal(const char *a, const char *b)
    546  FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
    547 {
    548  return (a == NULL && b == NULL) || (a && b && strcmp(a, b) == 0);
    549 }
    550 
    551 /// Returns true if first `n` characters of strings `a` and `b` are equal. Arguments may be NULL.
    552 bool strnequal(const char *a, const char *b, size_t n)
    553  FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
    554 {
    555  return (a == NULL && b == NULL) || (a && b && strncmp(a, b, n) == 0);
    556 }
    557 
    558 /// Writes time_t to "buf[8]".
    559 void time_to_bytes(time_t time_, uint8_t buf[8])
    560 {
    561  // time_t can be up to 8 bytes in size, more than uintmax_t in 32 bits
    562  // systems, thus we can't use put_bytes() here.
    563  for (size_t i = 7, bufi = 0; bufi < 8; i--, bufi++) {
    564    buf[bufi] = (uint8_t)((uint64_t)time_ >> (i * 8));
    565  }
    566 }
    567 
    568 /// Iterative merge sort for doubly linked list.
    569 /// O(NlogN) worst case, and stable.
    570 ///  - The list is divided into blocks of increasing size (1, 2, 4, 8, ...).
    571 ///  - Each pair of blocks is merged in sorted order.
    572 ///  - Merged blocks are reconnected to build the sorted list.
    573 void *mergesort_list(void *head, MergeSortGetFunc get_next, MergeSortSetFunc set_next,
    574                     MergeSortGetFunc get_prev, MergeSortSetFunc set_prev,
    575                     MergeSortCompareFunc compare)
    576 {
    577  if (!head || !get_next(head)) {
    578    return head;
    579  }
    580 
    581  // Count length
    582  int n = 0;
    583  void *curr = head;
    584  while (curr) {
    585    n++;
    586    curr = get_next(curr);
    587  }
    588 
    589  for (int size = 1; size < n; size *= 2) {
    590    void *new_head = NULL;
    591    void *tail = NULL;
    592    curr = head;
    593 
    594    while (curr) {
    595      // Split two runs
    596      void *left = curr;
    597      void *right = left;
    598      for (int i = 0; i < size && right; i++) {
    599        right = get_next(right);
    600      }
    601 
    602      void *next = right;
    603      for (int i = 0; i < size && next; i++) {
    604        next = get_next(next);
    605      }
    606 
    607      // Break links
    608      void *l_end = right ? get_prev(right) : NULL;
    609      if (l_end) {
    610        set_next(l_end, NULL);
    611      }
    612      if (right) {
    613        set_prev(right, NULL);
    614      }
    615 
    616      void *r_end = next ? get_prev(next) : NULL;
    617      if (r_end) {
    618        set_next(r_end, NULL);
    619      }
    620      if (next) {
    621        set_prev(next, NULL);
    622      }
    623 
    624      // Merge
    625      void *merged = NULL;
    626      void *merged_tail = NULL;
    627 
    628      while (left || right) {
    629        void *chosen = NULL;
    630        if (!left) {
    631          chosen = right;
    632          right = get_next(right);
    633        } else if (!right) {
    634          chosen = left;
    635          left = get_next(left);
    636        } else if (compare(left, right) <= 0) {
    637          chosen = left;
    638          left = get_next(left);
    639        } else {
    640          chosen = right;
    641          right = get_next(right);
    642        }
    643 
    644        if (merged_tail) {
    645          set_next(merged_tail, chosen);
    646          set_prev(chosen, merged_tail);
    647          merged_tail = chosen;
    648        } else {
    649          merged = merged_tail = chosen;
    650          set_prev(chosen, NULL);
    651        }
    652      }
    653 
    654      // Connect to full list
    655      if (!new_head) {
    656        new_head = merged;
    657      } else {
    658        set_next(tail, merged);
    659        set_prev(merged, tail);
    660      }
    661 
    662      // Move tail to end
    663      while (get_next(merged_tail)) {
    664        merged_tail = get_next(merged_tail);
    665      }
    666      tail = merged_tail;
    667 
    668      curr = next;
    669    }
    670 
    671    head = new_head;
    672  }
    673 
    674  return head;
    675 }
    676 
    677 #define REUSE_MAX 4
    678 
    679 static struct consumed_blk *arena_reuse_blk;
    680 static size_t arena_reuse_blk_count = 0;
    681 
    682 static void arena_free_reuse_blks(void)
    683 {
    684  while (arena_reuse_blk_count > 0) {
    685    struct consumed_blk *blk = arena_reuse_blk;
    686    arena_reuse_blk = arena_reuse_blk->prev;
    687    xfree(blk);
    688    arena_reuse_blk_count--;
    689  }
    690 }
    691 
    692 /// Finish the allocations in an arena.
    693 ///
    694 /// This does not immediately free the memory, but leaves existing allocated
    695 /// objects valid, and returns an opaque ArenaMem handle, which can be used to
    696 /// free the allocations using `arena_mem_free`, when the objects allocated
    697 /// from the arena are not needed anymore.
    698 ArenaMem arena_finish(Arena *arena)
    699 {
    700  struct consumed_blk *res = (struct consumed_blk *)arena->cur_blk;
    701  *arena = (Arena)ARENA_EMPTY;
    702  return res;
    703 }
    704 
    705 /// allocate a block of ARENA_BLOCK_SIZE
    706 ///
    707 /// free it with free_block
    708 void *alloc_block(void)
    709 {
    710  if (arena_reuse_blk_count > 0) {
    711    void *retval = (char *)arena_reuse_blk;
    712    arena_reuse_blk = arena_reuse_blk->prev;
    713    arena_reuse_blk_count--;
    714    return retval;
    715  } else {
    716    arena_alloc_count++;
    717    return xmalloc(ARENA_BLOCK_SIZE);
    718  }
    719 }
    720 
    721 void arena_alloc_block(Arena *arena)
    722 {
    723  struct consumed_blk *prev_blk = (struct consumed_blk *)arena->cur_blk;
    724  arena->cur_blk = alloc_block();
    725  arena->pos = 0;
    726  arena->size = ARENA_BLOCK_SIZE;
    727  struct consumed_blk *blk = arena_alloc(arena, sizeof(struct consumed_blk), true);
    728  blk->prev = prev_blk;
    729 }
    730 
    731 static size_t arena_align_offset(uint64_t off)
    732 {
    733 #define ARENA_ALIGN MAX(sizeof(void *), sizeof(double))
    734  return ((off + (ARENA_ALIGN - 1)) & ~(ARENA_ALIGN - 1));
    735 #undef ARENA_ALIGN
    736 }
    737 
    738 /// @param arena if NULL, do a global allocation. caller must then free the value!
    739 /// @param size if zero, will still return a non-null pointer, but not a usable or unique one
    740 void *arena_alloc(Arena *arena, size_t size, bool align)
    741 {
    742  if (!arena) {
    743    return xmalloc(size);
    744  }
    745  if (!arena->cur_blk) {
    746    arena_alloc_block(arena);
    747  }
    748  size_t alloc_pos = align ? arena_align_offset(arena->pos) : arena->pos;
    749  if (alloc_pos + size > arena->size) {
    750    if (size > (ARENA_BLOCK_SIZE - sizeof(struct consumed_blk)) >> 1) {
    751      // if allocation is too big, allocate a large block with the requested
    752      // size, but still with block pointer head. We do this even for
    753      // arena->size / 2, as there likely is space left for the next
    754      // small allocation in the current block.
    755      arena_alloc_count++;
    756      size_t hdr_size = sizeof(struct consumed_blk);
    757      size_t aligned_hdr_size = (align ? arena_align_offset(hdr_size) : hdr_size);
    758      char *alloc = xmalloc(size + aligned_hdr_size);
    759 
    760      // to simplify free-list management, arena->cur_blk must
    761      // always be a normal, ARENA_BLOCK_SIZE sized, block
    762      struct consumed_blk *cur_blk = (struct consumed_blk *)arena->cur_blk;
    763      struct consumed_blk *fix_blk = (struct consumed_blk *)alloc;
    764      fix_blk->prev = cur_blk->prev;
    765      cur_blk->prev = fix_blk;
    766      return alloc + aligned_hdr_size;
    767    } else {
    768      arena_alloc_block(arena);  // resets arena->pos
    769      alloc_pos = align ? arena_align_offset(arena->pos) : arena->pos;
    770    }
    771  }
    772 
    773  char *mem = arena->cur_blk + alloc_pos;
    774  arena->pos = alloc_pos + size;
    775  return mem;
    776 }
    777 
    778 void free_block(void *block)
    779 {
    780  if (arena_reuse_blk_count < REUSE_MAX) {
    781    struct consumed_blk *reuse_blk = block;
    782    reuse_blk->prev = arena_reuse_blk;
    783    arena_reuse_blk = reuse_blk;
    784    arena_reuse_blk_count++;
    785  } else {
    786    xfree(block);
    787  }
    788 }
    789 
    790 void arena_mem_free(ArenaMem mem)
    791 {
    792  struct consumed_blk *b = mem;
    793  // peel of the first block, as it is guaranteed to be ARENA_BLOCK_SIZE,
    794  // not a custom fix_blk
    795  if (b != NULL) {
    796    struct consumed_blk *reuse_blk = b;
    797    b = b->prev;
    798    free_block(reuse_blk);
    799  }
    800 
    801  while (b) {
    802    struct consumed_blk *prev = b->prev;
    803    xfree(b);
    804    b = prev;
    805  }
    806 }
    807 
    808 char *arena_allocz(Arena *arena, size_t size)
    809 {
    810  char *mem = arena_alloc(arena, size + 1, false);
    811  mem[size] = NUL;
    812  return mem;
    813 }
    814 
    815 char *arena_memdupz(Arena *arena, const char *buf, size_t size)
    816  FUNC_ATTR_NONNULL_ARG(2)
    817 {
    818  char *mem = arena_allocz(arena, size);
    819  memcpy(mem, buf, size);
    820  return mem;
    821 }
    822 
    823 char *arena_strdup(Arena *arena, const char *str)
    824  FUNC_ATTR_NONNULL_ARG(2)
    825 {
    826  return arena_memdupz(arena, str, strlen(str));
    827 }
    828 
    829 #if defined(EXITFREE)
    830 
    831 # include "nvim/autocmd.h"
    832 # include "nvim/buffer.h"
    833 # include "nvim/cmdhist.h"
    834 # include "nvim/diff.h"
    835 # include "nvim/edit.h"
    836 # include "nvim/ex_cmds.h"
    837 # include "nvim/ex_docmd.h"
    838 # include "nvim/file_search.h"
    839 # include "nvim/getchar.h"
    840 # include "nvim/grid.h"
    841 # include "nvim/mark.h"
    842 # include "nvim/msgpack_rpc/channel.h"
    843 # include "nvim/option.h"
    844 # include "nvim/os/os.h"
    845 # include "nvim/quickfix.h"
    846 # include "nvim/regexp.h"
    847 # include "nvim/register.h"
    848 # include "nvim/search.h"
    849 # include "nvim/spell.h"
    850 # include "nvim/tag.h"
    851 # include "nvim/window.h"
    852 
    853 // Free everything that we allocated.
    854 // Can be used to detect memory leaks, e.g., with ccmalloc.
    855 // NOTE: This is tricky!  Things are freed that functions depend on.  Don't be
    856 // surprised if Vim crashes...
    857 // Some things can't be freed, esp. things local to a library function.
    858 void free_all_mem(void)
    859 {
    860  buf_T *buf, *nextbuf;
    861 
    862  // When we cause a crash here it is caught and Vim tries to exit cleanly.
    863  // Don't try freeing everything again.
    864  if (entered_free_all_mem) {
    865    return;
    866  }
    867  entered_free_all_mem = true;
    868  // Don't want to trigger autocommands from here on.
    869  block_autocmds();
    870 
    871  // Close all tabs and windows.  Reset 'equalalways' to avoid redraws.
    872  p_ea = false;
    873  if (first_tabpage != NULL && first_tabpage->tp_next != NULL) {
    874    do_cmdline_cmd("tabonly!");
    875  }
    876 
    877  // Free all spell info.
    878  spell_free_all();
    879 
    880  // Clear user commands (before deleting buffers).
    881  ex_comclear(NULL);
    882 
    883  if (curbuf != NULL) {
    884    // Clear menus.
    885    do_cmdline_cmd("aunmenu *");
    886    do_cmdline_cmd("tlunmenu *");
    887    do_cmdline_cmd("menutranslate clear");
    888 
    889    // Clear mappings, abbreviations, breakpoints.
    890    // NB: curbuf not used with local=false arg
    891    map_clear_mode(curbuf, MAP_ALL_MODES, false, false);
    892    map_clear_mode(curbuf, MAP_ALL_MODES, false, true);
    893    do_cmdline_cmd("breakdel *");
    894    do_cmdline_cmd("profdel *");
    895    do_cmdline_cmd("set keymap=");
    896  }
    897 
    898  free_titles();
    899  free_findfile();
    900 
    901  // Obviously named calls.
    902  free_all_autocmds();
    903  free_all_marks();
    904  alist_clear(&global_alist);
    905  free_homedir();
    906  free_users();
    907  free_search_patterns();
    908  free_old_sub();
    909  free_last_insert();
    910  free_insexpand_stuff();
    911  free_prev_shellcmd();
    912  free_regexp_stuff();
    913  free_tag_stuff();
    914  free_cd_dir();
    915  free_signs();
    916  set_expr_line(NULL);
    917  if (curtab != NULL) {
    918    diff_clear(curtab);
    919  }
    920  clear_sb_text(true);            // free any scrollback text
    921 
    922  // Free some global vars.
    923  xfree(last_cmdline);
    924  xfree(new_last_cmdline);
    925  set_keep_msg(NULL, 0);
    926 
    927  // Clear cmdline history.
    928  p_hi = 0;
    929  init_history();
    930 
    931  free_quickfix();
    932 
    933  // Close all script inputs.
    934  close_all_scripts();
    935 
    936  if (curwin != NULL) {
    937    // Destroy all windows.  Must come before freeing buffers.
    938    win_free_all();
    939  }
    940 
    941  // Free all option values.  Must come after closing windows.
    942  free_all_options();
    943 
    944  // Free all buffers.  Reset 'autochdir' to avoid accessing things that
    945  // were freed already.
    946  // Must be after eval_clear to avoid it trying to access b:changedtick after
    947  // freeing it.
    948  p_acd = false;
    949  for (buf = firstbuf; buf != NULL;) {
    950    bufref_T bufref;
    951    set_bufref(&bufref, buf);
    952    nextbuf = buf->b_next;
    953 
    954    // Since options (in addition to other stuff) have been freed above we need to ensure no
    955    // callbacks are called, so free them before closing the buffer.
    956    buf_free_callbacks(buf);
    957 
    958    close_buffer(NULL, buf, DOBUF_WIPE, false, false);
    959    // Didn't work, try next one.
    960    buf = bufref_valid(&bufref) ? nextbuf : firstbuf;
    961  }
    962 
    963  // Clear registers.
    964  clear_registers();
    965  ResetRedobuff();
    966  ResetRedobuff();
    967 
    968  // highlight info
    969  free_highlight();
    970 
    971  reset_last_sourcing();
    972 
    973  if (first_tabpage != NULL) {
    974    free_tabpage(first_tabpage);
    975    first_tabpage = NULL;
    976  }
    977 
    978  // message history
    979  msg_hist_clear(0);
    980 
    981  channel_free_all_mem();
    982  eval_clear();
    983  api_extmark_free_all_mem();
    984  ctx_free_all();
    985 
    986  map_destroy(int, &buffer_handles);
    987  map_destroy(int, &window_handles);
    988  map_destroy(int, &tabpage_handles);
    989 
    990  // free screenlines (can't display anything now!)
    991  grid_free_all_mem();
    992  stl_clear_click_defs(tab_page_click_defs, tab_page_click_defs_size);
    993  xfree(tab_page_click_defs);
    994 
    995  clear_hl_tables(false);
    996 
    997  check_quickfix_busy();
    998 
    999  decor_free_all_mem();
   1000  drawline_free_all_mem();
   1001 
   1002  if (ui_client_channel_id) {
   1003    ui_client_free_all_mem();
   1004  }
   1005 
   1006  remote_ui_free_all_mem();
   1007  ui_free_all_mem();
   1008  ui_comp_free_all_mem();
   1009  nlua_free_all_mem();
   1010  rpc_free_all_mem();
   1011  autocmd_free_all_mem();
   1012 
   1013  // should be last, in case earlier free functions deallocates arenas
   1014  arena_free_reuse_blks();
   1015 }
   1016 
   1017 #endif