Mercurial > vim
diff src/eval.c @ 22541:7d6ba4204f66 v8.2.1819
patch 8.2.1819: Vim9: Memory leak when using a closure
Commit: https://github.com/vim/vim/commit/85d5e2b723e6fc233e53252dd5c523944146fbc2
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Oct 10 14:13:01 2020 +0200
patch 8.2.1819: Vim9: Memory leak when using a closure
Problem: Vim9: Memory leak when using a closure.
Solution: Compute the mininal refcount in the funcstack. Reenable disabled
tests.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 10 Oct 2020 14:15:04 +0200 |
parents | 35ef9b0a81a3 |
children | eb54d34ecd27 |
line wrap: on
line diff
--- a/src/eval.c +++ b/src/eval.c @@ -3984,21 +3984,12 @@ partial_free(partial_T *pt) else func_ptr_unref(pt->pt_func); + // Decrease the reference count for the context of a closure. If down + // to the minimum it may be time to free it. if (pt->pt_funcstack != NULL) { - // Decrease the reference count for the context of a closure. If down - // to zero free it and clear the variables on the stack. - if (--pt->pt_funcstack->fs_refcount == 0) - { - garray_T *gap = &pt->pt_funcstack->fs_ga; - typval_T *stack = gap->ga_data; - - for (i = 0; i < gap->ga_len; ++i) - clear_tv(stack + i); - ga_clear(gap); - vim_free(pt->pt_funcstack); - } - pt->pt_funcstack = NULL; + --pt->pt_funcstack->fs_refcount; + funcstack_check_refcount(pt->pt_funcstack); } vim_free(pt); @@ -4011,8 +4002,16 @@ partial_free(partial_T *pt) void partial_unref(partial_T *pt) { - if (pt != NULL && --pt->pt_refcount <= 0) - partial_free(pt); + if (pt != NULL) + { + if (--pt->pt_refcount <= 0) + partial_free(pt); + + // If the reference count goes down to one, the funcstack may be the + // only reference and can be freed if no other partials reference it. + else if (pt->pt_refcount == 1 && pt->pt_funcstack != NULL) + funcstack_check_refcount(pt->pt_funcstack); + } } /*