vim-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 vim/vim#3835)
4456ab527a
This commit is contained in:
Jan Edmund Lazo 2020-04-29 00:31:01 -04:00
parent 5058b07122
commit 66369cd9d0
No known key found for this signature in database
GPG Key ID: 64915E6E9F735B15

View File

@ -592,6 +592,8 @@ static void cleanup_function_call(funccall_T *fc)
if (!fc_referenced(fc)) { if (!fc_referenced(fc)) {
free_funccal(fc, false); free_funccal(fc, false);
} else { } else {
static int made_copy = 0;
// "fc" is still in use. This can happen when returning "a:000", // "fc" is still in use. This can happen when returning "a:000",
// assigning "l:" to a global variable or defining a closure. // assigning "l:" to a global variable or defining a closure.
// Link "fc" in the list for garbage collection later. // Link "fc" in the list for garbage collection later.
@ -607,6 +609,15 @@ static void cleanup_function_call(funccall_T *fc)
TV_LIST_ITER(&fc->l_varlist, li, { TV_LIST_ITER(&fc->l_varlist, li, {
tv_copy(TV_LIST_ITEM_TV(li), TV_LIST_ITEM_TV(li)); tv_copy(TV_LIST_ITEM_TV(li), TV_LIST_ITEM_TV(li));
}); });
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);
}
} }
} }