mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
gh-128923: Use zero to indicate unassigned unique id (#128925)
In the free threading build, the per thread reference counting uses a unique id for some objects to index into the local reference count table. Use 0 instead of -1 to indicate that the id is not assigned. This avoids bugs where zero-initialized heap type objects look like they have a unique id assigned.
This commit is contained in:
parent
767c89ba7c
commit
d66c08aa75
9 changed files with 110 additions and 33 deletions
|
@ -336,20 +336,20 @@ _Py_THREAD_INCREF_OBJECT(PyObject *obj, Py_ssize_t unique_id)
|
|||
{
|
||||
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
|
||||
|
||||
// Unsigned comparison so that `unique_id=-1`, which indicates that
|
||||
// per-thread refcounting has been disabled on this object, is handled by
|
||||
// the "else".
|
||||
if ((size_t)unique_id < (size_t)tstate->refcounts.size) {
|
||||
// The table index is `unique_id - 1` because 0 is not a valid unique id.
|
||||
// Unsigned comparison so that `idx=-1` is handled by the "else".
|
||||
size_t idx = (size_t)(unique_id - 1);
|
||||
if (idx < (size_t)tstate->refcounts.size) {
|
||||
# ifdef Py_REF_DEBUG
|
||||
_Py_INCREF_IncRefTotal();
|
||||
# endif
|
||||
_Py_INCREF_STAT_INC();
|
||||
tstate->refcounts.values[unique_id]++;
|
||||
tstate->refcounts.values[idx]++;
|
||||
}
|
||||
else {
|
||||
// The slow path resizes the per-thread refcount array if necessary.
|
||||
// It handles the unique_id=-1 case to keep the inlinable function smaller.
|
||||
_PyObject_ThreadIncrefSlow(obj, unique_id);
|
||||
// It handles the unique_id=0 case to keep the inlinable function smaller.
|
||||
_PyObject_ThreadIncrefSlow(obj, idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,15 +386,15 @@ _Py_THREAD_DECREF_OBJECT(PyObject *obj, Py_ssize_t unique_id)
|
|||
{
|
||||
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)_PyThreadState_GET();
|
||||
|
||||
// Unsigned comparison so that `unique_id=-1`, which indicates that
|
||||
// per-thread refcounting has been disabled on this object, is handled by
|
||||
// the "else".
|
||||
if ((size_t)unique_id < (size_t)tstate->refcounts.size) {
|
||||
// The table index is `unique_id - 1` because 0 is not a valid unique id.
|
||||
// Unsigned comparison so that `idx=-1` is handled by the "else".
|
||||
size_t idx = (size_t)(unique_id - 1);
|
||||
if (idx < (size_t)tstate->refcounts.size) {
|
||||
# ifdef Py_REF_DEBUG
|
||||
_Py_DECREF_DecRefTotal();
|
||||
# endif
|
||||
_Py_DECREF_STAT_INC();
|
||||
tstate->refcounts.values[unique_id]--;
|
||||
tstate->refcounts.values[idx]--;
|
||||
}
|
||||
else {
|
||||
// Directly decref the object if the id is not assigned or if
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue