summaryrefslogtreecommitdiff
path: root/data/vim/patches/8.1.1007
diff options
context:
space:
mode:
Diffstat (limited to 'data/vim/patches/8.1.1007')
-rw-r--r--data/vim/patches/8.1.1007613
1 files changed, 0 insertions, 613 deletions
diff --git a/data/vim/patches/8.1.1007 b/data/vim/patches/8.1.1007
deleted file mode 100644
index 706b30457..000000000
--- a/data/vim/patches/8.1.1007
+++ /dev/null
@@ -1,613 +0,0 @@
-To: vim_dev@googlegroups.com
-Subject: Patch 8.1.1007
-Fcc: outbox
-From: Bram Moolenaar <Bram@moolenaar.net>
-Mime-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-------------
-
-Patch 8.1.1007
-Problem: Using closure may consume a lot of memory.
-Solution: unreference items that are no longer needed. Add a test. (Ozaki
- Kiichi, closes #3961)
-Files: src/testdir/Make_all.mak, src/testdir/test_memory_usage.vim,
- src/userfunc.c
-
-
-*** ../vim-8.1.1006/src/testdir/Make_all.mak 2019-03-02 06:41:34.345330494 +0100
---- src/testdir/Make_all.mak 2019-03-14 13:22:28.717839506 +0100
-***************
-*** 63,70 ****
- # Individual tests, including the ones part of test_alot.
- # Please keep sorted up to test_alot.
- NEW_TESTS = \
-- test_arglist \
- test_arabic \
- test_assert \
- test_assign \
- test_autochdir \
---- 63,70 ----
- # Individual tests, including the ones part of test_alot.
- # Please keep sorted up to test_alot.
- NEW_TESTS = \
- test_arabic \
-+ test_arglist \
- test_assert \
- test_assign \
- test_autochdir \
-***************
-*** 108,118 ****
- test_ex_equal \
- test_ex_undo \
- test_ex_z \
-- test_exit \
- test_exec_while_if \
- test_execute_func \
- test_exists \
- test_exists_autocmd \
- test_expand \
- test_expand_dllpath \
- test_expand_func \
---- 108,118 ----
- test_ex_equal \
- test_ex_undo \
- test_ex_z \
- test_exec_while_if \
- test_execute_func \
- test_exists \
- test_exists_autocmd \
-+ test_exit \
- test_expand \
- test_expand_dllpath \
- test_expand_func \
-***************
-*** 179,184 ****
---- 179,185 ----
- test_match \
- test_matchadd_conceal \
- test_matchadd_conceal_utf8 \
-+ test_memory_usage \
- test_menu \
- test_messages \
- test_mksession \
-***************
-*** 355,360 ****
---- 356,362 ----
- test_maparg.res \
- test_marks.res \
- test_matchadd_conceal.res \
-+ test_memory_usage.res \
- test_mksession.res \
- test_nested_function.res \
- test_netbeans.res \
-*** ../vim-8.1.1006/src/testdir/test_memory_usage.vim 2019-03-14 13:42:48.909493098 +0100
---- src/testdir/test_memory_usage.vim 2019-03-14 13:26:00.264275955 +0100
-***************
-*** 0 ****
---- 1,144 ----
-+ " Tests for memory usage.
-+
-+ if !has('terminal') || has('gui_running') || $ASAN_OPTIONS !=# ''
-+ " Skip tests on Travis CI ASAN build because it's difficult to estimate
-+ " memory usage.
-+ finish
-+ endif
-+
-+ source shared.vim
-+
-+ func s:pick_nr(str) abort
-+ return substitute(a:str, '[^0-9]', '', 'g') * 1
-+ endfunc
-+
-+ if has('win32')
-+ if !executable('wmic')
-+ finish
-+ endif
-+ func s:memory_usage(pid) abort
-+ let cmd = printf('wmic process where processid=%d get WorkingSetSize', a:pid)
-+ return s:pick_nr(system(cmd)) / 1024
-+ endfunc
-+ elseif has('unix')
-+ if !executable('ps')
-+ finish
-+ endif
-+ func s:memory_usage(pid) abort
-+ return s:pick_nr(system('ps -o rss= -p ' . a:pid))
-+ endfunc
-+ else
-+ finish
-+ endif
-+
-+ " Wait for memory usage to level off.
-+ func s:monitor_memory_usage(pid) abort
-+ let proc = {}
-+ let proc.pid = a:pid
-+ let proc.hist = []
-+ let proc.min = 0
-+ let proc.max = 0
-+
-+ func proc.op() abort
-+ " Check the last 200ms.
-+ let val = s:memory_usage(self.pid)
-+ if self.min > val
-+ let self.min = val
-+ elseif self.max < val
-+ let self.max = val
-+ endif
-+ call add(self.hist, val)
-+ if len(self.hist) < 20
-+ return 0
-+ endif
-+ let sample = remove(self.hist, 0)
-+ return len(uniq([sample] + self.hist)) == 1
-+ endfunc
-+
-+ call WaitFor({-> proc.op()}, 10000)
-+ return {'last': get(proc.hist, -1), 'min': proc.min, 'max': proc.max}
-+ endfunc
-+
-+ let s:term_vim = {}
-+
-+ func s:term_vim.start(...) abort
-+ let self.buf = term_start([GetVimProg()] + a:000)
-+ let self.job = term_getjob(self.buf)
-+ call WaitFor({-> job_status(self.job) ==# 'run'})
-+ let self.pid = job_info(self.job).process
-+ endfunc
-+
-+ func s:term_vim.stop() abort
-+ call term_sendkeys(self.buf, ":qall!\<CR>")
-+ call WaitFor({-> job_status(self.job) ==# 'dead'})
-+ exe self.buf . 'bwipe!'
-+ endfunc
-+
-+ func s:vim_new() abort
-+ return copy(s:term_vim)
-+ endfunc
-+
-+ func Test_memory_func_capture_vargs()
-+ " Case: if a local variable captures a:000, funccall object will be free
-+ " just after it finishes.
-+ let testfile = 'Xtest.vim'
-+ call writefile([
-+ \ 'func s:f(...)',
-+ \ ' let x = a:000',
-+ \ 'endfunc',
-+ \ 'for _ in range(10000)',
-+ \ ' call s:f(0)',
-+ \ 'endfor',
-+ \ ], testfile)
-+
-+ let vim = s:vim_new()
-+ call vim.start('--clean', '-c', 'set noswapfile', testfile)
-+ let before = s:monitor_memory_usage(vim.pid).last
-+
-+ call term_sendkeys(vim.buf, ":so %\<CR>")
-+ call WaitFor({-> term_getcursor(vim.buf)[0] == 1})
-+ let after = s:monitor_memory_usage(vim.pid)
-+
-+ " Estimate the limit of max usage as 2x initial usage.
-+ call assert_inrange(before, 2 * before, after.max)
-+ " In this case, garbase collecting is not needed.
-+ call assert_equal(after.last, after.max)
-+
-+ call vim.stop()
-+ call delete(testfile)
-+ endfunc
-+
-+ func Test_memory_func_capture_lvars()
-+ " Case: if a local variable captures l: dict, funccall object will not be
-+ " free until garbage collector runs, but after that memory usage doesn't
-+ " increase so much even when rerun Xtest.vim since system memory caches.
-+ let testfile = 'Xtest.vim'
-+ call writefile([
-+ \ 'func s:f()',
-+ \ ' let x = l:',
-+ \ 'endfunc',
-+ \ 'for _ in range(10000)',
-+ \ ' call s:f()',
-+ \ 'endfor',
-+ \ ], testfile)
-+
-+ let vim = s:vim_new()
-+ call vim.start('--clean', '-c', 'set noswapfile', testfile)
-+ let before = s:monitor_memory_usage(vim.pid).last
-+
-+ call term_sendkeys(vim.buf, ":so %\<CR>")
-+ call WaitFor({-> term_getcursor(vim.buf)[0] == 1})
-+ let after = s:monitor_memory_usage(vim.pid)
-+
-+ " Rerun Xtest.vim.
-+ for _ in range(3)
-+ call term_sendkeys(vim.buf, ":so %\<CR>")
-+ call WaitFor({-> term_getcursor(vim.buf)[0] == 1})
-+ let last = s:monitor_memory_usage(vim.pid).last
-+ endfor
-+
-+ call assert_inrange(before, after.max + (after.last - before), last)
-+
-+ call vim.stop()
-+ call delete(testfile)
-+ endfunc
-*** ../vim-8.1.1006/src/userfunc.c 2019-02-14 13:43:33.779220100 +0100
---- src/userfunc.c 2019-03-14 13:35:20.756552196 +0100
-***************
-*** 39,50 ****
- /* Used by get_func_tv() */
- static garray_T funcargs = GA_EMPTY;
-
-! /* pointer to funccal for currently active function */
-! funccall_T *current_funccal = NULL;
-
-! /* Pointer to list of previously used funccal, still around because some
-! * item in it is still being used. */
-! funccall_T *previous_funccal = NULL;
-
- static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
- static char *e_funcdict = N_("E717: Dictionary entry already exists");
---- 39,50 ----
- /* Used by get_func_tv() */
- static garray_T funcargs = GA_EMPTY;
-
-! // pointer to funccal for currently active function
-! static funccall_T *current_funccal = NULL;
-
-! // Pointer to list of previously used funccal, still around because some
-! // item in it is still being used.
-! static funccall_T *previous_funccal = NULL;
-
- static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
- static char *e_funcdict = N_("E717: Dictionary entry already exists");
-***************
-*** 586,628 ****
- }
-
- /*
-! * Free "fc" and what it contains.
- */
-! static void
-! free_funccal(
-! funccall_T *fc,
-! int free_val) /* a: vars were allocated */
- {
-! listitem_T *li;
-! int i;
-
- for (i = 0; i < fc->fc_funcs.ga_len; ++i)
- {
-! ufunc_T *fp = ((ufunc_T **)(fc->fc_funcs.ga_data))[i];
-
-! /* When garbage collecting a funccall_T may be freed before the
-! * function that references it, clear its uf_scoped field.
-! * The function may have been redefined and point to another
-! * funccall_T, don't clear it then. */
- if (fp != NULL && fp->uf_scoped == fc)
- fp->uf_scoped = NULL;
- }
- ga_clear(&fc->fc_funcs);
-
-! /* The a: variables typevals may not have been allocated, only free the
-! * allocated variables. */
-! vars_clear_ext(&fc->l_avars.dv_hashtab, free_val);
-
-! /* free all l: variables */
- vars_clear(&fc->l_vars.dv_hashtab);
-
-! /* Free the a:000 variables if they were allocated. */
-! if (free_val)
-! for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
-! clear_tv(&li->li_tv);
-
-! func_ptr_unref(fc->func);
-! vim_free(fc);
- }
-
- /*
---- 586,636 ----
- }
-
- /*
-! * Free "fc".
- */
-! static void
-! free_funccal(funccall_T *fc)
- {
-! int i;
-
- for (i = 0; i < fc->fc_funcs.ga_len; ++i)
- {
-! ufunc_T *fp = ((ufunc_T **)(fc->fc_funcs.ga_data))[i];
-
-! // When garbage collecting a funccall_T may be freed before the
-! // function that references it, clear its uf_scoped field.
-! // The function may have been redefined and point to another
-! // funccall_T, don't clear it then.
- if (fp != NULL && fp->uf_scoped == fc)
- fp->uf_scoped = NULL;
- }
- ga_clear(&fc->fc_funcs);
-
-! func_ptr_unref(fc->func);
-! vim_free(fc);
-! }
-
-! /*
-! * Free "fc" and what it contains.
-! * Can be called only when "fc" is kept beyond the period of it called,
-! * i.e. after cleanup_function_call(fc).
-! */
-! static void
-! free_funccal_contents(funccall_T *fc)
-! {
-! listitem_T *li;
-!
-! // Free all l: variables.
- vars_clear(&fc->l_vars.dv_hashtab);
-
-! // Free all a: variables.
-! vars_clear(&fc->l_avars.dv_hashtab);
-
-! // Free the a:000 variables.
-! for (li = fc->l_varlist.lv_first; li != NULL; li = li->li_next)
-! clear_tv(&li->li_tv);
-!
-! free_funccal(fc);
- }
-
- /*
-***************
-*** 632,682 ****
- static void
- cleanup_function_call(funccall_T *fc)
- {
- current_funccal = fc->caller;
-
-! /* If the a:000 list and the l: and a: dicts are not referenced and there
-! * is no closure using it, we can free the funccall_T and what's in it. */
-! if (fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT
-! && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT
-! && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT
-! && fc->fc_refcount <= 0)
-! {
-! free_funccal(fc, FALSE);
-! }
- else
- {
-! hashitem_T *hi;
-! 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.
-! * Link "fc" in the list for garbage collection later. */
-! fc->caller = previous_funccal;
-! previous_funccal = fc;
-
-! /* Make a copy of the a: variables, since we didn't do that above. */
- todo = (int)fc->l_avars.dv_hashtab.ht_used;
- for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
- {
- if (!HASHITEM_EMPTY(hi))
- {
- --todo;
-! v = HI2DI(hi);
-! copy_tv(&v->di_tv, &v->di_tv);
- }
- }
-
-! /* 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 soon to avoid using
- // too much memory.
- made_copy = 0;
---- 640,714 ----
- static void
- cleanup_function_call(funccall_T *fc)
- {
-+ int may_free_fc = fc->fc_refcount <= 0;
-+ int free_fc = TRUE;
-+
- current_funccal = fc->caller;
-
-! // Free all l: variables if not referred.
-! if (may_free_fc && fc->l_vars.dv_refcount == DO_NOT_FREE_CNT)
-! vars_clear(&fc->l_vars.dv_hashtab);
-! else
-! free_fc = FALSE;
-!
-! // If the a:000 list and the l: and a: dicts are not referenced and
-! // there is no closure using it, we can free the funccall_T and what's
-! // in it.
-! if (may_free_fc && fc->l_avars.dv_refcount == DO_NOT_FREE_CNT)
-! vars_clear_ext(&fc->l_avars.dv_hashtab, FALSE);
- else
- {
-! int todo;
-! hashitem_T *hi;
-! dictitem_T *di;
-
-! free_fc = FALSE;
-!
-! // Make a copy of the a: variables, since we didn't do that above.
- todo = (int)fc->l_avars.dv_hashtab.ht_used;
- for (hi = fc->l_avars.dv_hashtab.ht_array; todo > 0; ++hi)
- {
- if (!HASHITEM_EMPTY(hi))
- {
- --todo;
-! di = HI2DI(hi);
-! copy_tv(&di->di_tv, &di->di_tv);
- }
- }
-+ }
-+
-+ if (may_free_fc && fc->l_varlist.lv_refcount == DO_NOT_FREE_CNT)
-+ fc->l_varlist.lv_first = NULL;
-+ else
-+ {
-+ listitem_T *li;
-
-! free_fc = FALSE;
-!
-! // 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 (free_fc)
-+ free_funccal(fc);
-+ 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.
-! fc->caller = previous_funccal;
-! previous_funccal = fc;
-!
-! if (want_garbage_collect)
-! // If garbage collector is ready, clear count.
-! made_copy = 0;
-! else if (++made_copy >= (int)((4096 * 1024) / sizeof(*fc)))
- {
-! // We have made a lot of copies, worth 4 Mbyte. This can happen
-! // when repetitively calling a function that creates a reference to
- // itself somehow. Call the garbage collector soon to avoid using
- // too much memory.
- made_copy = 0;
-***************
-*** 731,737 ****
-
- line_breakcheck(); /* check for CTRL-C hit */
-
-! fc = (funccall_T *)alloc(sizeof(funccall_T));
- if (fc == NULL)
- return;
- fc->caller = current_funccal;
---- 763,769 ----
-
- line_breakcheck(); /* check for CTRL-C hit */
-
-! fc = (funccall_T *)alloc_clear(sizeof(funccall_T));
- if (fc == NULL)
- return;
- fc->caller = current_funccal;
-***************
-*** 832,847 ****
- {
- v = &fc->fixvar[fixvar_idx++].var;
- v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
- }
- else
- {
-! v = (dictitem_T *)alloc((unsigned)(sizeof(dictitem_T)
-! + STRLEN(name)));
- if (v == NULL)
- break;
-! v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX | DI_FLAGS_ALLOC;
- }
-- STRCPY(v->di_key, name);
-
- /* Note: the values are copied directly to avoid alloc/free.
- * "argvars" must have VAR_FIXED for v_lock. */
---- 864,878 ----
- {
- v = &fc->fixvar[fixvar_idx++].var;
- v->di_flags = DI_FLAGS_RO | DI_FLAGS_FIX;
-+ STRCPY(v->di_key, name);
- }
- else
- {
-! v = dictitem_alloc(name);
- if (v == NULL)
- break;
-! v->di_flags |= DI_FLAGS_RO | DI_FLAGS_FIX;
- }
-
- /* Note: the values are copied directly to avoid alloc/free.
- * "argvars" must have VAR_FIXED for v_lock. */
-***************
-*** 860,868 ****
-
- if (ai >= 0 && ai < MAX_FUNC_ARGS)
- {
-! list_append(&fc->l_varlist, &fc->l_listitems[ai]);
-! fc->l_listitems[ai].li_tv = argvars[i];
-! fc->l_listitems[ai].li_tv.v_lock = VAR_FIXED;
- }
- }
-
---- 891,901 ----
-
- if (ai >= 0 && ai < MAX_FUNC_ARGS)
- {
-! listitem_T *li = &fc->l_listitems[ai];
-!
-! li->li_tv = argvars[i];
-! li->li_tv.v_lock = VAR_FIXED;
-! list_append(&fc->l_varlist, li);
- }
- }
-
-***************
-*** 1088,1094 ****
- if (fc == *pfc)
- {
- *pfc = fc->caller;
-! free_funccal(fc, TRUE);
- return;
- }
- }
---- 1121,1127 ----
- if (fc == *pfc)
- {
- *pfc = fc->caller;
-! free_funccal_contents(fc);
- return;
- }
- }
-***************
-*** 3646,3652 ****
- {
- fc = *pfc;
- *pfc = fc->caller;
-! free_funccal(fc, TRUE);
- did_free = TRUE;
- did_free_funccal = TRUE;
- }
---- 3679,3685 ----
- {
- fc = *pfc;
- *pfc = fc->caller;
-! free_funccal_contents(fc);
- did_free = TRUE;
- did_free_funccal = TRUE;
- }
-*** ../vim-8.1.1006/src/version.c 2019-03-13 06:49:20.492351919 +0100
---- src/version.c 2019-03-14 13:27:08.671770246 +0100
-***************
-*** 781,782 ****
---- 781,784 ----
- { /* Add new patch number below this line */
-+ /**/
-+ 1007,
- /**/
-
---
-"I don’t know how to make a screenshot" - Richard Stallman, July 2002
-(when asked to send a screenshot of his desktop for unix.se)
-
- /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\
-/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
-\\\ an exciting new programming language -- http://www.Zimbu.org ///
- \\\ help me help AIDS victims -- http://ICCF-Holland.org ///