From a93c51e3a8e15f1a486d11d5b55a64f3381babe0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 7 Feb 2020 00:38:59 +0100 Subject: [PATCH] bpo-39573: Use Py_REFCNT() macro (GH-18388) Replace direct acccess to PyObject.ob_refcnt with usage of the Py_REFCNT() macro. --- Modules/_functoolsmodule.c | 4 ++-- Modules/_testcapimodule.c | 16 +++++++++------- Objects/enumobject.c | 4 ++-- Objects/fileobject.c | 2 +- Objects/object.c | 36 ++++++++++++++++++------------------ Objects/tupleobject.c | 2 +- Objects/typeobject.c | 5 +++-- Objects/weakrefobject.c | 9 +++++---- Python/sysmodule.c | 2 +- 9 files changed, 42 insertions(+), 38 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 987087b1ac9..50d8c58e954 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -649,7 +649,7 @@ functools_reduce(PyObject *self, PyObject *args) for (;;) { PyObject *op2; - if (args->ob_refcnt > 1) { + if (Py_REFCNT(args) > 1) { Py_DECREF(args); if ((args = PyTuple_New(2)) == NULL) goto Fail; @@ -666,7 +666,7 @@ functools_reduce(PyObject *self, PyObject *args) result = op2; else { /* Update the args tuple in-place */ - assert(args->ob_refcnt == 1); + assert(Py_REFCNT(args) == 1); Py_XSETREF(_PyTuple_ITEMS(args)[0], result); Py_XSETREF(_PyTuple_ITEMS(args)[1], op2); if ((result = PyObject_Call(func, args, NULL)) == NULL) { diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index c5812f827df..27db86a70b9 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -3550,8 +3550,8 @@ slot_tp_del(PyObject *self) PyObject *error_type, *error_value, *error_traceback; /* Temporarily resurrect the object. */ - assert(self->ob_refcnt == 0); - self->ob_refcnt = 1; + assert(Py_REFCNT(self) == 0); + Py_REFCNT(self) = 1; /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); @@ -3573,17 +3573,19 @@ slot_tp_del(PyObject *self) /* Undo the temporary resurrection; can't use DECREF here, it would * cause a recursive call. */ - assert(self->ob_refcnt > 0); - if (--self->ob_refcnt == 0) - return; /* this is the normal path out */ + assert(Py_REFCNT(self) > 0); + if (--Py_REFCNT(self) == 0) { + /* this is the normal path out */ + return; + } /* __del__ resurrected it! Make it look like the original Py_DECREF * never happened. */ { - Py_ssize_t refcnt = self->ob_refcnt; + Py_ssize_t refcnt = Py_REFCNT(self); _Py_NewReference(self); - self->ob_refcnt = refcnt; + Py_REFCNT(self) = refcnt; } assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self)); /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased diff --git a/Objects/enumobject.c b/Objects/enumobject.c index 4786297c41a..75703be5fcf 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -122,7 +122,7 @@ enum_next_long(enumobject *en, PyObject* next_item) } en->en_longindex = stepped_up; - if (result->ob_refcnt == 1) { + if (Py_REFCNT(result) == 1) { Py_INCREF(result); old_index = PyTuple_GET_ITEM(result, 0); old_item = PyTuple_GET_ITEM(result, 1); @@ -167,7 +167,7 @@ enum_next(enumobject *en) } en->en_index++; - if (result->ob_refcnt == 1) { + if (Py_REFCNT(result) == 1) { Py_INCREF(result); old_index = PyTuple_GET_ITEM(result, 0); old_item = PyTuple_GET_ITEM(result, 1); diff --git a/Objects/fileobject.c b/Objects/fileobject.c index 527693c8099..c0eff8bed51 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -85,7 +85,7 @@ PyFile_GetLine(PyObject *f, int n) "EOF when reading a line"); } else if (s[len-1] == '\n') { - if (result->ob_refcnt == 1) + if (Py_REFCNT(result) == 1) _PyBytes_Resize(&result, len-1); else { PyObject *v; diff --git a/Objects/object.c b/Objects/object.c index 9eaa163bdfd..f9682fe5b1f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -58,7 +58,7 @@ _Py_GetRefTotal(void) Py_ssize_t total = _Py_RefTotal; o = _PySet_Dummy; if (o != NULL) - total -= o->ob_refcnt; + total -= Py_REFCNT(o); return total; } @@ -206,32 +206,32 @@ PyObject_CallFinalizer(PyObject *self) int PyObject_CallFinalizerFromDealloc(PyObject *self) { - if (self->ob_refcnt != 0) { + if (Py_REFCNT(self) != 0) { _PyObject_ASSERT_FAILED_MSG(self, "PyObject_CallFinalizerFromDealloc called " "on object with a non-zero refcount"); } /* Temporarily resurrect the object. */ - self->ob_refcnt = 1; + Py_REFCNT(self) = 1; PyObject_CallFinalizer(self); _PyObject_ASSERT_WITH_MSG(self, - self->ob_refcnt > 0, + Py_REFCNT(self) > 0, "refcount is too small"); /* Undo the temporary resurrection; can't use DECREF here, it would * cause a recursive call. */ - if (--self->ob_refcnt == 0) { + if (--Py_REFCNT(self) == 0) { return 0; /* this is the normal path out */ } /* tp_finalize resurrected it! Make it look like the original Py_DECREF * never happened. */ - Py_ssize_t refcnt = self->ob_refcnt; + Py_ssize_t refcnt = Py_REFCNT(self); _Py_NewReference(self); - self->ob_refcnt = refcnt; + Py_REFCNT(self) = refcnt; _PyObject_ASSERT(self, (!PyType_IS_GC(Py_TYPE(self)) @@ -263,12 +263,12 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) Py_END_ALLOW_THREADS } else { - if (op->ob_refcnt <= 0) { + if (Py_REFCNT(op) <= 0) { /* XXX(twouters) cast refcount to long until %zd is universally available */ Py_BEGIN_ALLOW_THREADS fprintf(fp, "", - (long)op->ob_refcnt, (void *)op); + (long)Py_REFCNT(op), (void *)op); Py_END_ALLOW_THREADS } else { @@ -363,7 +363,7 @@ _PyObject_Dump(PyObject* op) fprintf(stderr, "object address : %p\n", (void *)op); /* XXX(twouters) cast refcount to long until %zd is universally available */ - fprintf(stderr, "object refcount : %ld\n", (long)op->ob_refcnt); + fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op)); fflush(stderr); PyTypeObject *type = Py_TYPE(op); @@ -1010,7 +1010,7 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) return err; } Py_DECREF(name); - _PyObject_ASSERT(name, name->ob_refcnt >= 1); + _PyObject_ASSERT(name, Py_REFCNT(name) >= 1); if (tp->tp_getattr == NULL && tp->tp_getattro == NULL) PyErr_Format(PyExc_TypeError, "'%.100s' object has no attributes " @@ -1829,7 +1829,7 @@ _Py_NewReference(PyObject *op) void _Py_ForgetReference(PyObject *op) { - if (op->ob_refcnt < 0) { + if (Py_REFCNT(op) < 0) { _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt"); } @@ -1867,7 +1867,7 @@ _Py_PrintReferences(FILE *fp) PyObject *op; fprintf(fp, "Remaining objects:\n"); for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { - fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", (void *)op, op->ob_refcnt); + fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] ", (void *)op, Py_REFCNT(op)); if (PyObject_Print(op, fp, 0) != 0) PyErr_Clear(); putc('\n', fp); @@ -1884,7 +1884,7 @@ _Py_PrintReferenceAddresses(FILE *fp) fprintf(fp, "Remaining object addresses:\n"); for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", (void *)op, - op->ob_refcnt, Py_TYPE(op)->tp_name); + Py_REFCNT(op), Py_TYPE(op)->tp_name); } PyObject * @@ -2025,7 +2025,7 @@ _PyTrash_deposit_object(PyObject *op) _PyObject_ASSERT(op, PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); - _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyObject_ASSERT(op, Py_REFCNT(op) == 0); _PyGCHead_SET_PREV(_Py_AS_GC(op), gcstate->trash_delete_later); gcstate->trash_delete_later = op; } @@ -2037,7 +2037,7 @@ _PyTrash_thread_deposit_object(PyObject *op) PyThreadState *tstate = _PyThreadState_GET(); _PyObject_ASSERT(op, PyObject_IS_GC(op)); _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op)); - _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyObject_ASSERT(op, Py_REFCNT(op) == 0); _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later); tstate->trash_delete_later = op; } @@ -2064,7 +2064,7 @@ _PyTrash_destroy_chain(void) * assorted non-release builds calling Py_DECREF again ends * up distorting allocation statistics. */ - _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyObject_ASSERT(op, Py_REFCNT(op) == 0); ++gcstate->trash_delete_nesting; (*dealloc)(op); --gcstate->trash_delete_nesting; @@ -2102,7 +2102,7 @@ _PyTrash_thread_destroy_chain(void) * assorted non-release builds calling Py_DECREF again ends * up distorting allocation statistics. */ - _PyObject_ASSERT(op, op->ob_refcnt == 0); + _PyObject_ASSERT(op, Py_REFCNT(op) == 0); (*dealloc)(op); assert(tstate->trash_delete_nesting == 1); } diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 8c8c66f266f..d114bd64096 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -153,7 +153,7 @@ int PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) { PyObject **p; - if (!PyTuple_Check(op) || op->ob_refcnt != 1) { + if (!PyTuple_Check(op) || Py_REFCNT(op) != 1) { Py_XDECREF(newitem); PyErr_BadInternalCall(); return -1; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 01def837803..d85ff3ce569 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1173,8 +1173,9 @@ subtype_dealloc(PyObject *self) } if (type->tp_del) { type->tp_del(self); - if (self->ob_refcnt > 0) + if (Py_REFCNT(self) > 0) { return; + } } /* Find the nearest base with a different tp_dealloc */ @@ -1239,7 +1240,7 @@ subtype_dealloc(PyObject *self) if (type->tp_del) { _PyObject_GC_TRACK(self); type->tp_del(self); - if (self->ob_refcnt > 0) { + if (Py_REFCNT(self) > 0) { /* Resurrected */ goto endlabel; } diff --git a/Objects/weakrefobject.c b/Objects/weakrefobject.c index bf79e0c7ecb..d104b646f01 100644 --- a/Objects/weakrefobject.c +++ b/Objects/weakrefobject.c @@ -952,7 +952,8 @@ PyObject_ClearWeakRefs(PyObject *object) if (object == NULL || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)) - || object->ob_refcnt != 0) { + || Py_REFCNT(object) != 0) + { PyErr_BadInternalCall(); return; } @@ -975,8 +976,9 @@ PyObject_ClearWeakRefs(PyObject *object) current->wr_callback = NULL; clear_weakref(current); if (callback != NULL) { - if (((PyObject *)current)->ob_refcnt > 0) + if (Py_REFCNT((PyObject *)current) > 0) { handle_callback(current, callback); + } Py_DECREF(callback); } } @@ -993,8 +995,7 @@ PyObject_ClearWeakRefs(PyObject *object) for (i = 0; i < count; ++i) { PyWeakReference *next = current->wr_next; - if (((PyObject *)current)->ob_refcnt > 0) - { + if (Py_REFCNT((PyObject *)current) > 0) { Py_INCREF(current); PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 1cb10300d77..d8d18747454 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1656,7 +1656,7 @@ static Py_ssize_t sys_getrefcount_impl(PyObject *module, PyObject *object) /*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/ { - return object->ob_refcnt; + return Py_REFCNT(object); } #ifdef Py_REF_DEBUG