@@ -1401,6 +1401,28 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
14011401    return  n  +  m ;
14021402}
14031403
1404+ static  PyObject  * 
1405+ list_from_object_stack (_PyObjectStack  * stack )
1406+ {
1407+     PyObject  * list  =  PyList_New (_PyObjectStack_Size (stack ));
1408+     if  (list  ==  NULL ) {
1409+         PyObject  * op ;
1410+         while  ((op  =  _PyObjectStack_Pop (stack )) !=  NULL ) {
1411+             Py_DECREF (op );
1412+         }
1413+         return  NULL ;
1414+     }
1415+ 
1416+     PyObject  * op ;
1417+     Py_ssize_t  idx  =  0 ;
1418+     while  ((op  =  _PyObjectStack_Pop (stack )) !=  NULL ) {
1419+         assert (idx  <  PyList_GET_SIZE (list ));
1420+         PyList_SET_ITEM (list , idx ++ , op );
1421+     }
1422+     assert (idx  ==  PyList_GET_SIZE (list ));
1423+     return  list ;
1424+ }
1425+ 
14041426struct  get_referrers_args  {
14051427    struct  visitor_args  base ;
14061428    PyObject  * objs ;
@@ -1435,8 +1457,12 @@ visit_get_referrers(const mi_heap_t *heap, const mi_heap_area_t *area,
14351457    }
14361458
14371459    struct  get_referrers_args  * arg  =  (struct  get_referrers_args  * )args ;
1460+     if  (op  ==  arg -> objs ) {
1461+         // Don't include the tuple itself in the referrers list. 
1462+         return  true;
1463+     }
14381464    if  (Py_TYPE (op )-> tp_traverse (op , referrersvisit , arg -> objs )) {
1439-         if  (_PyObjectStack_Push (& arg -> results , op ) <  0 ) {
1465+         if  (_PyObjectStack_Push (& arg -> results , Py_NewRef ( op ) ) <  0 ) {
14401466            return  false;
14411467        }
14421468    }
@@ -1447,11 +1473,6 @@ visit_get_referrers(const mi_heap_t *heap, const mi_heap_area_t *area,
14471473PyObject  * 
14481474_PyGC_GetReferrers (PyInterpreterState  * interp , PyObject  * objs )
14491475{
1450-     PyObject  * result  =  PyList_New (0 );
1451-     if  (!result ) {
1452-         return  NULL ;
1453-     }
1454- 
14551476    // NOTE: We can't append to the PyListObject during gc_visit_heaps() 
14561477    // because PyList_Append() may reclaim an abandoned mimalloc segments 
14571478    // while we are traversing them. 
@@ -1460,23 +1481,12 @@ _PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs)
14601481    int  err  =  gc_visit_heaps (interp , & visit_get_referrers , & args .base );
14611482    _PyEval_StartTheWorld (interp );
14621483
1484+     PyObject  * list  =  list_from_object_stack (& args .results );
14631485    if  (err  <  0 ) {
14641486        PyErr_NoMemory ();
1465-         goto  error ;
1487+         Py_CLEAR ( list ) ;
14661488    }
1467- 
1468-     PyObject  * op ;
1469-     while  ((op  =  _PyObjectStack_Pop (& args .results )) !=  NULL ) {
1470-         if  (op  !=  objs  &&  PyList_Append (result , op ) <  0 ) {
1471-             goto error ;
1472-         }
1473-     }
1474-     return  result ;
1475- 
1476- error :
1477-     Py_DECREF (result );
1478-     _PyObjectStack_Clear (& args .results );
1479-     return  NULL ;
1489+     return  list ;
14801490}
14811491
14821492struct  get_objects_args  {
@@ -1499,7 +1509,7 @@ visit_get_objects(const mi_heap_t *heap, const mi_heap_area_t *area,
14991509    }
15001510
15011511    struct  get_objects_args  * arg  =  (struct  get_objects_args  * )args ;
1502-     if  (_PyObjectStack_Push (& arg -> objects , op ) <  0 ) {
1512+     if  (_PyObjectStack_Push (& arg -> objects , Py_NewRef ( op ) ) <  0 ) {
15031513        return  false;
15041514    }
15051515    return  true;
@@ -1508,11 +1518,6 @@ visit_get_objects(const mi_heap_t *heap, const mi_heap_area_t *area,
15081518PyObject  * 
15091519_PyGC_GetObjects (PyInterpreterState  * interp , int  generation )
15101520{
1511-     PyObject  * result  =  PyList_New (0 );
1512-     if  (!result ) {
1513-         return  NULL ;
1514-     }
1515- 
15161521    // NOTE: We can't append to the PyListObject during gc_visit_heaps() 
15171522    // because PyList_Append() may reclaim an abandoned mimalloc segments 
15181523    // while we are traversing them. 
@@ -1521,23 +1526,12 @@ _PyGC_GetObjects(PyInterpreterState *interp, int generation)
15211526    int  err  =  gc_visit_heaps (interp , & visit_get_objects , & args .base );
15221527    _PyEval_StartTheWorld (interp );
15231528
1529+     PyObject  * list  =  list_from_object_stack (& args .objects );
15241530    if  (err  <  0 ) {
15251531        PyErr_NoMemory ();
1526-         goto  error ;
1532+         Py_CLEAR ( list ) ;
15271533    }
1528- 
1529-     PyObject  * op ;
1530-     while  ((op  =  _PyObjectStack_Pop (& args .objects )) !=  NULL ) {
1531-         if  (op  !=  result  &&  PyList_Append (result , op ) <  0 ) {
1532-             goto error ;
1533-         }
1534-     }
1535-     return  result ;
1536- 
1537- error :
1538-     Py_DECREF (result );
1539-     _PyObjectStack_Clear (& args .objects );
1540-     return  NULL ;
1534+     return  list ;
15411535}
15421536
15431537static  bool 
0 commit comments