aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/misc2.c85
-rw-r--r--src/misc2.h2
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);