gh-111506: Implement Py_SET_REFCNT() as opaque function in limited C API (#111508)

In the limited C API version 3.13, Py_SET_REFCNT() function is now
implemented as an opaque function call.

Add _Py_SetRefcnt() to the stable ABI.
This commit is contained in:
Victor Stinner 2023-11-03 18:18:57 +01:00 committed by GitHub
parent e0afed7e27
commit 20cfab903d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 2 deletions

View File

@ -327,7 +327,15 @@ static inline int Py_IS_TYPE(PyObject *ob, PyTypeObject *type) {
#endif
// Py_SET_REFCNT() implementation for stable ABI
PyAPI_FUNC(void) _Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt);
static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030d0000
// Stable ABI implements Py_SET_REFCNT() as a function call
// on limited C API version 3.13 and newer.
_Py_SetRefcnt(ob, refcnt);
#else
// This immortal check is for code that is unaware of immortal objects.
// The runtime tracks these objects and we should avoid as much
// as possible having extensions inadvertently change the refcnt
@ -335,7 +343,7 @@ static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
if (_Py_IsImmortal(ob)) {
return;
}
#if !defined(Py_NOGIL)
#ifndef Py_NOGIL
ob->ob_refcnt = refcnt;
#else
if (_Py_IsOwnedByCurrentThread(ob)) {
@ -352,7 +360,8 @@ static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
ob->ob_ref_local = 0;
ob->ob_ref_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED);
}
#endif
#endif // Py_NOGIL
#endif // Py_LIMITED_API+0 < 0x030d0000
}
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
# define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), (refcnt))

View File

@ -907,6 +907,7 @@ SYMBOL_NAMES = (
"_Py_IncRef",
"_Py_NoneStruct",
"_Py_NotImplementedStruct",
"_Py_SetRefcnt",
"_Py_SwappedOp",
"_Py_TrueStruct",
"_Py_VaBuildValue_SizeT",

View File

@ -0,0 +1,2 @@
In the limited C API version 3.13, :c:func:`Py_SET_REFCNT` function is now
implemented as an opaque function call. Patch by Victor Stinner.

View File

@ -2480,3 +2480,6 @@
added = '3.13'
[function.PyUnicode_AsUTF8]
added = '3.13'
[function._Py_SetRefcnt]
added = '3.13'
abi_only = true

View File

@ -2931,3 +2931,11 @@ int Py_IsFalse(PyObject *x)
{
return Py_Is(x, Py_False);
}
// Py_SET_REFCNT() implementation for stable ABI
void
_Py_SetRefcnt(PyObject *ob, Py_ssize_t refcnt)
{
Py_SET_REFCNT(ob, refcnt);
}

1
PC/python3dll.c generated
View File

@ -19,6 +19,7 @@ EXPORT_FUNC(_Py_Dealloc)
EXPORT_FUNC(_Py_DecRef)
EXPORT_FUNC(_Py_IncRef)
EXPORT_FUNC(_Py_NegativeRefcount)
EXPORT_FUNC(_Py_SetRefcnt)
EXPORT_FUNC(_Py_VaBuildValue_SizeT)
EXPORT_FUNC(_PyArg_Parse_SizeT)
EXPORT_FUNC(_PyArg_ParseTuple_SizeT)