Skip to content
Merged
2 changes: 1 addition & 1 deletion Modules/_ctypes/_ctypes.c
Original file line number Diff line number Diff line change
Expand Up @@ -3251,7 +3251,7 @@ PyCData_MallocBuffer(CDataObject *obj, StgInfo *info)
* used in constructors and therefore does not have concurrent
* access.
*/
assert (Py_REFCNT(obj) == 1);
assert (_PyObject_IsUniquelyReferenced((PyObject *)obj));
assert(stginfo_get_dict_final(info) == 1);

if ((size_t)info->size <= sizeof(obj->b_value)) {
Expand Down
5 changes: 3 additions & 2 deletions Modules/_elementtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -912,7 +912,7 @@ deepcopy(elementtreestate *st, PyObject *object, PyObject *memo)
return Py_NewRef(object);
}

if (Py_REFCNT(object) == 1) {
if (_PyObject_IsUniquelyReferenced(object)) {
if (PyDict_CheckExact(object)) {
PyObject *key, *value;
Py_ssize_t pos = 0;
Expand Down Expand Up @@ -2794,7 +2794,8 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
self->data = Py_NewRef(data);
} else {
/* more than one item; use a list to collect items */
if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 &&
if (PyBytes_CheckExact(self->data) &&
_PyObject_IsUniquelyReferenced(self->data) &&
PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) {
/* XXX this code path unused in Python 3? */
/* expat often generates single character data sections; handle
Expand Down
4 changes: 2 additions & 2 deletions Modules/_functoolsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ partial_new(PyTypeObject *type, PyObject *args, PyObject *kw)
if (kw == NULL) {
pto->kw = PyDict_New();
}
else if (Py_REFCNT(kw) == 1) {
else if (_PyObject_IsUniquelyReferenced(kw)) {
pto->kw = Py_NewRef(kw);
}
else {
Expand Down Expand Up @@ -1093,7 +1093,7 @@ _functools_reduce_impl(PyObject *module, PyObject *func, PyObject *seq,
result = op2;
else {
/* Update the args tuple in-place */
assert(Py_REFCNT(args) == 1);
assert(_PyObject_IsUniquelyReferenced(args));
Py_XSETREF(_PyTuple_ITEMS(args)[0], result);
Py_XSETREF(_PyTuple_ITEMS(args)[1], op2);
if ((result = PyObject_Call(func, args, NULL)) == NULL) {
Expand Down
4 changes: 2 additions & 2 deletions Modules/_testcapi/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ negative_refcount(PyObject *self, PyObject *Py_UNUSED(args))
if (obj == NULL) {
return NULL;
}
assert(Py_REFCNT(obj) == 1);
assert(PyUnstable_Object_IsUniquelyReferenced(obj));

Py_SET_REFCNT(obj, 0);
/* Py_DECREF() must call _Py_NegativeRefcount() and abort Python */
Expand All @@ -275,7 +275,7 @@ decref_freed_object(PyObject *self, PyObject *Py_UNUSED(args))
if (obj == NULL) {
return NULL;
}
assert(Py_REFCNT(obj) == 1);
assert(PyUnstable_Object_IsUniquelyReferenced(obj));

// Deallocate the memory
Py_DECREF(obj);
Expand Down
14 changes: 7 additions & 7 deletions Modules/itertoolsmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ pairwise_next(PyObject *op)
}

result = po->result;
if (Py_REFCNT(result) == 1) {
if (_PyObject_IsUniquelyReferenced(result)) {
Py_INCREF(result);
PyObject *last_old = PyTuple_GET_ITEM(result, 0);
PyObject *last_new = PyTuple_GET_ITEM(result, 1);
Expand Down Expand Up @@ -802,7 +802,7 @@ teedataobject_traverse(PyObject *op, visitproc visit, void * arg)
static void
teedataobject_safe_decref(PyObject *obj)
{
while (obj && Py_REFCNT(obj) == 1) {
while (obj && _PyObject_IsUniquelyReferenced(obj)) {
teedataobject *tmp = teedataobject_CAST(obj);
PyObject *nextlink = tmp->nextlink;
tmp->nextlink = NULL;
Expand Down Expand Up @@ -2143,7 +2143,7 @@ product_next_lock_held(PyObject *op)
_PyTuple_Recycle(result);
}
/* Now, we've got the only copy so we can update it in-place */
assert (npools==0 || Py_REFCNT(result) == 1);
assert (npools==0 || _PyObject_IsUniquelyReferenced(result));

/* Update the pool indices right-to-left. Only advance to the
next pool when the previous one rolls-over */
Expand Down Expand Up @@ -2381,7 +2381,7 @@ combinations_next_lock_held(PyObject *op)
* CPython's empty tuple is a singleton and cached in
* PyTuple's freelist.
*/
assert(r == 0 || Py_REFCNT(result) == 1);
assert(r == 0 || _PyObject_IsUniquelyReferenced(result));

/* Scan indices right-to-left until finding one that is not
at its maximum (i + n - r). */
Expand Down Expand Up @@ -2633,7 +2633,7 @@ cwr_next(PyObject *op)
}
/* Now, we've got the only copy so we can update it in-place CPython's
empty tuple is a singleton and cached in PyTuple's freelist. */
assert(r == 0 || Py_REFCNT(result) == 1);
assert(r == 0 || _PyObject_IsUniquelyReferenced(result));

/* Scan indices right-to-left until finding one that is not
* at its maximum (n-1). */
Expand Down Expand Up @@ -2893,7 +2893,7 @@ permutations_next(PyObject *op)
_PyTuple_Recycle(result);
}
/* Now, we've got the only copy so we can update it in-place */
assert(r == 0 || Py_REFCNT(result) == 1);
assert(r == 0 || _PyObject_IsUniquelyReferenced(result));

/* Decrement rightmost cycle, moving leftward upon zero rollover */
for (i=r-1 ; i>=0 ; i--) {
Expand Down Expand Up @@ -3847,7 +3847,7 @@ zip_longest_next(PyObject *op)
return NULL;
if (lz->numactive == 0)
return NULL;
if (Py_REFCNT(result) == 1) {
if (_PyObject_IsUniquelyReferenced(result)) {
Py_INCREF(result);
for (i=0 ; i < tuplesize ; i++) {
it = PyTuple_GET_ITEM(lz->ittuple, i);
Expand Down
2 changes: 1 addition & 1 deletion Objects/bytesobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -3171,7 +3171,7 @@ PyBytes_Concat(PyObject **pv, PyObject *w)
return;
}

if (Py_REFCNT(*pv) == 1 && PyBytes_CheckExact(*pv)) {
if (_PyObject_IsUniquelyReferenced(*pv) && PyBytes_CheckExact(*pv)) {
/* Only one reference, so we can resize in place */
Py_ssize_t oldsize;
Py_buffer wb;
Expand Down
10 changes: 2 additions & 8 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -5670,13 +5670,7 @@ dictiter_iternext_threadsafe(PyDictObject *d, PyObject *self,
static bool
has_unique_reference(PyObject *op)
{
#ifdef Py_GIL_DISABLED
return (_Py_IsOwnedByCurrentThread(op) &&
op->ob_ref_local == 1 &&
_Py_atomic_load_ssize_relaxed(&op->ob_ref_shared) == 0);
#else
return Py_REFCNT(op) == 1;
#endif
return _PyObject_IsUniquelyReferenced(op) == 1;
}

static bool
Expand Down Expand Up @@ -5828,7 +5822,7 @@ dictreviter_iter_lock_held(PyDictObject *d, PyObject *self)
}
else if (Py_IS_TYPE(di, &PyDictRevIterItem_Type)) {
result = di->di_result;
if (Py_REFCNT(result) == 1) {
if (_PyObject_IsUniquelyReferenced(result)) {
PyObject *oldkey = PyTuple_GET_ITEM(result, 0);
PyObject *oldvalue = PyTuple_GET_ITEM(result, 1);
PyTuple_SET_ITEM(result, 0, Py_NewRef(key));
Expand Down
3 changes: 2 additions & 1 deletion Objects/listobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ ensure_shared_on_resize(PyListObject *self)
// We can't use _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED here because
// the `CALL_LIST_APPEND` bytecode handler may lock the list without
// a critical section.
assert(Py_REFCNT(self) == 1 || PyMutex_IsLocked(&_PyObject_CAST(self)->ob_mutex));
assert(_PyObject_IsUniquelyReferenced((PyObject *)self) ||
PyMutex_IsLocked(&_PyObject_CAST(self)->ob_mutex));

// Ensure that the list array is freed using QSBR if we are not the
// owning thread.
Expand Down
18 changes: 10 additions & 8 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ _PyLong_Negate(PyLongObject **x_p)
PyLongObject *x;

x = (PyLongObject *)*x_p;
if (Py_REFCNT(x) == 1) {
if (_PyObject_IsUniquelyReferenced((PyObject *)x)) {
_PyLong_FlipSign(x);
return;
}
Expand Down Expand Up @@ -3848,7 +3848,7 @@ long_add(PyLongObject *a, PyLongObject *b)
and thus z must be a multiple-digit int.
That also means z is not an element of
small_ints, so negating it in-place is safe. */
assert(Py_REFCNT(z) == 1);
assert(_PyObject_IsUniquelyReferenced((PyObject *)z));
_PyLong_FlipSign(z);
}
}
Expand Down Expand Up @@ -3895,7 +3895,8 @@ long_sub(PyLongObject *a, PyLongObject *b)
else {
z = x_add(a, b);
if (z != NULL) {
assert(_PyLong_IsZero(z) || Py_REFCNT(z) == 1);
assert(_PyLong_IsZero(z) ||
_PyObject_IsUniquelyReferenced((PyObject *)z));
_PyLong_FlipSign(z);
}
}
Expand Down Expand Up @@ -5487,7 +5488,7 @@ long_lshift1(PyLongObject *a, Py_ssize_t wordshift, digit remshift)
if (z == NULL)
return NULL;
if (_PyLong_IsNegative(a)) {
assert(Py_REFCNT(z) == 1);
assert(_PyObject_IsUniquelyReferenced((PyObject *)z));
_PyLong_FlipSign(z);
}
for (i = 0; i < wordshift; i++)
Expand Down Expand Up @@ -5849,7 +5850,7 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg)
assert(size_a >= 0);
_PyLong_SetSignAndDigitCount(c, 1, size_a);
}
else if (Py_REFCNT(a) == 1) {
else if (_PyObject_IsUniquelyReferenced((PyObject *)a)) {
c = (PyLongObject*)Py_NewRef(a);
}
else {
Expand All @@ -5863,7 +5864,8 @@ _PyLong_GCD(PyObject *aarg, PyObject *barg)
assert(size_a >= 0);
_PyLong_SetSignAndDigitCount(d, 1, size_a);
}
else if (Py_REFCNT(b) == 1 && size_a <= alloc_b) {
else if (_PyObject_IsUniquelyReferenced((PyObject *)b) &&
size_a <= alloc_b) {
d = (PyLongObject*)Py_NewRef(b);
assert(size_a >= 0);
_PyLong_SetSignAndDigitCount(d, 1, size_a);
Expand Down Expand Up @@ -6951,7 +6953,7 @@ PyLongWriter_Discard(PyLongWriter *writer)
}

PyLongObject *obj = (PyLongObject *)writer;
assert(Py_REFCNT(obj) == 1);
assert(_PyObject_IsUniquelyReferenced((PyObject *)obj));
Py_DECREF(obj);
}

Expand All @@ -6960,7 +6962,7 @@ PyObject*
PyLongWriter_Finish(PyLongWriter *writer)
{
PyLongObject *obj = (PyLongObject *)writer;
assert(Py_REFCNT(obj) == 1);
assert(_PyObject_IsUniquelyReferenced((PyObject *)obj));

// Normalize and get singleton if possible
obj = maybe_small_long(long_normalize(obj));
Expand Down
4 changes: 2 additions & 2 deletions Objects/setobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1058,7 +1058,7 @@ set_update_lock_held(PySetObject *so, PyObject *other)
static int
set_update_local(PySetObject *so, PyObject *other)
{
assert(Py_REFCNT(so) == 1);
assert(_PyObject_IsUniquelyReferenced((PyObject *)so));
if (PyAnySet_Check(other)) {
int rv;
Py_BEGIN_CRITICAL_SECTION(other);
Expand Down Expand Up @@ -2444,7 +2444,7 @@ set_init(PyObject *so, PyObject *args, PyObject *kwds)
if (!PyArg_UnpackTuple(args, Py_TYPE(self)->tp_name, 0, 1, &iterable))
return -1;

if (Py_REFCNT(self) == 1 && self->fill == 0) {
if (_PyObject_IsUniquelyReferenced((PyObject *)self) && self->fill == 0) {
self->hash = -1;
if (iterable == NULL) {
return 0;
Expand Down
4 changes: 2 additions & 2 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1162,7 +1162,7 @@ static int
resize_inplace(PyObject *unicode, Py_ssize_t length)
{
assert(!PyUnicode_IS_COMPACT(unicode));
assert(Py_REFCNT(unicode) == 1);
assert(_PyObject_IsUniquelyReferenced(unicode));

Py_ssize_t new_size;
Py_ssize_t char_size;
Expand Down Expand Up @@ -1717,7 +1717,7 @@ unicode_dealloc(PyObject *unicode)
// Successfully popped.
assert(popped == unicode);
// Only our `popped` reference should be left; remove it too.
assert(Py_REFCNT(unicode) == 1);
assert(_PyObject_IsUniquelyReferenced(unicode));
Py_SET_REFCNT(unicode, 0);
#ifdef Py_REF_DEBUG
/* let's be pedantic with the ref total */
Expand Down
3 changes: 2 additions & 1 deletion Python/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "pycore_code.h" // _PyCode_New()
#include "pycore_hashtable.h" // _Py_hashtable_t
#include "pycore_long.h" // _PyLong_IsZero()
#include "pycore_object.h" // _PyObject_IsUniquelyReferenced
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_setobject.h" // _PySet_NextEntryRef()
#include "pycore_unicodeobject.h" // _PyUnicode_InternImmortal()
Expand Down Expand Up @@ -388,7 +389,7 @@ w_ref(PyObject *v, char *flag, WFILE *p)
* But we use TYPE_REF always for interned string, to PYC file stable
* as possible.
*/
if (Py_REFCNT(v) == 1 &&
if (_PyObject_IsUniquelyReferenced(v) &&
!(PyUnicode_CheckExact(v) && PyUnicode_CHECK_INTERNED(v))) {
return 0;
}
Expand Down
Loading