@@ -1435,6 +1435,7 @@ move_to_reachable(PyObject *op, PyGC_Head *reachable, int visited_space)
14351435 return 0 ;
14361436}
14371437
1438+
14381439static Py_ssize_t
14391440mark_all_reachable (PyGC_Head * reachable , PyGC_Head * visited , int visited_space )
14401441{
@@ -1444,18 +1445,77 @@ mark_all_reachable(PyGC_Head *reachable, PyGC_Head *visited, int visited_space)
14441445 .visited_space = visited_space ,
14451446 .size = 0
14461447 };
1448+ Py_ssize_t objects_marked = 0 ;
14471449 while (!gc_list_is_empty (reachable )) {
14481450 PyGC_Head * gc = _PyGCHead_NEXT (reachable );
14491451 assert (gc_old_space (gc ) == visited_space );
14501452 gc_list_move (gc , visited );
14511453 PyObject * op = FROM_GC (gc );
1452- traverseproc traverse = Py_TYPE (op )-> tp_traverse ;
1453- (void ) traverse (op ,
1454- visit_add_to_container ,
1455- & arg );
1454+ assert (PyObject_IS_GC (op ));
1455+ switch (Py_TYPE (op )-> tp_version_tag ) {
1456+ case _Py_TYPE_VERSION_LIST :
1457+ {
1458+ PyListObject * o = (PyListObject * )op ;
1459+ Py_ssize_t i ;
1460+ for (i = Py_SIZE (o ); -- i >= 0 ; ) {
1461+ PyObject * item = o -> ob_item [i ];
1462+ objects_marked += move_to_reachable (item , reachable , visited_space );
1463+ }
1464+ break ;
1465+ }
1466+ case _Py_TYPE_VERSION_TUPLE :
1467+ {
1468+ PyTupleObject * o = (PyTupleObject * )op ;
1469+ for (Py_ssize_t i = Py_SIZE (o ); -- i >= 0 ; ) {
1470+ PyObject * item = o -> ob_item [i ];
1471+ objects_marked += move_to_reachable (item , reachable , visited_space );
1472+ }
1473+ break ;
1474+ }
1475+ case _Py_TYPE_VERSION_DICT :
1476+ {
1477+ PyDictObject * mp = (PyDictObject * )op ;
1478+ PyDictKeysObject * keys = mp -> ma_keys ;
1479+ Py_ssize_t i , n = keys -> dk_nentries ;
1480+ if (DK_IS_UNICODE (keys )) {
1481+ if (_PyDict_HasSplitTable (mp )) {
1482+ if (!mp -> ma_values -> embedded ) {
1483+ for (i = 0 ; i < n ; i ++ ) {
1484+ PyObject * value = mp -> ma_values -> values [i ];
1485+ objects_marked += move_to_reachable (value , reachable , visited_space );
1486+ }
1487+ }
1488+ }
1489+ else {
1490+ PyDictUnicodeEntry * entries = DK_UNICODE_ENTRIES (keys );
1491+ for (i = 0 ; i < n ; i ++ ) {
1492+ PyObject * value = entries [i ].me_value ;
1493+ objects_marked += move_to_reachable (value , reachable , visited_space );
1494+ }
1495+ }
1496+ }
1497+ else {
1498+ PyDictKeyEntry * entries = DK_ENTRIES (keys );
1499+ for (i = 0 ; i < n ; i ++ ) {
1500+ if (entries [i ].me_value != NULL ) {
1501+ PyObject * key = entries [i ].me_key ;
1502+ objects_marked += move_to_reachable (key , reachable , visited_space );
1503+ PyObject * value = entries [i ].me_value ;
1504+ objects_marked += move_to_reachable (value , reachable , visited_space );
1505+ }
1506+ }
1507+ }
1508+ break ;
1509+ }
1510+ default :
1511+ {
1512+ traverseproc traverse = Py_TYPE (op )-> tp_traverse ;
1513+ (void ) traverse (op , visit_add_to_container , & arg );
1514+ }
1515+ }
14561516 }
14571517 gc_list_validate_space (visited , visited_space );
1458- return arg .size ;
1518+ return objects_marked + arg .size ;
14591519}
14601520
14611521static Py_ssize_t
0 commit comments