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.
This commit is contained in:
Mark Shannon 2024-03-26 11:11:42 +00:00 committed by GitHub
parent bf82f77957
commit 8bef34f625
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 56 additions and 43 deletions

View file

@ -113,7 +113,19 @@ static inline void _PyObject_GC_SET_SHARED_INLINE(PyObject *op) {
/* Bit 1 is set when the object is in generation which is GCed currently. */
#define _PyGC_PREV_MASK_COLLECTING 2
/* Bit 0 is set if the object belongs to old space 1 */
/* Bit 0 in _gc_next is the old space bit.
* It is set as follows:
* Young: gcstate->visited_space
* old[0]: 0
* old[1]: 1
* permanent: 0
*
* During a collection all objects handled should have the bit set to
* gcstate->visited_space, as objects are moved from the young gen
* and the increment into old[gcstate->visited_space].
* When object are moved from the pending space, old[gcstate->visited_space^1]
* into the increment, the old space bit is flipped.
*/
#define _PyGC_NEXT_MASK_OLD_SPACE_1 1
#define _PyGC_PREV_SHIFT 2

View file

@ -318,8 +318,8 @@ static inline void _PyObject_GC_TRACK(
PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev);
_PyGCHead_SET_NEXT(last, gc);
_PyGCHead_SET_PREV(gc, last);
_PyGCHead_SET_NEXT(gc, generation0);
assert((gc->_gc_next & _PyGC_NEXT_MASK_OLD_SPACE_1) == 0);
/* Young objects will be moved into the visited space during GC, so set the bit here */
gc->_gc_next = ((uintptr_t)generation0) | interp->gc.visited_space;
generation0->_gc_prev = (uintptr_t)gc;
#endif
}