diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-01-23 23:00:30 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-01-23 23:00:30 +0100 |
commit | 4456ab527a6a5faae9287f3bd2e52cc18966cfb0 (patch) | |
tree | 4b780e00f74b4b12aa61a18beb093908a3264543 | |
parent | cfc15237ab88ecb78b12030f6e04b87618b56124 (diff) | |
download | vim-git-4456ab527a6a5faae9287f3bd2e52cc18966cfb0.tar.gz |
patch 8.1.0800: may use a lot of memory when a function refers itselfv8.1.0800
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)
-rw-r--r-- | src/userfunc.c | 13 | ||||
-rw-r--r-- | src/version.c | 2 |
2 files changed, 15 insertions, 0 deletions
diff --git a/src/userfunc.c b/src/userfunc.c index 6887c2c5c..66e07b1f4 100644 --- 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; diff --git a/src/version.c b/src/version.c index d5ea08645..b8b06307d 100644 --- 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, |