Skip to content

Commit bec2a0f

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(), _Py_IsOwnedByCurrentThread() and _Py_ThreadId() have to be converted to an inline functions, since non-static Py_SET_REFCNT() function cannot call a static functions. _Py_IsImmortal(), _Py_IsOwnedByCurrentThread() and _Py_ThreadId() are not part of the stable ABI.
1 parent 3d712a9 commit bec2a0f

File tree

6 files changed

+26
-15
lines changed

6 files changed

+26
-15
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

+11-11
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y);
239239
#define Py_Is(x, y) ((x) == (y))
240240

241241
#if defined(Py_GIL_DISABLED) && !defined(Py_LIMITED_API)
242-
static inline uintptr_t
242+
inline uintptr_t
243243
_Py_ThreadId(void)
244244
{
245245
uintptr_t tid;
@@ -285,7 +285,7 @@ _Py_ThreadId(void)
285285
return tid;
286286
}
287287

288-
static inline Py_ALWAYS_INLINE int
288+
inline Py_ALWAYS_INLINE int
289289
_Py_IsOwnedByCurrentThread(PyObject *ob)
290290
{
291291
return ob->ob_tid == _Py_ThreadId();
@@ -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

+11
Original file line numberDiff line numberDiff line change
@@ -2938,3 +2938,14 @@ _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt)
29382938
{
29392939
Py_SET_REFCNT(ob, refcnt);
29402940
}
2941+
2942+
2943+
// Export inline functions as a regular functions
2944+
#ifdef Py_GIL_DISABLED
2945+
extern inline uintptr_t _Py_ThreadId(void);
2946+
extern inline int _Py_IsOwnedByCurrentThread(PyObject *ob);
2947+
#endif
2948+
#undef _Py_IsImmortal
2949+
extern inline PyAPI_FUNC(int) _Py_IsImmortal(PyObject *op);
2950+
#undef Py_SET_REFCNT
2951+
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)