comparison src/eval.c @ 6577:7092ec5d5ef1 v7.4.615

updated for version 7.4.615 Problem: Vim hangs when freeing a lot of objects. Solution: Do not go back to the start of the list every time. (Yasuhiro Matsumoto and Ariya Mizutani)
author Bram Moolenaar <bram@vim.org>
date Tue, 03 Feb 2015 17:10:06 +0100
parents 38add5a3d617
children 1ffe91b5e514
comparison
equal deleted inserted replaced
6576:2528980526f9 6577:7092ec5d5ef1
5972 if (l != NULL && --l->lv_refcount <= 0) 5972 if (l != NULL && --l->lv_refcount <= 0)
5973 list_free(l, TRUE); 5973 list_free(l, TRUE);
5974 } 5974 }
5975 5975
5976 /* 5976 /*
5977 * Free a list, including all items it points to. 5977 * Free a list, including all non-container items it points to.
5978 * Ignores the reference count. 5978 * Ignores the reference count.
5979 */ 5979 */
5980 void 5980 void
5981 list_free(l, recurse) 5981 list_free(l, recurse)
5982 list_T *l; 5982 list_T *l;
6939 */ 6939 */
6940 static int 6940 static int
6941 free_unref_items(copyID) 6941 free_unref_items(copyID)
6942 int copyID; 6942 int copyID;
6943 { 6943 {
6944 dict_T *dd; 6944 dict_T *dd, *dd_next;
6945 list_T *ll; 6945 list_T *ll, *ll_next;
6946 int did_free = FALSE; 6946 int did_free = FALSE;
6947 6947
6948 /* 6948 /*
6949 * Go through the list of dicts and free items without the copyID. 6949 * Go through the list of dicts and free items without the copyID.
6950 */ 6950 */
6951 for (dd = first_dict; dd != NULL; ) 6951 for (dd = first_dict; dd != NULL; )
6952 {
6953 dd_next = dd->dv_used_next;
6952 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)) 6954 if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
6953 { 6955 {
6954 /* Free the Dictionary and ordinary items it contains, but don't 6956 /* Free the Dictionary and ordinary items it contains, but don't
6955 * recurse into Lists and Dictionaries, they will be in the list 6957 * recurse into Lists and Dictionaries, they will be in the list
6956 * of dicts or list of lists. */ 6958 * of dicts or list of lists. */
6957 dict_free(dd, FALSE); 6959 dict_free(dd, FALSE);
6958 did_free = TRUE; 6960 did_free = TRUE;
6959 6961 }
6960 /* restart, next dict may also have been freed */ 6962 dd = dd_next;
6961 dd = first_dict; 6963 }
6962 }
6963 else
6964 dd = dd->dv_used_next;
6965 6964
6966 /* 6965 /*
6967 * Go through the list of lists and free items without the copyID. 6966 * Go through the list of lists and free items without the copyID.
6968 * But don't free a list that has a watcher (used in a for loop), these 6967 * But don't free a list that has a watcher (used in a for loop), these
6969 * are not referenced anywhere. 6968 * are not referenced anywhere.
6970 */ 6969 */
6971 for (ll = first_list; ll != NULL; ) 6970 for (ll = first_list; ll != NULL; )
6971 {
6972 ll_next = ll->lv_used_next;
6972 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) 6973 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
6973 && ll->lv_watch == NULL) 6974 && ll->lv_watch == NULL)
6974 { 6975 {
6975 /* Free the List and ordinary items it contains, but don't recurse 6976 /* Free the List and ordinary items it contains, but don't recurse
6976 * into Lists and Dictionaries, they will be in the list of dicts 6977 * into Lists and Dictionaries, they will be in the list of dicts
6977 * or list of lists. */ 6978 * or list of lists. */
6978 list_free(ll, FALSE); 6979 list_free(ll, FALSE);
6979 did_free = TRUE; 6980 did_free = TRUE;
6980 6981 }
6981 /* restart, next list may also have been freed */ 6982 ll = ll_next;
6982 ll = first_list; 6983 }
6983 }
6984 else
6985 ll = ll->lv_used_next;
6986
6987 return did_free; 6984 return did_free;
6988 } 6985 }
6989 6986
6990 /* 6987 /*
6991 * Mark all lists and dicts referenced through hashtab "ht" with "copyID". 6988 * Mark all lists and dicts referenced through hashtab "ht" with "copyID".
7211 if (d != NULL && --d->dv_refcount <= 0) 7208 if (d != NULL && --d->dv_refcount <= 0)
7212 dict_free(d, TRUE); 7209 dict_free(d, TRUE);
7213 } 7210 }
7214 7211
7215 /* 7212 /*
7216 * Free a Dictionary, including all items it contains. 7213 * Free a Dictionary, including all non-container items it contains.
7217 * Ignores the reference count. 7214 * Ignores the reference count.
7218 */ 7215 */
7219 void 7216 void
7220 dict_free(d, recurse) 7217 dict_free(d, recurse)
7221 dict_T *d; 7218 dict_T *d;