• R/O
  • SSH

vim: 提交

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

修訂a4ed0de125d9f358bd30d26a8aab30b6b845da15 (tree)
時間2020-09-19 22:30:04
作者Bram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 8.2.1711: Vim9: leaking memory when using partial

Commit: https://github.com/vim/vim/commit/fdeab65db60929e28640fd740c333f9bcfea0e15
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Sep 19 15:16:50 2020 +0200

patch 8.2.1711: Vim9: leaking memory when using partial
Problem: Vim9: leaking memory when using partial.
Solution: Do delete the function even when it was compiled.

Change Summary

差異

diff -r bf31e05d3fec -r a4ed0de125d9 src/proto/vim9compile.pro
--- a/src/proto/vim9compile.pro Sat Sep 19 14:15:05 2020 +0200
+++ b/src/proto/vim9compile.pro Sat Sep 19 15:30:04 2020 +0200
@@ -17,5 +17,6 @@
1717 void set_function_type(ufunc_T *ufunc);
1818 void delete_instr(isn_T *isn);
1919 void clear_def_function(ufunc_T *ufunc);
20+void unlink_def_function(ufunc_T *ufunc);
2021 void free_def_functions(void);
2122 /* vim: set ft=c : */
diff -r bf31e05d3fec -r a4ed0de125d9 src/userfunc.c
--- a/src/userfunc.c Sat Sep 19 14:15:05 2020 +0200
+++ b/src/userfunc.c Sat Sep 19 15:30:04 2020 +0200
@@ -1049,6 +1049,21 @@
10491049 }
10501050 }
10511051 }
1052+
1053+/*
1054+ * There are two kinds of function names:
1055+ * 1. ordinary names, function defined with :function or :def
1056+ * 2. numbered functions and lambdas
1057+ * For the first we only count the name stored in func_hashtab as a reference,
1058+ * using function() does not count as a reference, because the function is
1059+ * looked up by name.
1060+ */
1061+ static int
1062+func_name_refcount(char_u *name)
1063+{
1064+ return isdigit(*name) || *name == '<';
1065+}
1066+
10521067 /*
10531068 * Unreference "fc": decrement the reference count and free it when it
10541069 * becomes zero. "fp" is detached from "fc".
@@ -1172,6 +1187,8 @@
11721187
11731188 if ((fp->uf_flags & FC_DEAD) == 0 || force)
11741189 {
1190+ if (fp->uf_dfunc_idx > 0)
1191+ unlink_def_function(fp);
11751192 VIM_CLEAR(fp->uf_name_exp);
11761193 vim_free(fp);
11771194 }
@@ -1185,7 +1202,8 @@
11851202 func_clear_free(ufunc_T *fp, int force)
11861203 {
11871204 func_clear(fp, force);
1188- if (force || fp->uf_dfunc_idx == 0 || (fp->uf_flags & FC_COPY))
1205+ if (force || fp->uf_dfunc_idx == 0 || func_name_refcount(fp->uf_name)
1206+ || (fp->uf_flags & FC_COPY))
11891207 func_free(fp, force);
11901208 else
11911209 fp->uf_flags |= FC_DEAD;
@@ -1730,20 +1748,6 @@
17301748 return error;
17311749 }
17321750
1733-/*
1734- * There are two kinds of function names:
1735- * 1. ordinary names, function defined with :function
1736- * 2. numbered functions and lambdas
1737- * For the first we only count the name stored in func_hashtab as a reference,
1738- * using function() does not count as a reference, because the function is
1739- * looked up by name.
1740- */
1741- static int
1742-func_name_refcount(char_u *name)
1743-{
1744- return isdigit(*name) || *name == '<';
1745-}
1746-
17471751 static funccal_entry_T *funccal_stack = NULL;
17481752
17491753 /*
diff -r bf31e05d3fec -r a4ed0de125d9 src/version.c
--- a/src/version.c Sat Sep 19 14:15:05 2020 +0200
+++ b/src/version.c Sat Sep 19 15:30:04 2020 +0200
@@ -751,6 +751,8 @@
751751 static int included_patches[] =
752752 { /* Add new patch number below this line */
753753 /**/
754+ 1711,
755+/**/
754756 1710,
755757 /**/
756758 1709,
diff -r bf31e05d3fec -r a4ed0de125d9 src/vim9compile.c
--- a/src/vim9compile.c Sat Sep 19 14:15:05 2020 +0200
+++ b/src/vim9compile.c Sat Sep 19 15:30:04 2020 +0200
@@ -2593,6 +2593,9 @@
25932593 // The return type will now be known.
25942594 set_function_type(ufunc);
25952595
2596+ // The function reference count will be 1. When the ISN_FUNCREF
2597+ // instruction is deleted the reference count is decremented and the
2598+ // function is freed.
25962599 return generate_FUNCREF(cctx, ufunc);
25972600 }
25982601
@@ -7424,6 +7427,18 @@
74247427 }
74257428 }
74267429
7430+/*
7431+ * Used when a user function is about to be deleted: remove the pointer to it.
7432+ * The entry in def_functions is then unused.
7433+ */
7434+ void
7435+unlink_def_function(ufunc_T *ufunc)
7436+{
7437+ dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
7438+
7439+ dfunc->df_ufunc = NULL;
7440+}
7441+
74277442 #if defined(EXITFREE) || defined(PROTO)
74287443 /*
74297444 * Free all functions defined with ":def".
diff -r bf31e05d3fec -r a4ed0de125d9 src/vim9execute.c
--- a/src/vim9execute.c Sat Sep 19 14:15:05 2020 +0200
+++ b/src/vim9execute.c Sat Sep 19 15:30:04 2020 +0200
@@ -270,12 +270,18 @@
270270 {
271271 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
272272 + ectx->ec_dfunc_idx;
273- int argcount = ufunc_argcount(dfunc->df_ufunc);
274- int top = ectx->ec_frame_idx - argcount;
273+ int argcount;
274+ int top;
275275 int idx;
276276 typval_T *tv;
277277 int closure_in_use = FALSE;
278278
279+ if (dfunc->df_ufunc == NULL)
280+ // function was freed
281+ return OK;
282+ argcount = ufunc_argcount(dfunc->df_ufunc);
283+ top = ectx->ec_frame_idx - argcount;
284+
279285 // Check if any created closure is still in use.
280286 for (idx = 0; idx < dfunc->df_closure_count; ++idx)
281287 {
Show on old repository browser