1
0
forked from aniani/vim

patch 7.4.2197

Problem:    All functions are freed on exit, which may hide leaks.
Solution:   Only free named functions, not reference counted ones.
This commit is contained in:
Bram Moolenaar
2016-08-11 22:51:05 +02:00
parent 91c5262b19
commit c257487035
2 changed files with 38 additions and 19 deletions

View File

@@ -1099,22 +1099,53 @@ func_free(ufunc_T *fp, int force)
vim_free(fp);
}
/*
* There are two kinds of function names:
* 1. ordinary names, function defined with :function
* 2. numbered functions and lambdas
* For the first we only count the name stored in func_hashtab as a reference,
* using function() does not count as a reference, because the function is
* looked up by name.
*/
static int
func_name_refcount(char_u *name)
{
return isdigit(*name) || *name == '<';
}
#if defined(EXITFREE) || defined(PROTO)
void
free_all_functions(void)
{
hashitem_T *hi;
ufunc_T *fp;
long_u skipped = 0;
long_u todo;
/* Need to start all over every time, because func_free() may change the
* hash table. */
while (func_hashtab.ht_used > 0)
for (hi = func_hashtab.ht_array; ; ++hi)
while (func_hashtab.ht_used > skipped)
{
todo = func_hashtab.ht_used;
for (hi = func_hashtab.ht_array; todo > 0; ++hi)
if (!HASHITEM_EMPTY(hi))
{
func_free(HI2UF(hi), TRUE);
break;
--todo;
/* Only free functions that are not refcounted, those are
* supposed to be freed when no longer referenced. */
fp = HI2UF(hi);
if (func_name_refcount(fp->uf_name))
++skipped;
else
{
func_free(fp, TRUE);
skipped = 0;
break;
}
}
hash_clear(&func_hashtab);
}
if (skipped == 0)
hash_clear(&func_hashtab);
}
#endif
@@ -1668,20 +1699,6 @@ theend:
return name;
}
/*
* There are two kinds of function names:
* 1. ordinary names, function defined with :function
* 2. numbered functions and lambdas
* For the first we only count the name stored in func_hashtab as a reference,
* using function() does not count as a reference, because the function is
* looked up by name.
*/
static int
func_name_refcount(char_u *name)
{
return isdigit(*name) || *name == '<';
}
/*
* ":function"
*/