@@ -85,6 +85,26 @@ whose size is determined when the object is allocated.
85
85
#define PyVarObject_HEAD_INIT (type , size ) \
86
86
{ PyObject_HEAD_INIT(type) size },
87
87
88
+ /*
89
+ In 32 bit systems, an object will be marked as immortal by setting all of the
90
+ lower 30 bits of the reference count field, which is equal to: 0x3FFFFFFF
91
+
92
+ Using the lower 30 bits makes the value backwards compatible by allowing
93
+ C-Extensions without the updated checks in Py_INCREF and Py_DECREF to safely
94
+ increase and decrease the objects reference count. The object would lose its
95
+ immortality, but the execution would still be correct.
96
+
97
+ Reference count increases and decreases will first go through an immortality
98
+ check by comparing the reference count field to the immortality reference count.
99
+ */
100
+ #define _Py_IMMORTAL_REFCNT (UINT_MAX >> 2)
101
+
102
+ #define PyVarObject_HEAD_INIT (type , size ) \
103
+ { \
104
+ PyObject_HEAD_INIT(type) \
105
+ (size) \
106
+ },
107
+
88
108
/* PyObject_VAR_HEAD defines the initial segment of all variable-size
89
109
* container objects. These end with a declaration of an array with 1
90
110
* element, but enough space is malloc'ed so that the array actually
@@ -151,6 +171,15 @@ static inline Py_ssize_t Py_SIZE(PyObject *ob) {
151
171
# define Py_SIZE (ob ) Py_SIZE(_PyObject_CAST(ob))
152
172
#endif
153
173
174
+ static inline Py_ALWAYS_INLINE int _Py_IsImmortal (PyObject * op )
175
+ {
176
+ #if SIZEOF_VOID_P > 4
177
+ return _Py_CAST (PY_INT32_T , op -> ob_refcnt ) < 0 ;
178
+ #else
179
+ return op -> ob_refcnt == _Py_IMMORTAL_REFCNT ;
180
+ #endif
181
+ }
182
+ #define _Py_IsImmortal (op ) _Py_IsImmortal(_PyObject_CAST(op))
154
183
155
184
static inline int Py_IS_TYPE (PyObject * ob , PyTypeObject * type ) {
156
185
return Py_TYPE (ob ) == type ;
@@ -161,6 +190,13 @@ static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
161
190
162
191
163
192
static inline void Py_SET_REFCNT (PyObject * ob , Py_ssize_t refcnt ) {
193
+ // This immortal check is for code that is unaware of immortal objects.
194
+ // The runtime tracks these objects and we should avoid as much
195
+ // as possible having extensions inadvertently change the refcnt
196
+ // of an immortalized object.
197
+ if (_Py_IsImmortal (ob )) {
198
+ return ;
199
+ }
164
200
ob -> ob_refcnt = refcnt ;
165
201
}
166
202
#if !defined(Py_LIMITED_API ) || Py_LIMITED_API + 0 < 0x030b0000
@@ -514,11 +550,18 @@ PyAPI_FUNC(void) Py_DecRef(PyObject *);
514
550
PyAPI_FUNC (void ) _Py_IncRef (PyObject * );
515
551
PyAPI_FUNC (void ) _Py_DecRef (PyObject * );
516
552
517
- static inline void Py_INCREF (PyObject * op )
553
+ static inline Py_ALWAYS_INLINE void Py_INCREF (PyObject * op )
518
554
{
519
- #if defined(Py_REF_DEBUG ) && defined(Py_LIMITED_API ) && Py_LIMITED_API + 0 >= 0x030A0000
520
- // Stable ABI for Python 3.10 built in debug mode.
555
+ #if defined(Py_LIMITED_API ) && (Py_LIMITED_API + 0 >= 0x030c0000 || defined(Py_REF_DEBUG ))
556
+ // Stable ABI implements Py_INCREF() as a function call on limited C API
557
+ // version 3.12 and newer, and on Python built in debug mode. _Py_IncRef()
558
+ // was added to Python 3.10.0a7, use Py_IncRef() on older Python versions.
559
+ // Py_IncRef() accepts NULL whereas _Py_IncRef() doesn't.
560
+ # if Py_LIMITED_API + 0 >= 0x030a00A7
521
561
_Py_IncRef (op );
562
+ # else
563
+ Py_IncRef (op );
564
+ # endif
522
565
#else
523
566
// Non-limited C API and limited C API for Python 3.9 and older access
524
567
// directly PyObject.ob_refcnt.
@@ -532,11 +575,17 @@ static inline void Py_INCREF(PyObject *op)
532
575
# define Py_INCREF (op ) Py_INCREF(_PyObject_CAST(op))
533
576
#endif
534
577
535
-
536
- #if defined(Py_REF_DEBUG ) && defined(Py_LIMITED_API ) && Py_LIMITED_API + 0 >= 0x030A0000
537
- // Stable ABI for limited C API version 3.10 of Python debug build
578
+ #if defined(Py_LIMITED_API ) && (Py_LIMITED_API + 0 >= 0x030c0000 || defined(Py_REF_DEBUG ))
579
+ // Stable ABI implements Py_DECREF() as a function call on limited C API
580
+ // version 3.12 and newer, and on Python built in debug mode. _Py_DecRef() was
581
+ // added to Python 3.10.0a7, use Py_DecRef() on older Python versions.
582
+ // Py_DecRef() accepts NULL whereas _Py_IncRef() doesn't.
538
583
static inline void Py_DECREF (PyObject * op ) {
584
+ # if Py_LIMITED_API + 0 >= 0x030a00A7
539
585
_Py_DecRef (op );
586
+ # else
587
+ Py_DecRef (op );
588
+ # endif
540
589
}
541
590
#define Py_DECREF (op ) Py_DECREF(_PyObject_CAST(op))
542
591
@@ -556,10 +605,13 @@ static inline void Py_DECREF(const char *filename, int lineno, PyObject *op)
556
605
#define Py_DECREF (op ) Py_DECREF(__FILE__, __LINE__, _PyObject_CAST(op))
557
606
558
607
#else
559
- static inline void Py_DECREF (PyObject * op )
608
+ static inline Py_ALWAYS_INLINE void Py_DECREF (PyObject * op )
560
609
{
561
610
// Non-limited C API and limited C API for Python 3.9 and older access
562
611
// directly PyObject.ob_refcnt.
612
+ if (_Py_IsImmortal (op )) {
613
+ return ;
614
+ }
563
615
if (-- op -> ob_refcnt == 0 ) {
564
616
_Py_Dealloc (op );
565
617
}
0 commit comments