aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2015-01-10 09:55:55 -0500
committerJustin M. Keyes <justinkz@gmail.com>2015-01-10 09:55:55 -0500
commita684cc175a6c1ca2cfc3bff2d68383d32008cb3b (patch)
treec6a37ba2b32501db3a2e795d8fe28451c34750ab /src/nvim/eval.c
parentf2460e93be3e047c1350a970e5963aadc90f2697 (diff)
parent36ba1d9fba1c5ad07f3c8464514219ecb4d9dd17 (diff)
downloadrneovim-a684cc175a6c1ca2cfc3bff2d68383d32008cb3b.tar.gz
rneovim-a684cc175a6c1ca2cfc3bff2d68383d32008cb3b.tar.bz2
rneovim-a684cc175a6c1ca2cfc3bff2d68383d32008cb3b.zip
Merge pull request #1761 from oni-link/speed.up.gc
Speed up garbage collection (Issue 1687).
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c64
1 files changed, 32 insertions, 32 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index d3ce7b46a7..9974315d3f 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -5543,49 +5543,48 @@ int garbage_collect(void)
return did_free;
}
-/*
- * Free lists and dictionaries that are no longer referenced.
- */
+/// Free lists and dictionaries that are no longer referenced.
+///
+/// Note: This function may only be called from garbage_collect().
+///
+/// @param copyID Free lists/dictionaries that don't have this ID.
+/// @return true, if something was freed.
static int free_unref_items(int copyID)
{
- dict_T *dd;
- list_T *ll;
- int did_free = FALSE;
+ bool did_free = false;
- /*
- * Go through the list of dicts and free items without the copyID.
- */
- for (dd = first_dict; dd != NULL; )
+ // Go through the list of dicts and free items without the copyID.
+ for (dict_T *dd = first_dict; dd != NULL; ) {
if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
- /* Free the Dictionary and ordinary items it contains, but don't
- * recurse into Lists and Dictionaries, they will be in the list
- * of dicts or list of lists. */
+ // Free the Dictionary and ordinary items it contains, but don't
+ // recurse into Lists and Dictionaries, they will be in the list
+ // of dicts or list of lists. */
+ dict_T *dd_next = dd->dv_used_next;
dict_free(dd, FALSE);
- did_free = TRUE;
-
- /* restart, next dict may also have been freed */
- dd = first_dict;
- } else
+ did_free = true;
+ dd = dd_next;
+ } else {
dd = dd->dv_used_next;
+ }
+ }
- /*
- * Go through the list of lists and free items without the copyID.
- * But don't free a list that has a watcher (used in a for loop), these
- * are not referenced anywhere.
- */
- for (ll = first_list; ll != NULL; )
+ // Go through the list of lists and free items without the copyID.
+ // But don't free a list that has a watcher (used in a for loop), these
+ // are not referenced anywhere.
+ for (list_T *ll = first_list; ll != NULL;) {
if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
&& ll->lv_watch == NULL) {
- /* Free the List and ordinary items it contains, but don't recurse
- * into Lists and Dictionaries, they will be in the list of dicts
- * or list of lists. */
+ // Free the List and ordinary items it contains, but don't recurse
+ // into Lists and Dictionaries, they will be in the list of dicts
+ // or list of lists.
+ list_T* ll_next = ll->lv_used_next;
list_free(ll, FALSE);
- did_free = TRUE;
-
- /* restart, next list may also have been freed */
- ll = first_list;
- } else
+ did_free = true;
+ ll = ll_next;
+ } else {
ll = ll->lv_used_next;
+ }
+ }
return did_free;
}
@@ -5717,6 +5716,7 @@ dict_free (
/* Lock the hashtab, we don't want it to resize while freeing items. */
hash_lock(&d->dv_hashtab);
+ assert(d->dv_hashtab.ht_locked > 0);
todo = (int)d->dv_hashtab.ht_used;
for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
if (!HASHITEM_EMPTY(hi)) {