mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
gh-117376: Make Py_DECREF
a macro in ceval.c in free-threaded build (#122975)
`Py_DECREF` and `PyStackRef_CLOSE` are now implemented as macros in the free-threaded build in ceval.c. There are two motivations; * MSVC has problems inlining functions in ceval.c in the PGO build. * We will want to mark escaping calls in order to spill the stack pointer in ceval.c and we will want to do this around `_Py_Dealloc` (or `_Py_MergeZeroLocalRefcount` or `_Py_DecRefShared`), not around the entire `Py_DECREF` or `PyStackRef_CLOSE` call.
This commit is contained in:
parent
67f2c84bff
commit
556e855684
2 changed files with 53 additions and 27 deletions
|
@ -190,18 +190,15 @@ PyStackRef_FromPyObjectImmortal(PyObject *obj)
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#ifdef Py_GIL_DISABLED
|
#ifdef Py_GIL_DISABLED
|
||||||
static inline void
|
# define PyStackRef_CLOSE(REF) \
|
||||||
PyStackRef_CLOSE(_PyStackRef stackref)
|
do { \
|
||||||
{
|
_PyStackRef _close_tmp = (REF); \
|
||||||
if (PyStackRef_IsDeferred(stackref)) {
|
if (!PyStackRef_IsDeferred(_close_tmp)) { \
|
||||||
// No assert for being immortal or deferred here.
|
Py_DECREF(PyStackRef_AsPyObjectBorrow(_close_tmp)); \
|
||||||
// The GC unsets deferred objects right before clearing.
|
} \
|
||||||
return;
|
} while (0)
|
||||||
}
|
|
||||||
Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref));
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
# define PyStackRef_CLOSE(stackref) Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref));
|
# define PyStackRef_CLOSE(stackref) Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PyStackRef_XCLOSE(stackref) \
|
#define PyStackRef_XCLOSE(stackref) \
|
||||||
|
@ -227,7 +224,7 @@ PyStackRef_DUP(_PyStackRef stackref)
|
||||||
return stackref;
|
return stackref;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define PyStackRef_DUP(stackref) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)));
|
# define PyStackRef_DUP(stackref) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
|
@ -52,13 +52,27 @@
|
||||||
# error "ceval.c must be build with Py_BUILD_CORE define for best performance"
|
# error "ceval.c must be build with Py_BUILD_CORE define for best performance"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS) && !defined(Py_GIL_DISABLED)
|
#if !defined(Py_DEBUG) && !defined(Py_TRACE_REFS)
|
||||||
// GH-89279: The MSVC compiler does not inline these static inline functions
|
// GH-89279: The MSVC compiler does not inline these static inline functions
|
||||||
// in PGO build in _PyEval_EvalFrameDefault(), because this function is over
|
// in PGO build in _PyEval_EvalFrameDefault(), because this function is over
|
||||||
// the limit of PGO, and that limit cannot be configured.
|
// the limit of PGO, and that limit cannot be configured.
|
||||||
// Define them as macros to make sure that they are always inlined by the
|
// Define them as macros to make sure that they are always inlined by the
|
||||||
// preprocessor.
|
// preprocessor.
|
||||||
// TODO: implement Py_DECREF macro for Py_GIL_DISABLED
|
|
||||||
|
#undef Py_IS_TYPE
|
||||||
|
#define Py_IS_TYPE(ob, type) \
|
||||||
|
(_PyObject_CAST(ob)->ob_type == (type))
|
||||||
|
|
||||||
|
#undef Py_XDECREF
|
||||||
|
#define Py_XDECREF(arg) \
|
||||||
|
do { \
|
||||||
|
PyObject *xop = _PyObject_CAST(arg); \
|
||||||
|
if (xop != NULL) { \
|
||||||
|
Py_DECREF(xop); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#ifndef Py_GIL_DISABLED
|
||||||
|
|
||||||
#undef Py_DECREF
|
#undef Py_DECREF
|
||||||
#define Py_DECREF(arg) \
|
#define Py_DECREF(arg) \
|
||||||
|
@ -74,19 +88,6 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#undef Py_XDECREF
|
|
||||||
#define Py_XDECREF(arg) \
|
|
||||||
do { \
|
|
||||||
PyObject *xop = _PyObject_CAST(arg); \
|
|
||||||
if (xop != NULL) { \
|
|
||||||
Py_DECREF(xop); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#undef Py_IS_TYPE
|
|
||||||
#define Py_IS_TYPE(ob, type) \
|
|
||||||
(_PyObject_CAST(ob)->ob_type == (type))
|
|
||||||
|
|
||||||
#undef _Py_DECREF_SPECIALIZED
|
#undef _Py_DECREF_SPECIALIZED
|
||||||
#define _Py_DECREF_SPECIALIZED(arg, dealloc) \
|
#define _Py_DECREF_SPECIALIZED(arg, dealloc) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -100,6 +101,34 @@
|
||||||
d(op); \
|
d(op); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#else // Py_GIL_DISABLED
|
||||||
|
|
||||||
|
#undef Py_DECREF
|
||||||
|
#define Py_DECREF(arg) \
|
||||||
|
do { \
|
||||||
|
PyObject *op = _PyObject_CAST(arg); \
|
||||||
|
uint32_t local = _Py_atomic_load_uint32_relaxed(&op->ob_ref_local); \
|
||||||
|
if (local == _Py_IMMORTAL_REFCNT_LOCAL) { \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
_Py_DECREF_STAT_INC(); \
|
||||||
|
if (_Py_IsOwnedByCurrentThread(op)) { \
|
||||||
|
local--; \
|
||||||
|
_Py_atomic_store_uint32_relaxed(&op->ob_ref_local, local); \
|
||||||
|
if (local == 0) { \
|
||||||
|
_Py_MergeZeroLocalRefcount(op); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else { \
|
||||||
|
_Py_DecRefShared(op); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#undef _Py_DECREF_SPECIALIZED
|
||||||
|
#define _Py_DECREF_SPECIALIZED(arg, dealloc) Py_DECREF(arg)
|
||||||
|
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue