@@ -1404,7 +1404,7 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
14041404struct  get_referrers_args  {
14051405    struct  visitor_args  base ;
14061406    PyObject  * objs ;
1407-     struct   worklist  results ;
1407+     _PyObjectStack  results ;
14081408};
14091409
14101410static  int 
@@ -1428,11 +1428,17 @@ visit_get_referrers(const mi_heap_t *heap, const mi_heap_area_t *area,
14281428    if  (op  ==  NULL ) {
14291429        return  true;
14301430    }
1431+     if  (op -> ob_gc_bits  &  (_PyGC_BITS_UNREACHABLE  | _PyGC_BITS_FROZEN )) {
1432+         // Exclude unreachable objects (in-progress GC) and frozen 
1433+         // objects from gc.get_objects() to match the default build. 
1434+         return  true;
1435+     }
14311436
14321437    struct  get_referrers_args  * arg  =  (struct  get_referrers_args  * )args ;
14331438    if  (Py_TYPE (op )-> tp_traverse (op , referrersvisit , arg -> objs )) {
1434-         op -> ob_tid  =  0 ;  // we will restore the refcount later 
1435-         worklist_push (& arg -> results , op );
1439+         if  (_PyObjectStack_Push (& arg -> results , op ) <  0 ) {
1440+             return  false;
1441+         }
14361442    }
14371443
14381444    return  true;
@@ -1446,43 +1452,36 @@ _PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs)
14461452        return  NULL ;
14471453    }
14481454
1455+     // NOTE: We can't append to the PyListObject during gc_visit_heaps() 
1456+     // because PyList_Append() may reclaim an abandoned mimalloc segments 
1457+     // while we are traversing them. 
1458+     struct  get_referrers_args  args  =  { .objs  =  objs  };
14491459    _PyEval_StopTheWorld (interp );
1460+     int  err  =  gc_visit_heaps (interp , & visit_get_referrers , & args .base );
1461+     _PyEval_StartTheWorld (interp );
14501462
1451-     // Append all objects to a worklist. This abuses ob_tid. We will restore 
1452-     // it later. NOTE: We can't append to the PyListObject during 
1453-     // gc_visit_heaps() because PyList_Append() may reclaim an abandoned 
1454-     // mimalloc segments while we are traversing them. 
1455-     struct  get_referrers_args  args  =  { .objs  =  objs  };
1456-     gc_visit_heaps (interp , & visit_get_referrers , & args .base );
1463+     if  (err  <  0 ) {
1464+         PyErr_NoMemory ();
1465+         goto error ;
1466+     }
14571467
1458-     bool  error  =  false;
14591468    PyObject  * op ;
1460-     while  ((op  =  worklist_pop (& args .results )) !=  NULL ) {
1461-         gc_restore_tid (op );
1469+     while  ((op  =  _PyObjectStack_Pop (& args .results )) !=  NULL ) {
14621470        if  (op  !=  objs  &&  PyList_Append (result , op ) <  0 ) {
1463-             error  =  true;
1464-             break ;
1471+             goto error ;
14651472        }
14661473    }
1467- 
1468-     // In case of error, clear the remaining worklist 
1469-     while  ((op  =  worklist_pop (& args .results )) !=  NULL ) {
1470-         gc_restore_tid (op );
1471-     }
1472- 
1473-     _PyEval_StartTheWorld (interp );
1474- 
1475-     if  (error ) {
1476-         Py_DECREF (result );
1477-         return  NULL ;
1478-     }
1479- 
14801474    return  result ;
1475+ 
1476+ error :
1477+     Py_DECREF (result );
1478+     _PyObjectStack_Clear (& args .results );
1479+     return  NULL ;
14811480}
14821481
14831482struct  get_objects_args  {
14841483    struct  visitor_args  base ;
1485-     struct   worklist  objects ;
1484+     _PyObjectStack  objects ;
14861485};
14871486
14881487static  bool 
@@ -1493,11 +1492,16 @@ visit_get_objects(const mi_heap_t *heap, const mi_heap_area_t *area,
14931492    if  (op  ==  NULL ) {
14941493        return  true;
14951494    }
1495+     if  (op -> ob_gc_bits  &  (_PyGC_BITS_UNREACHABLE  | _PyGC_BITS_FROZEN )) {
1496+         // Exclude unreachable objects (in-progress GC) and frozen 
1497+         // objects from gc.get_objects() to match the default build. 
1498+         return  true;
1499+     }
14961500
14971501    struct  get_objects_args  * arg  =  (struct  get_objects_args  * )args ;
1498-     op -> ob_tid   =   0 ;   // we will restore the refcount later 
1499-     worklist_push ( & arg -> objects ,  op ) ;
1500- 
1502+     if  ( _PyObjectStack_Push ( & arg -> objects ,  op )  <   0 ) { 
1503+          return  false ;
1504+     } 
15011505    return  true;
15021506}
15031507
@@ -1509,38 +1513,31 @@ _PyGC_GetObjects(PyInterpreterState *interp, int generation)
15091513        return  NULL ;
15101514    }
15111515
1516+     // NOTE: We can't append to the PyListObject during gc_visit_heaps() 
1517+     // because PyList_Append() may reclaim an abandoned mimalloc segments 
1518+     // while we are traversing them. 
1519+     struct  get_objects_args  args  =  { 0  };
15121520    _PyEval_StopTheWorld (interp );
1521+     int  err  =  gc_visit_heaps (interp , & visit_get_objects , & args .base );
1522+     _PyEval_StartTheWorld (interp );
15131523
1514-     // Append all objects to a worklist. This abuses ob_tid. We will restore 
1515-     // it later. NOTE: We can't append to the list during gc_visit_heaps() 
1516-     // because PyList_Append() may reclaim an abandoned mimalloc segment 
1517-     // while we are traversing it. 
1518-     struct  get_objects_args  args  =  { 0  };
1519-     gc_visit_heaps (interp , & visit_get_objects , & args .base );
1524+     if  (err  <  0 ) {
1525+         PyErr_NoMemory ();
1526+         goto error ;
1527+     }
15201528
1521-     bool  error  =  false;
15221529    PyObject  * op ;
1523-     while  ((op  =  worklist_pop (& args .objects )) !=  NULL ) {
1524-         gc_restore_tid (op );
1530+     while  ((op  =  _PyObjectStack_Pop (& args .objects )) !=  NULL ) {
15251531        if  (op  !=  result  &&  PyList_Append (result , op ) <  0 ) {
1526-             error  =  true;
1527-             break ;
1532+             goto error ;
15281533        }
15291534    }
1530- 
1531-     // In case of error, clear the remaining worklist 
1532-     while  ((op  =  worklist_pop (& args .objects )) !=  NULL ) {
1533-         gc_restore_tid (op );
1534-     }
1535- 
1536-     _PyEval_StartTheWorld (interp );
1537- 
1538-     if  (error ) {
1539-         Py_DECREF (result );
1540-         return  NULL ;
1541-     }
1542- 
15431535    return  result ;
1536+ 
1537+ error :
1538+     Py_DECREF (result );
1539+     _PyObjectStack_Clear (& args .objects );
1540+     return  NULL ;
15441541}
15451542
15461543static  bool 
0 commit comments