changeset 15585:6ca8f0350723 v8.1.0800

patch 8.1.0800: may use a lot of memory when a function refers itself commit https://github.com/vim/vim/commit/4456ab527a6a5faae9287f3bd2e52cc18966cfb0 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Jan 23 23:00:30 2019 +0100 patch 8.1.0800: may use a lot of memory when a function refers itself Problem: May use a lot of memory when a function creates a cyclic reference. Solution: After saving a funccal many times, invoke the garbage collector. (closes #3835)
author Bram Moolenaar <Bram@vim.org>
date Wed, 23 Jan 2019 23:15:05 +0100
parents 072d640a241b
children 291f2cc021b0
files src/userfunc.c src/version.c
diffstat 2 files changed, 15 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -651,6 +651,7 @@ cleanup_function_call(funccall_T *fc)
 	listitem_T	*li;
 	int		todo;
 	dictitem_T	*v;
+	static int	made_copy = 0;
 
 	/* "fc" is still in use.  This can happen when returning "a:000",
 	 * assigning "l:" to a global variable or defining a closure.
@@ -673,6 +674,16 @@ cleanup_function_call(funccall_T *fc)
 	/* Make a copy of the a:000 items, since we didn't do that above. */
 	for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
 	    copy_tv(&li->li_tv, &li->li_tv);
+
+	if (++made_copy == 10000)
+	{
+	    // We have made a lot of copies.  This can happen when
+	    // repetitively calling a function that creates a reference to
+	    // itself somehow.  Call the garbage collector here to avoid using
+	    // too much memory.
+	    made_copy = 0;
+	    (void)garbage_collect(FALSE);
+	}
     }
 }
 
@@ -723,6 +734,8 @@ call_user_func(
     line_breakcheck();		/* check for CTRL-C hit */
 
     fc = (funccall_T *)alloc(sizeof(funccall_T));
+    if (fc == NULL)
+	return;
     fc->caller = current_funccal;
     current_funccal = fc;
     fc->func = fp;
--- a/src/version.c
+++ b/src/version.c
@@ -792,6 +792,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    800,
+/**/
     799,
 /**/
     798,