@@ -1161,27 +1161,51 @@ typedef struct lru_list_elem {
1161
1161
1162
1162
#define lru_list_elem_CAST (op ) ((lru_list_elem *)(op))
1163
1163
1164
+ static int
1165
+ lru_list_elem_clear (PyObject * op )
1166
+ {
1167
+ lru_list_elem * link = lru_list_elem_CAST (op );
1168
+ Py_CLEAR (link -> key );
1169
+ Py_CLEAR (link -> result );
1170
+ return 0 ;
1171
+ }
1172
+
1164
1173
static void
1165
1174
lru_list_elem_dealloc (PyObject * op )
1166
1175
{
1167
- lru_list_elem * link = lru_list_elem_CAST (op );
1168
- PyTypeObject * tp = Py_TYPE (link );
1169
- Py_XDECREF (link -> key );
1170
- Py_XDECREF (link -> result );
1171
- tp -> tp_free (link );
1176
+ PyTypeObject * tp = Py_TYPE (op );
1177
+ PyObject_GC_UnTrack (op );
1178
+ (void )lru_list_elem_clear (op );
1179
+ tp -> tp_free (op );
1172
1180
Py_DECREF (tp );
1173
1181
}
1174
1182
1183
+ static int
1184
+ lru_list_elem_traverse (PyObject * op , visitproc visit , void * arg )
1185
+ {
1186
+ lru_list_elem * self = lru_list_elem_CAST (op );
1187
+ Py_VISIT (Py_TYPE (op ));
1188
+ Py_VISIT (self -> key );
1189
+ Py_VISIT (self -> result );
1190
+ return 0 ;
1191
+ }
1192
+
1175
1193
static PyType_Slot lru_list_elem_type_slots [] = {
1194
+ {Py_tp_clear , lru_list_elem_clear },
1176
1195
{Py_tp_dealloc , lru_list_elem_dealloc },
1196
+ {Py_tp_traverse , lru_list_elem_traverse },
1177
1197
{0 , 0 }
1178
1198
};
1179
1199
1180
1200
static PyType_Spec lru_list_elem_type_spec = {
1181
1201
.name = "functools._lru_list_elem" ,
1182
1202
.basicsize = sizeof (lru_list_elem ),
1183
- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION |
1184
- Py_TPFLAGS_IMMUTABLETYPE ,
1203
+ .flags = (
1204
+ Py_TPFLAGS_DEFAULT
1205
+ | Py_TPFLAGS_DISALLOW_INSTANTIATION
1206
+ | Py_TPFLAGS_IMMUTABLETYPE
1207
+ | Py_TPFLAGS_HAVE_GC
1208
+ ),
1185
1209
.slots = lru_list_elem_type_slots
1186
1210
};
1187
1211
@@ -1454,8 +1478,10 @@ bounded_lru_cache_update_lock_held(lru_cache_object *self,
1454
1478
self -> root .next == & self -> root )
1455
1479
{
1456
1480
/* Cache is not full, so put the result in a new link */
1457
- link = (lru_list_elem * )PyObject_New (lru_list_elem ,
1458
- self -> lru_list_elem_type );
1481
+ PyTypeObject * type = self -> lru_list_elem_type ;
1482
+ assert (type != NULL );
1483
+ assert (type -> tp_alloc != NULL );
1484
+ link = (lru_list_elem * )type -> tp_alloc (type , 0 );
1459
1485
if (link == NULL ) {
1460
1486
Py_DECREF (key );
1461
1487
Py_DECREF (result );
@@ -1811,9 +1837,7 @@ lru_cache_tp_traverse(PyObject *op, visitproc visit, void *arg)
1811
1837
lru_list_elem * link = self -> root .next ;
1812
1838
while (link != & self -> root ) {
1813
1839
lru_list_elem * next = link -> next ;
1814
- Py_VISIT (link -> key );
1815
- Py_VISIT (link -> result );
1816
- Py_VISIT (Py_TYPE (link ));
1840
+ Py_VISIT (link );
1817
1841
link = next ;
1818
1842
}
1819
1843
Py_VISIT (self -> cache );
0 commit comments