mirror of
https://github.com/neovim/neovim.git
synced 2025-09-26 21:18:34 +00:00
Merge pull request #1761 from oni-link/speed.up.gc
Speed up garbage collection (Issue 1687).
This commit is contained in:
@@ -5543,49 +5543,48 @@ int garbage_collect(void)
|
|||||||
return did_free;
|
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)
|
static int free_unref_items(int copyID)
|
||||||
{
|
{
|
||||||
dict_T *dd;
|
bool did_free = false;
|
||||||
list_T *ll;
|
|
||||||
int did_free = FALSE;
|
|
||||||
|
|
||||||
/*
|
// Go through the list of dicts and free items without the copyID.
|
||||||
* Go through the list of dicts and free items without the copyID.
|
for (dict_T *dd = first_dict; dd != NULL; ) {
|
||||||
*/
|
|
||||||
for (dd = first_dict; dd != NULL; )
|
|
||||||
if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
|
if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) {
|
||||||
/* Free the Dictionary and ordinary items it contains, but don't
|
// Free the Dictionary and ordinary items it contains, but don't
|
||||||
* recurse into Lists and Dictionaries, they will be in the list
|
// recurse into Lists and Dictionaries, they will be in the list
|
||||||
* of dicts or list of lists. */
|
// of dicts or list of lists. */
|
||||||
|
dict_T *dd_next = dd->dv_used_next;
|
||||||
dict_free(dd, FALSE);
|
dict_free(dd, FALSE);
|
||||||
did_free = TRUE;
|
did_free = true;
|
||||||
|
dd = dd_next;
|
||||||
/* restart, next dict may also have been freed */
|
} else {
|
||||||
dd = first_dict;
|
|
||||||
} else
|
|
||||||
dd = dd->dv_used_next;
|
dd = dd->dv_used_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
// Go through the list of lists and free items without the copyID.
|
||||||
* 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
|
||||||
* But don't free a list that has a watcher (used in a for loop), these
|
// are not referenced anywhere.
|
||||||
* are not referenced anywhere.
|
for (list_T *ll = first_list; ll != NULL;) {
|
||||||
*/
|
|
||||||
for (ll = first_list; ll != NULL; )
|
|
||||||
if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
|
if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
|
||||||
&& ll->lv_watch == NULL) {
|
&& ll->lv_watch == NULL) {
|
||||||
/* Free the List and ordinary items it contains, but don't recurse
|
// Free the List and ordinary items it contains, but don't recurse
|
||||||
* into Lists and Dictionaries, they will be in the list of dicts
|
// into Lists and Dictionaries, they will be in the list of dicts
|
||||||
* or list of lists. */
|
// or list of lists.
|
||||||
|
list_T* ll_next = ll->lv_used_next;
|
||||||
list_free(ll, FALSE);
|
list_free(ll, FALSE);
|
||||||
did_free = TRUE;
|
did_free = true;
|
||||||
|
ll = ll_next;
|
||||||
/* restart, next list may also have been freed */
|
} else {
|
||||||
ll = first_list;
|
|
||||||
} else
|
|
||||||
ll = ll->lv_used_next;
|
ll = ll->lv_used_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return did_free;
|
return did_free;
|
||||||
}
|
}
|
||||||
@@ -5717,6 +5716,7 @@ dict_free (
|
|||||||
|
|
||||||
/* Lock the hashtab, we don't want it to resize while freeing items. */
|
/* Lock the hashtab, we don't want it to resize while freeing items. */
|
||||||
hash_lock(&d->dv_hashtab);
|
hash_lock(&d->dv_hashtab);
|
||||||
|
assert(d->dv_hashtab.ht_locked > 0);
|
||||||
todo = (int)d->dv_hashtab.ht_used;
|
todo = (int)d->dv_hashtab.ht_used;
|
||||||
for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
|
for (hi = d->dv_hashtab.ht_array; todo > 0; ++hi) {
|
||||||
if (!HASHITEM_EMPTY(hi)) {
|
if (!HASHITEM_EMPTY(hi)) {
|
||||||
|
Reference in New Issue
Block a user