Mercurial > vim
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; |