diff options
author | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2020-04-29 00:31:01 -0400 |
---|---|---|
committer | Jan Edmund Lazo <jan.lazo@mail.utoronto.ca> | 2020-05-03 13:16:37 -0400 |
commit | 66369cd9d03bf4b09c354f4a23ed24adad834408 (patch) | |
tree | 19287c2428e1ebf62836609ee79dabb37b09fe28 | |
parent | 5058b07122507e5cdd988dc956f0b6b359d18193 (diff) | |
download | rneovim-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.c | 11 |
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); + } } } |