Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Include/internal/pycore_dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,7 @@ PyDictObject *_PyObject_MaterializeManagedDict_LockHeld(PyObject *);
static inline Py_ssize_t
_PyDict_UniqueId(PyDictObject *mp)
{
// Offset by one so that _ma_watcher_tag=0 represents an unassigned id
return (Py_ssize_t)(mp->_ma_watcher_tag >> DICT_UNIQUE_ID_SHIFT) - 1;
return (Py_ssize_t)(mp->_ma_watcher_tag >> DICT_UNIQUE_ID_SHIFT);
}

static inline void
Expand Down
24 changes: 12 additions & 12 deletions Include/internal/pycore_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions Include/internal/pycore_uniqueid.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extern "C" {
// Per-thread reference counting is used along with deferred reference
// counting to avoid scaling bottlenecks due to reference count contention.
//
// An id of -1 is used to indicate that an object doesn't use per-thread
// An id of 0 is used to indicate that an object doesn't use per-thread
// refcounting. This value is used when the object is finalized by the GC
// and during interpreter shutdown to allow the object to be
// deallocated promptly when the object's refcount reaches zero.
Expand Down Expand Up @@ -45,6 +45,8 @@ struct _Py_unique_id_pool {
Py_ssize_t size;
};

#define _Py_INVALID_UNIQUE_ID 0

// Assigns the next id from the pool of ids.
extern Py_ssize_t _PyObject_AssignUniqueId(PyObject *obj);

Expand All @@ -65,7 +67,7 @@ extern void _PyObject_FinalizePerThreadRefcounts(_PyThreadStateImpl *tstate);
extern void _PyObject_FinalizeUniqueIdPool(PyInterpreterState *interp);

// Increfs the object, resizing the thread-local refcount array if necessary.
PyAPI_FUNC(void) _PyObject_ThreadIncrefSlow(PyObject *obj, Py_ssize_t unique_id);
PyAPI_FUNC(void) _PyObject_ThreadIncrefSlow(PyObject *obj, size_t idx);

#endif /* Py_GIL_DISABLED */

Expand Down
Loading
Loading