aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2020-04-29 00:31:01 -0400
committerJan Edmund Lazo <jan.lazo@mail.utoronto.ca>2020-05-03 13:16:37 -0400
commit66369cd9d03bf4b09c354f4a23ed24adad834408 (patch)
tree19287c2428e1ebf62836609ee79dabb37b09fe28
parent5058b07122507e5cdd988dc956f0b6b359d18193 (diff)
downloadrneovim-66369cd9d03bf4b09c354f4a23ed24adad834408.tar.gz
rneovim-66369cd9d03bf4b09c354f4a23ed24adad834408.tar.bz2
rneovim-66369cd9d03bf4b09c354f4a23ed24adad834408.zip
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) https://github.com/vim/vim/commit/4456ab527a6a5faae9287f3bd2e52cc18966cfb0
-rw-r--r--src/nvim/eval/userfunc.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index c55a29c67c..6e3c6c592a 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -592,6 +592,8 @@ static void cleanup_function_call(funccall_T *fc)
if (!fc_referenced(fc)) {
free_funccal(fc, false);
} else {
+ 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.
// 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_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);
+ }
}
}