@@ -13,6 +13,7 @@ extern "C" {
1313#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_PTR_RELAXED()
1414#include "pycore_pystate.h" // _PyThreadState_GET
1515#include "pycore_stats.h" // OBJECT_STAT_INC
16+ #include "pycore_gc.h" // _Py_GC_OBJECT
1617
1718static inline struct _Py_freelists *
1819_Py_freelists_GET (void )
@@ -38,8 +39,8 @@ _Py_freelists_GET(void)
3839 _PyFreeList_Push(&_Py_freelists_GET()->NAME, _PyObject_CAST(op), limit)
3940
4041// Pops a PyObject from the freelist, returns NULL if the freelist is empty.
41- #define _Py_FREELIST_POP (TYPE , NAME ) \
42- _Py_CAST(TYPE*, _PyFreeList_Pop(&_Py_freelists_GET()->NAME))
42+ #define _Py_FREELIST_POP (TYPE , NAME , IS_GC ) \
43+ _Py_CAST(TYPE*, _PyFreeList_Pop(&_Py_freelists_GET()->NAME, (IS_GC) ? _Py_GC_OBJECT : 0 ))
4344
4445// Pops a non-PyObject data structure from the freelist, returns NULL if the
4546// freelist is empty.
@@ -82,13 +83,28 @@ _PyFreeList_PopNoStats(struct _Py_freelist *fl)
8283 return obj ;
8384}
8485
86+ #ifndef NDEBUG
87+ static int
88+ consistent_flags (PyObject * op , int flags )
89+ {
90+ if (Py_TYPE (op )-> tp_flags & Py_TPFLAGS_HAVE_GC ) {
91+ return flags == _Py_GC_OBJECT ;
92+ }
93+ else {
94+ return flags == 0 ;
95+ }
96+ }
97+ #endif
98+
8599static inline PyObject *
86- _PyFreeList_Pop (struct _Py_freelist * fl )
100+ _PyFreeList_Pop (struct _Py_freelist * fl , int flags )
87101{
88102 PyObject * op = _PyFreeList_PopNoStats (fl );
89103 if (op != NULL ) {
90104 OBJECT_STAT_INC (from_freelist );
91105 _Py_NewReference (op );
106+ assert (consistent_flags (op , flags ));
107+ op -> ob_flags = flags ;
92108 }
93109 return op ;
94110}
0 commit comments