Skip to content

Commit 076136e

Browse files
committed
pythongh-111506: Implement Py_SET_REFCNT() as inline function
Convert Py_SET_REFCNT() and _Py_IsImmortal() static inline functions to inline functions. Py_SET_REFCNT() function is now exported as "Py_SET_REFCNT" name in the stable ABI, instead of "_Py_SetRefcnt". _Py_IsImmortal() has to be converted to an inline function, since non-static Py_SET_REFCNT() function cannot call a static _Py_IsImmortal() function. _Py_IsImmortal() is not part of the stable ABI.
1 parent f8c0198 commit 076136e

File tree

6 files changed

+21
-13
lines changed

6 files changed

+21
-13
lines changed

Doc/data/stable_abi.dat

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/object.h

+9-9
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,8 @@ static inline Py_ssize_t Py_SIZE(PyObject *ob) {
332332
# define Py_SIZE(ob) Py_SIZE(_PyObject_CAST(ob))
333333
#endif
334334

335-
static inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op)
335+
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000
336+
inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op)
336337
{
337338
#if defined(Py_GIL_DISABLED)
338339
return (op->ob_ref_local == _Py_IMMORTAL_REFCNT_LOCAL);
@@ -343,6 +344,8 @@ static inline Py_ALWAYS_INLINE int _Py_IsImmortal(PyObject *op)
343344
#endif
344345
}
345346
#define _Py_IsImmortal(op) _Py_IsImmortal(_PyObject_CAST(op))
347+
#endif // !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000
348+
346349

347350
static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
348351
return Py_TYPE(ob) == type;
@@ -352,15 +355,12 @@ static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
352355
#endif
353356

354357

355-
// Py_SET_REFCNT() implementation for stable ABI
356-
PyAPI_FUNC(void) _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt);
357-
358-
static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
358+
// Stable ABI implements Py_SET_REFCNT() as an opaque function call in the
359+
// limited C API version 3.13 and newer.
359360
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030d0000
360-
// Stable ABI implements Py_SET_REFCNT() as a function call
361-
// on limited C API version 3.13 and newer.
362-
_Py_SetRefcnt(ob, refcnt);
361+
PyAPI_DATA(void) Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt);
363362
#else
363+
inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
364364
// This immortal check is for code that is unaware of immortal objects.
365365
// The runtime tracks these objects and we should avoid as much
366366
// as possible having extensions inadvertently change the refcnt
@@ -394,11 +394,11 @@ static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
394394
ob->ob_ref_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED);
395395
}
396396
#endif // Py_GIL_DISABLED
397-
#endif // Py_LIMITED_API+0 < 0x030d0000
398397
}
399398
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
400399
# define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), (refcnt))
401400
#endif
401+
#endif // !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030d0000
402402

403403

404404
static inline void Py_SET_TYPE(PyObject *ob, PyTypeObject *type) {

Lib/test/test_stable_abi_ctypes.py

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Misc/stable_abi.toml

+1-2
Original file line numberDiff line numberDiff line change
@@ -2478,6 +2478,5 @@
24782478
added = '3.13'
24792479
[function.PySys_AuditTuple]
24802480
added = '3.13'
2481-
[function._Py_SetRefcnt]
2481+
[function.Py_SET_REFCNT]
24822482
added = '3.13'
2483-
abi_only = true

Objects/object.c

+8
Original file line numberDiff line numberDiff line change
@@ -2938,3 +2938,11 @@ _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt)
29382938
{
29392939
Py_SET_REFCNT(ob, refcnt);
29402940
}
2941+
2942+
// Export _Py_IsImmortal() as a regular function
2943+
#undef _Py_IsImmortal
2944+
extern inline PyAPI_FUNC(int) _Py_IsImmortal(PyObject *op);
2945+
2946+
// Export Py_SET_REFCNT() as a regular function in stable ABI
2947+
#undef Py_SET_REFCNT
2948+
extern inline PyAPI_FUNC(void) Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt);

PC/python3dll.c

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)