Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(2)

Side by Side Diff: Objects/odictobject.c

Issue 25935: OrderedDict prevents garbage collection if a circulary referenced class is used as key
Patch Set: Created 4 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Ordered Dictionary object implementation. 1 /* Ordered Dictionary object implementation.
2 2
3 This implementation is necessarily explicitly equivalent to the pure Python 3 This implementation is necessarily explicitly equivalent to the pure Python
4 OrderedDict class in Lib/collections/__init__.py. The strategy there 4 OrderedDict class in Lib/collections/__init__.py. The strategy there
5 involves using a doubly-linked-list to capture the order. We keep to that 5 involves using a doubly-linked-list to capture the order. We keep to that
6 strategy, using a lower-level linked-list. 6 strategy, using a lower-level linked-list.
7 7
8 About the Linked-List 8 About the Linked-List
9 ===================== 9 =====================
10 10
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 _odict_remove_node(od, node); 765 _odict_remove_node(od, node);
766 _odictnode_DEALLOC(node); 766 _odictnode_DEALLOC(node);
767 return 0; 767 return 0;
768 } 768 }
769 769
770 static void 770 static void
771 _odict_clear_nodes(PyODictObject *od) 771 _odict_clear_nodes(PyODictObject *od)
772 { 772 {
773 _ODictNode *node, *next; 773 _ODictNode *node, *next;
774 774
775 if (!_odict_EMPTY(od)) {
776 node = _odict_FIRST(od);
777 while (node != NULL) {
778 next = _odictnode_NEXT(node);
779 _odictnode_DEALLOC(node);
780 node = next;
781 }
782 _odict_FIRST(od) = NULL;
783 _odict_LAST(od) = NULL;
784 }
785
786 _odict_free_fast_nodes(od); 775 _odict_free_fast_nodes(od);
787 od->od_fast_nodes = NULL; 776 od->od_fast_nodes = NULL;
777
778 node = _odict_FIRST(od);
779 _odict_FIRST(od) = NULL;
780 _odict_LAST(od) = NULL;
781 while (node != NULL) {
782 next = _odictnode_NEXT(node);
783 _odictnode_DEALLOC(node);
784 node = next;
785 }
788 } 786 }
789 787
790 /* There isn't any memory management of nodes past this point. */ 788 /* There isn't any memory management of nodes past this point. */
791 #undef _odictnode_DEALLOC 789 #undef _odictnode_DEALLOC
792 790
793 static int 791 static int
794 _odict_keys_equal(PyODictObject *a, PyODictObject *b) 792 _odict_keys_equal(PyODictObject *a, PyODictObject *b)
795 { 793 {
796 _ODictNode *node_a, *node_b; 794 _ODictNode *node_a, *node_b;
797 795
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 /* clear() */ 1224 /* clear() */
1227 1225
1228 PyDoc_STRVAR(odict_clear__doc__, 1226 PyDoc_STRVAR(odict_clear__doc__,
1229 "od.clear() -> None. Remove all items from od."); 1227 "od.clear() -> None. Remove all items from od.");
1230 1228
1231 static PyObject * 1229 static PyObject *
1232 odict_clear(register PyODictObject *od) 1230 odict_clear(register PyODictObject *od)
1233 { 1231 {
1234 PyDict_Clear((PyObject *)od); 1232 PyDict_Clear((PyObject *)od);
1235 _odict_clear_nodes(od); 1233 _odict_clear_nodes(od);
1236 _odict_FIRST(od) = NULL;
1237 _odict_LAST(od) = NULL;
1238 if (_odict_resize(od) < 0) 1234 if (_odict_resize(od) < 0)
1239 return NULL; 1235 return NULL;
1240 Py_RETURN_NONE; 1236 Py_RETURN_NONE;
1241 } 1237 }
1242 1238
1243 /* copy() */ 1239 /* copy() */
1244 1240
1245 /* forward */ 1241 /* forward */
1246 static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *, 1242 static int _PyODict_SetItem_KnownHash(PyObject *, PyObject *, PyObject *,
1247 Py_hash_t); 1243 Py_hash_t);
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 /* tp_doc */ 1545 /* tp_doc */
1550 1546
1551 PyDoc_STRVAR(odict_doc, 1547 PyDoc_STRVAR(odict_doc,
1552 "Dictionary that remembers insertion order"); 1548 "Dictionary that remembers insertion order");
1553 1549
1554 /* tp_traverse */ 1550 /* tp_traverse */
1555 1551
1556 static int 1552 static int
1557 odict_traverse(PyODictObject *od, visitproc visit, void *arg) 1553 odict_traverse(PyODictObject *od, visitproc visit, void *arg)
1558 { 1554 {
1555 _ODictNode *node;
1556
1559 Py_VISIT(od->od_inst_dict); 1557 Py_VISIT(od->od_inst_dict);
1560 Py_VISIT(od->od_weakreflist); 1558 Py_VISIT(od->od_weakreflist);
1559 _odict_FOREACH(od, node) {
1560 Py_VISIT(_odictnode_KEY(node));
1561 }
1561 return PyDict_Type.tp_traverse((PyObject *)od, visit, arg); 1562 return PyDict_Type.tp_traverse((PyObject *)od, visit, arg);
1562 } 1563 }
1563 1564
1564 /* tp_clear */ 1565 /* tp_clear */
1565 1566
1566 static int 1567 static int
1567 odict_tp_clear(PyODictObject *od) 1568 odict_tp_clear(PyODictObject *od)
1568 { 1569 {
1569 PyObject *res; 1570 PyObject *res;
1570 Py_CLEAR(od->od_inst_dict); 1571 Py_CLEAR(od->od_inst_dict);
(...skipping 850 matching lines...) Expand 10 before | Expand all | Expand 10 after
2421 if (items == NULL) 2422 if (items == NULL)
2422 return NULL; 2423 return NULL;
2423 res = mutablemapping_add_pairs(self, items); 2424 res = mutablemapping_add_pairs(self, items);
2424 Py_DECREF(items); 2425 Py_DECREF(items);
2425 if (res == -1) 2426 if (res == -1)
2426 return NULL; 2427 return NULL;
2427 } 2428 }
2428 2429
2429 Py_RETURN_NONE; 2430 Py_RETURN_NONE;
2430 } 2431 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+