GH-117108: Set the "old space bit" to "visited" for all young objects… · python/cpython@8bef34f · GitHub
Skip to content

Commit 8bef34f

Browse files
authored
GH-117108: Set the "old space bit" to "visited" for all young objects (#117213)
Change old space bit of young objects from 0 to gcstate->visited_space. This ensures that any object created *and* collected during cycle GC has the bit set correctly.
1 parent bf82f77 commit 8bef34f

5 files changed

Lines changed: 56 additions & 43 deletions

File tree

Include/internal/pycore_gc.h

Lines changed: 13 additions & 1 deletion

Include/internal/pycore_object.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -318,8 +318,8 @@ static inline void _PyObject_GC_TRACK(
318318
PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev);
319319
_PyGCHead_SET_NEXT(last, gc);
320320
_PyGCHead_SET_PREV(gc, last);
321-
_PyGCHead_SET_NEXT(gc, generation0);
322-
assert((gc->_gc_next & _PyGC_NEXT_MASK_OLD_SPACE_1) == 0);
321+
/* Young objects will be moved into the visited space during GC, so set the bit here */
322+
gc->_gc_next = ((uintptr_t)generation0) | interp->gc.visited_space;
323323
generation0->_gc_prev = (uintptr_t)gc;
324324
#endif
325325
}

Lib/test/test_gc.py

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -823,32 +823,10 @@ def test_get_objects_generations(self):
823823
self.assertTrue(
824824
any(l is element for element in gc.get_objects(generation=0))
825825
)
826-
self.assertFalse(
827-
any(l is element for element in gc.get_objects(generation=1))
828-
)
829-
self.assertFalse(
830-
any(l is element for element in gc.get_objects(generation=2))
831-
)
832-
gc.collect(generation=0)
833-
self.assertFalse(
834-
any(l is element for element in gc.get_objects(generation=0))
835-
)
836-
self.assertTrue(
837-
any(l is element for element in gc.get_objects(generation=1))
838-
)
839-
self.assertFalse(
840-
any(l is element for element in gc.get_objects(generation=2))
841-
)
842-
gc.collect(generation=2)
826+
gc.collect()
843827
self.assertFalse(
844828
any(l is element for element in gc.get_objects(generation=0))
845829
)
846-
self.assertFalse(
847-
any(l is element for element in gc.get_objects(generation=1))
848-
)
849-
self.assertTrue(
850-
any(l is element for element in gc.get_objects(generation=2))
851-
)
852830
del l
853831
gc.collect()
854832

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Change the old space bit of objects in the young generation from 0 to
2+
gcstate->visited, so that any objects created during GC will have the old
3+
bit set correctly if they get moved into the old generation.

Python/gc.c

Lines changed: 37 additions & 17 deletions

0 commit comments

Comments
 (0)