@@ -1161,27 +1161,51 @@ typedef struct lru_list_elem {
11611161
11621162#define  lru_list_elem_CAST (op )  ((lru_list_elem *)(op))
11631163
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+ 
11641173static  void 
11651174lru_list_elem_dealloc (PyObject  * op )
11661175{
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 );
11721180    Py_DECREF (tp );
11731181}
11741182
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+ 
11751193static  PyType_Slot  lru_list_elem_type_slots [] =  {
1194+     {Py_tp_clear , lru_list_elem_clear },
11761195    {Py_tp_dealloc , lru_list_elem_dealloc },
1196+     {Py_tp_traverse , lru_list_elem_traverse },
11771197    {0 , 0 }
11781198};
11791199
11801200static  PyType_Spec  lru_list_elem_type_spec  =  {
11811201    .name  =  "functools._lru_list_elem" ,
11821202    .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+     ),
11851209    .slots  =  lru_list_elem_type_slots 
11861210};
11871211
@@ -1454,8 +1478,10 @@ bounded_lru_cache_update_lock_held(lru_cache_object *self,
14541478        self -> root .next  ==  & self -> root )
14551479    {
14561480        /* 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 );
14591485        if  (link  ==  NULL ) {
14601486            Py_DECREF (key );
14611487            Py_DECREF (result );
@@ -1811,9 +1837,7 @@ lru_cache_tp_traverse(PyObject *op, visitproc visit, void *arg)
18111837    lru_list_elem  * link  =  self -> root .next ;
18121838    while  (link  !=  & self -> root ) {
18131839        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 );
18171841        link  =  next ;
18181842    }
18191843    Py_VISIT (self -> cache );
0 commit comments