summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <bram@vim.org>2015-02-03 17:10:06 +0100
committerBram Moolenaar <bram@vim.org>2015-02-03 17:10:06 +0100
commit7dfd24622a69b99280a88744bb1ab08bab3869a2 (patch)
tree40cb1eb030dc142af4ce1e79b9e33bcd04eff78a
parente2479b9f245a5065c26cce65b64f9b6d910f4dad (diff)
downloadvim-7dfd24622a69b99280a88744bb1ab08bab3869a2.tar.gz
updated for version 7.4.615v7.4.615v7-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)
-rw-r--r--src/eval.c27
-rw-r--r--src/version.c2
2 files changed, 14 insertions, 15 deletions
diff --git a/src/eval.c b/src/eval.c
index 6d5d762f..b8288c29 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -5974,7 +5974,7 @@ list_unref(l)
}
/*
- * Free a list, including all items it points to.
+ * Free a list, including all non-container items it points to.
* Ignores the reference count.
*/
void
@@ -6941,14 +6941,16 @@ garbage_collect()
free_unref_items(copyID)
int copyID;
{
- dict_T *dd;
- list_T *ll;
+ dict_T *dd, *dd_next;
+ list_T *ll, *ll_next;
int did_free = FALSE;
/*
* Go through the list of dicts and free items without the copyID.
*/
for (dd = first_dict; dd != NULL; )
+ {
+ dd_next = dd->dv_used_next;
if ((dd->dv_copyID & COPYID_MASK) != (copyID & COPYID_MASK))
{
/* Free the Dictionary and ordinary items it contains, but don't
@@ -6956,12 +6958,9 @@ free_unref_items(copyID)
* of dicts or list of lists. */
dict_free(dd, FALSE);
did_free = TRUE;
-
- /* restart, next dict may also have been freed */
- dd = first_dict;
}
- else
- dd = dd->dv_used_next;
+ dd = dd_next;
+ }
/*
* Go through the list of lists and free items without the copyID.
@@ -6969,6 +6968,8 @@ free_unref_items(copyID)
* are not referenced anywhere.
*/
for (ll = first_list; ll != NULL; )
+ {
+ ll_next = ll->lv_used_next;
if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK)
&& ll->lv_watch == NULL)
{
@@ -6977,13 +6978,9 @@ free_unref_items(copyID)
* or list of lists. */
list_free(ll, FALSE);
did_free = TRUE;
-
- /* restart, next list may also have been freed */
- ll = first_list;
}
- else
- ll = ll->lv_used_next;
-
+ ll = ll_next;
+ }
return did_free;
}
@@ -7213,7 +7210,7 @@ dict_unref(d)
}
/*
- * Free a Dictionary, including all items it contains.
+ * Free a Dictionary, including all non-container items it contains.
* Ignores the reference count.
*/
void
diff --git a/src/version.c b/src/version.c
index efee40de..f278cdac 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 615,
+/**/
614,
/**/
613,