diff options
author | Ed Nutting <github@ednutting.com> | 2024-12-15 13:51:03 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-15 13:51:03 (GMT) |
commit | ab05beb8cea62636bd86f6f7cf1a82d7efca7162 (patch) | |
tree | 6f3629dccfc9e338cc42d23b2f9c3471e90302ce | |
parent | 7900a85019457c14e8c6abac532846bc9f26760d (diff) | |
download | cpython-ab05beb8cea62636bd86f6f7cf1a82d7efca7162.zip cpython-ab05beb8cea62636bd86f6f7cf1a82d7efca7162.tar.gz cpython-ab05beb8cea62636bd86f6f7cf1a82d7efca7162.tar.bz2 |
gh-127599: Fix _Py_RefcntAdd missing calls to _Py_INCREF_STAT_INC/_Py_INCREF_IMMORTAL_STAT_INC (#127717)
Previously, `_Py_RefcntAdd` hasn't called
`_Py_INCREF_STAT_INC/_Py_INCREF_IMMORTAL_STAT_INC` which is incorrect.
Now it has been fixed.
-rw-r--r-- | Include/cpython/pystats.h | 6 | ||||
-rw-r--r-- | Include/internal/pycore_object.h | 5 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core_and_Builtins/2024-12-07-13-06-09.gh-issue-127599.tXCZb_.rst | 2 |
3 files changed, 13 insertions, 0 deletions
diff --git a/Include/cpython/pystats.h b/Include/cpython/pystats.h index 2ae4800..29ef0c0 100644 --- a/Include/cpython/pystats.h +++ b/Include/cpython/pystats.h @@ -18,6 +18,12 @@ // // Define _PY_INTERPRETER macro to increment interpreter_increfs and // interpreter_decrefs. Otherwise, increment increfs and decrefs. +// +// The number of incref operations counted by `incref` and +// `interpreter_incref` is the number of increment operations, which is +// not equal to the total of all reference counts. A single increment +// operation may increase the reference count of an object by more than +// one. For example, see `_Py_RefcntAdd`. #ifndef Py_CPYTHON_PYSTATS_H # error "this header file must not be included directly" diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 668ea47..d7d68f9 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -131,6 +131,7 @@ extern void _Py_DecRefTotal(PyThreadState *); static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n) { if (_Py_IsImmortal(op)) { + _Py_INCREF_IMMORTAL_STAT_INC(); return; } #ifdef Py_REF_DEBUG @@ -159,6 +160,10 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n) _Py_atomic_add_ssize(&op->ob_ref_shared, (n << _Py_REF_SHARED_SHIFT)); } #endif + // Although the ref count was increased by `n` (which may be greater than 1) + // it is only a single increment (i.e. addition) operation, so only 1 refcnt + // increment operation is counted. + _Py_INCREF_STAT_INC(); } #define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n) diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-07-13-06-09.gh-issue-127599.tXCZb_.rst b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-07-13-06-09.gh-issue-127599.tXCZb_.rst new file mode 100644 index 0000000..565ecb8 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-07-13-06-09.gh-issue-127599.tXCZb_.rst @@ -0,0 +1,2 @@ +Fix statistics for increments of object reference counts (in particular, when +a reference count was increased by more than 1 in a single operation). |