diff options
-rw-r--r-- | src/misc2.c | 85 | ||||
-rw-r--r-- | src/misc2.h | 2 |
2 files changed, 41 insertions, 46 deletions
diff --git a/src/misc2.c b/src/misc2.c index 21d942e370..5c07ada005 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -642,63 +642,56 @@ char_u *alloc_check(unsigned size) */ char_u *lalloc_clear(long_u size, int message) { - char_u *p; - - p = (lalloc(size, message)); - if (p != NULL) - (void)memset(p, 0, (size_t)size); + char_u *p = lalloc(size, message); + memset(p, 0, (size_t)size); return p; } -/* - * Low level memory allocation function. - * This is used often, KEEP IT FAST! - */ -char_u *lalloc(long_u size, int message) +/// When out of memory: try to release some memfile blocks and +/// if some blocks are released call malloc again. +void try_to_free_memory() { - char_u *p; /* pointer to new storage space */ - static int releasing = FALSE; /* don't do mf_release_all() recursive */ - int try_again; + static bool trying_to_free = false; + // avoid recursive calls + if (trying_to_free) + return; + trying_to_free = true; - /* Safety check for allocating zero bytes */ - if (size == 0) { - /* Don't hide this message */ - emsg_silent = 0; - EMSGN(_("E341: Internal error: lalloc(%ld, )"), size); - return NULL; - } + // free any scrollback text + clear_sb_text(); + // Try to save all buffers and release as many blocks as possible + mf_release_all(); + // cleanup recursive lists/dicts + garbage_collect(); - /* - * Loop when out of memory: Try to release some memfile blocks and - * if some blocks are released call malloc again. - */ - for (;; ) { - if ((p = (char_u *)malloc((size_t)size)) != NULL) { - /* No check for available memory: Just return. */ - goto theend; - } - /* - * Remember that mf_release_all() is being called to avoid an endless - * loop, because mf_release_all() may call alloc() recursively. - */ - if (releasing) - break; - releasing = TRUE; + trying_to_free = false; +} + +void *xmalloc(size_t size) +{ + void *ret = malloc(size); - clear_sb_text(); /* free any scrollback text */ - try_again = mf_release_all(); /* release as many blocks as possible */ - try_again |= garbage_collect(); /* cleanup recursive lists/dicts */ + if (!ret && !size) + ret = malloc(1); - releasing = FALSE; - if (!try_again) - break; + if (!ret) { + try_to_free_memory(); + ret = malloc(size); + if (!ret && !size) + ret = malloc(1); + if (!ret) { + OUT_STR("Vim: Error: Out of memory.\n"); + preserve_exit(); + } } - if (message && p == NULL) - do_outofmem_msg(size); + return ret; +} -theend: - return p; +/// Old low level memory allocation function. Prefer xmalloc() from now on. +char_u *lalloc(long_u size, int message) +{ + return (char_u *)xmalloc((size_t)size); } /* diff --git a/src/misc2.h b/src/misc2.h index d8f13d7640..0e52993412 100644 --- a/src/misc2.h +++ b/src/misc2.h @@ -27,6 +27,8 @@ char_u *alloc(unsigned size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); char_u *alloc_clear(unsigned size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); char_u *alloc_check(unsigned size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); char_u *lalloc_clear(long_u size, int message) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); +void try_to_free_memory(); +void *xmalloc(size_t size) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); char_u *lalloc(long_u size, int message) FUNC_ATTR_MALLOC FUNC_ATTR_ALLOC_SIZE(1); void do_outofmem_msg(long_u size); void free_all_mem(void); |