summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2016-01-19 12:48:42 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2016-01-19 12:48:42 (GMT)
commit4918b47c64cd69b3fecc1a7d9adcca82f6ec711c (patch)
tree7dd19bdc5818839e279289d23c75ab8c7cf19797 /Objects
parent31a858cbf1eca34f04dd425fa7f8d6f031e5de66 (diff)
parentd205d0145c8f5a37d0a46261eb0193e27b5b0ad8 (diff)
downloadcpython-4918b47c64cd69b3fecc1a7d9adcca82f6ec711c.zip
cpython-4918b47c64cd69b3fecc1a7d9adcca82f6ec711c.tar.gz
cpython-4918b47c64cd69b3fecc1a7d9adcca82f6ec711c.tar.bz2
Issue #25935: Garbage collector now breaks reference loops with OrderedDict.
Diffstat (limited to 'Objects')
-rw-r--r--Objects/odictobject.c27
1 files changed, 14 insertions, 13 deletions
diff --git a/Objects/odictobject.c b/Objects/odictobject.c
index c15b408..1abdd02 100644
--- a/Objects/odictobject.c
+++ b/Objects/odictobject.c
@@ -772,19 +772,17 @@ _odict_clear_nodes(PyODictObject *od)
{
_ODictNode *node, *next;
- if (!_odict_EMPTY(od)) {
- node = _odict_FIRST(od);
- while (node != NULL) {
- next = _odictnode_NEXT(node);
- _odictnode_DEALLOC(node);
- node = next;
- }
- _odict_FIRST(od) = NULL;
- _odict_LAST(od) = NULL;
- }
-
_odict_free_fast_nodes(od);
od->od_fast_nodes = NULL;
+
+ node = _odict_FIRST(od);
+ _odict_FIRST(od) = NULL;
+ _odict_LAST(od) = NULL;
+ while (node != NULL) {
+ next = _odictnode_NEXT(node);
+ _odictnode_DEALLOC(node);
+ node = next;
+ }
}
/* There isn't any memory management of nodes past this point. */
@@ -1233,8 +1231,6 @@ odict_clear(register PyODictObject *od)
{
PyDict_Clear((PyObject *)od);
_odict_clear_nodes(od);
- _odict_FIRST(od) = NULL;
- _odict_LAST(od) = NULL;
if (_odict_resize(od) < 0)
return NULL;
Py_RETURN_NONE;
@@ -1556,8 +1552,13 @@ PyDoc_STRVAR(odict_doc,
static int
odict_traverse(PyODictObject *od, visitproc visit, void *arg)
{
+ _ODictNode *node;
+
Py_VISIT(od->od_inst_dict);
Py_VISIT(od->od_weakreflist);
+ _odict_FOREACH(od, node) {
+ Py_VISIT(_odictnode_KEY(node));
+ }
return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
}