mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-39573: Use Py_REFCNT() macro (GH-18388)
Replace direct acccess to PyObject.ob_refcnt with usage of the Py_REFCNT() macro.
This commit is contained in:
		
							parent
							
								
									446463f8db
								
							
						
					
					
						commit
						a93c51e3a8
					
				
					 9 changed files with 42 additions and 38 deletions
				
			
		|  | @ -649,7 +649,7 @@ functools_reduce(PyObject *self, PyObject *args) | ||||||
|     for (;;) { |     for (;;) { | ||||||
|         PyObject *op2; |         PyObject *op2; | ||||||
| 
 | 
 | ||||||
|         if (args->ob_refcnt > 1) { |         if (Py_REFCNT(args) > 1) { | ||||||
|             Py_DECREF(args); |             Py_DECREF(args); | ||||||
|             if ((args = PyTuple_New(2)) == NULL) |             if ((args = PyTuple_New(2)) == NULL) | ||||||
|                 goto Fail; |                 goto Fail; | ||||||
|  | @ -666,7 +666,7 @@ functools_reduce(PyObject *self, PyObject *args) | ||||||
|             result = op2; |             result = op2; | ||||||
|         else { |         else { | ||||||
|             /* Update the args tuple in-place */ |             /* 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)[0], result); | ||||||
|             Py_XSETREF(_PyTuple_ITEMS(args)[1], op2); |             Py_XSETREF(_PyTuple_ITEMS(args)[1], op2); | ||||||
|             if ((result = PyObject_Call(func, args, NULL)) == NULL) { |             if ((result = PyObject_Call(func, args, NULL)) == NULL) { | ||||||
|  |  | ||||||
|  | @ -3550,8 +3550,8 @@ slot_tp_del(PyObject *self) | ||||||
|     PyObject *error_type, *error_value, *error_traceback; |     PyObject *error_type, *error_value, *error_traceback; | ||||||
| 
 | 
 | ||||||
|     /* Temporarily resurrect the object. */ |     /* Temporarily resurrect the object. */ | ||||||
|     assert(self->ob_refcnt == 0); |     assert(Py_REFCNT(self) == 0); | ||||||
|     self->ob_refcnt = 1; |     Py_REFCNT(self) = 1; | ||||||
| 
 | 
 | ||||||
|     /* Save the current exception, if any. */ |     /* Save the current exception, if any. */ | ||||||
|     PyErr_Fetch(&error_type, &error_value, &error_traceback); |     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
 |     /* Undo the temporary resurrection; can't use DECREF here, it would
 | ||||||
|      * cause a recursive call. |      * cause a recursive call. | ||||||
|      */ |      */ | ||||||
|     assert(self->ob_refcnt > 0); |     assert(Py_REFCNT(self) > 0); | ||||||
|     if (--self->ob_refcnt == 0) |     if (--Py_REFCNT(self) == 0) { | ||||||
|         return;         /* this is the normal path out */ |         /* this is the normal path out */ | ||||||
|  |         return; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     /* __del__ resurrected it!  Make it look like the original Py_DECREF
 |     /* __del__ resurrected it!  Make it look like the original Py_DECREF
 | ||||||
|      * never happened. |      * never happened. | ||||||
|      */ |      */ | ||||||
|     { |     { | ||||||
|         Py_ssize_t refcnt = self->ob_refcnt; |         Py_ssize_t refcnt = Py_REFCNT(self); | ||||||
|         _Py_NewReference(self); |         _Py_NewReference(self); | ||||||
|         self->ob_refcnt = refcnt; |         Py_REFCNT(self) = refcnt; | ||||||
|     } |     } | ||||||
|     assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self)); |     assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self)); | ||||||
|     /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
 |     /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
 | ||||||
|  |  | ||||||
|  | @ -122,7 +122,7 @@ enum_next_long(enumobject *en, PyObject* next_item) | ||||||
|     } |     } | ||||||
|     en->en_longindex = stepped_up; |     en->en_longindex = stepped_up; | ||||||
| 
 | 
 | ||||||
|     if (result->ob_refcnt == 1) { |     if (Py_REFCNT(result) == 1) { | ||||||
|         Py_INCREF(result); |         Py_INCREF(result); | ||||||
|         old_index = PyTuple_GET_ITEM(result, 0); |         old_index = PyTuple_GET_ITEM(result, 0); | ||||||
|         old_item = PyTuple_GET_ITEM(result, 1); |         old_item = PyTuple_GET_ITEM(result, 1); | ||||||
|  | @ -167,7 +167,7 @@ enum_next(enumobject *en) | ||||||
|     } |     } | ||||||
|     en->en_index++; |     en->en_index++; | ||||||
| 
 | 
 | ||||||
|     if (result->ob_refcnt == 1) { |     if (Py_REFCNT(result) == 1) { | ||||||
|         Py_INCREF(result); |         Py_INCREF(result); | ||||||
|         old_index = PyTuple_GET_ITEM(result, 0); |         old_index = PyTuple_GET_ITEM(result, 0); | ||||||
|         old_item = PyTuple_GET_ITEM(result, 1); |         old_item = PyTuple_GET_ITEM(result, 1); | ||||||
|  |  | ||||||
|  | @ -85,7 +85,7 @@ PyFile_GetLine(PyObject *f, int n) | ||||||
|                             "EOF when reading a line"); |                             "EOF when reading a line"); | ||||||
|         } |         } | ||||||
|         else if (s[len-1] == '\n') { |         else if (s[len-1] == '\n') { | ||||||
|             if (result->ob_refcnt == 1) |             if (Py_REFCNT(result) == 1) | ||||||
|                 _PyBytes_Resize(&result, len-1); |                 _PyBytes_Resize(&result, len-1); | ||||||
|             else { |             else { | ||||||
|                 PyObject *v; |                 PyObject *v; | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ _Py_GetRefTotal(void) | ||||||
|     Py_ssize_t total = _Py_RefTotal; |     Py_ssize_t total = _Py_RefTotal; | ||||||
|     o = _PySet_Dummy; |     o = _PySet_Dummy; | ||||||
|     if (o != NULL) |     if (o != NULL) | ||||||
|         total -= o->ob_refcnt; |         total -= Py_REFCNT(o); | ||||||
|     return total; |     return total; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -206,32 +206,32 @@ PyObject_CallFinalizer(PyObject *self) | ||||||
| int | int | ||||||
| PyObject_CallFinalizerFromDealloc(PyObject *self) | PyObject_CallFinalizerFromDealloc(PyObject *self) | ||||||
| { | { | ||||||
|     if (self->ob_refcnt != 0) { |     if (Py_REFCNT(self) != 0) { | ||||||
|         _PyObject_ASSERT_FAILED_MSG(self, |         _PyObject_ASSERT_FAILED_MSG(self, | ||||||
|                                     "PyObject_CallFinalizerFromDealloc called " |                                     "PyObject_CallFinalizerFromDealloc called " | ||||||
|                                     "on object with a non-zero refcount"); |                                     "on object with a non-zero refcount"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /* Temporarily resurrect the object. */ |     /* Temporarily resurrect the object. */ | ||||||
|     self->ob_refcnt = 1; |     Py_REFCNT(self) = 1; | ||||||
| 
 | 
 | ||||||
|     PyObject_CallFinalizer(self); |     PyObject_CallFinalizer(self); | ||||||
| 
 | 
 | ||||||
|     _PyObject_ASSERT_WITH_MSG(self, |     _PyObject_ASSERT_WITH_MSG(self, | ||||||
|                               self->ob_refcnt > 0, |                               Py_REFCNT(self) > 0, | ||||||
|                               "refcount is too small"); |                               "refcount is too small"); | ||||||
| 
 | 
 | ||||||
|     /* Undo the temporary resurrection; can't use DECREF here, it would
 |     /* Undo the temporary resurrection; can't use DECREF here, it would
 | ||||||
|      * cause a recursive call. */ |      * cause a recursive call. */ | ||||||
|     if (--self->ob_refcnt == 0) { |     if (--Py_REFCNT(self) == 0) { | ||||||
|         return 0;         /* this is the normal path out */ |         return 0;         /* this is the normal path out */ | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /* tp_finalize resurrected it!  Make it look like the original Py_DECREF
 |     /* tp_finalize resurrected it!  Make it look like the original Py_DECREF
 | ||||||
|      * never happened. */ |      * never happened. */ | ||||||
|     Py_ssize_t refcnt = self->ob_refcnt; |     Py_ssize_t refcnt = Py_REFCNT(self); | ||||||
|     _Py_NewReference(self); |     _Py_NewReference(self); | ||||||
|     self->ob_refcnt = refcnt; |     Py_REFCNT(self) = refcnt; | ||||||
| 
 | 
 | ||||||
|     _PyObject_ASSERT(self, |     _PyObject_ASSERT(self, | ||||||
|                      (!PyType_IS_GC(Py_TYPE(self)) |                      (!PyType_IS_GC(Py_TYPE(self)) | ||||||
|  | @ -263,12 +263,12 @@ PyObject_Print(PyObject *op, FILE *fp, int flags) | ||||||
|         Py_END_ALLOW_THREADS |         Py_END_ALLOW_THREADS | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         if (op->ob_refcnt <= 0) { |         if (Py_REFCNT(op) <= 0) { | ||||||
|             /* XXX(twouters) cast refcount to long until %zd is
 |             /* XXX(twouters) cast refcount to long until %zd is
 | ||||||
|                universally available */ |                universally available */ | ||||||
|             Py_BEGIN_ALLOW_THREADS |             Py_BEGIN_ALLOW_THREADS | ||||||
|             fprintf(fp, "<refcnt %ld at %p>", |             fprintf(fp, "<refcnt %ld at %p>", | ||||||
|                 (long)op->ob_refcnt, (void *)op); |                 (long)Py_REFCNT(op), (void *)op); | ||||||
|             Py_END_ALLOW_THREADS |             Py_END_ALLOW_THREADS | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|  | @ -363,7 +363,7 @@ _PyObject_Dump(PyObject* op) | ||||||
|     fprintf(stderr, "object address  : %p\n", (void *)op); |     fprintf(stderr, "object address  : %p\n", (void *)op); | ||||||
|     /* XXX(twouters) cast refcount to long until %zd is
 |     /* XXX(twouters) cast refcount to long until %zd is
 | ||||||
|        universally available */ |        universally available */ | ||||||
|     fprintf(stderr, "object refcount : %ld\n", (long)op->ob_refcnt); |     fprintf(stderr, "object refcount : %ld\n", (long)Py_REFCNT(op)); | ||||||
|     fflush(stderr); |     fflush(stderr); | ||||||
| 
 | 
 | ||||||
|     PyTypeObject *type = Py_TYPE(op); |     PyTypeObject *type = Py_TYPE(op); | ||||||
|  | @ -1010,7 +1010,7 @@ PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) | ||||||
|         return err; |         return err; | ||||||
|     } |     } | ||||||
|     Py_DECREF(name); |     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) |     if (tp->tp_getattr == NULL && tp->tp_getattro == NULL) | ||||||
|         PyErr_Format(PyExc_TypeError, |         PyErr_Format(PyExc_TypeError, | ||||||
|                      "'%.100s' object has no attributes " |                      "'%.100s' object has no attributes " | ||||||
|  | @ -1829,7 +1829,7 @@ _Py_NewReference(PyObject *op) | ||||||
| void | void | ||||||
| _Py_ForgetReference(PyObject *op) | _Py_ForgetReference(PyObject *op) | ||||||
| { | { | ||||||
|     if (op->ob_refcnt < 0) { |     if (Py_REFCNT(op) < 0) { | ||||||
|         _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt"); |         _PyObject_ASSERT_FAILED_MSG(op, "negative refcnt"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -1867,7 +1867,7 @@ _Py_PrintReferences(FILE *fp) | ||||||
|     PyObject *op; |     PyObject *op; | ||||||
|     fprintf(fp, "Remaining objects:\n"); |     fprintf(fp, "Remaining objects:\n"); | ||||||
|     for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) { |     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) |         if (PyObject_Print(op, fp, 0) != 0) | ||||||
|             PyErr_Clear(); |             PyErr_Clear(); | ||||||
|         putc('\n', fp); |         putc('\n', fp); | ||||||
|  | @ -1884,7 +1884,7 @@ _Py_PrintReferenceAddresses(FILE *fp) | ||||||
|     fprintf(fp, "Remaining object addresses:\n"); |     fprintf(fp, "Remaining object addresses:\n"); | ||||||
|     for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) |     for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) | ||||||
|         fprintf(fp, "%p [%" PY_FORMAT_SIZE_T "d] %s\n", (void *)op, |         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 * | PyObject * | ||||||
|  | @ -2025,7 +2025,7 @@ _PyTrash_deposit_object(PyObject *op) | ||||||
| 
 | 
 | ||||||
|     _PyObject_ASSERT(op, PyObject_IS_GC(op)); |     _PyObject_ASSERT(op, PyObject_IS_GC(op)); | ||||||
|     _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(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); |     _PyGCHead_SET_PREV(_Py_AS_GC(op), gcstate->trash_delete_later); | ||||||
|     gcstate->trash_delete_later = op; |     gcstate->trash_delete_later = op; | ||||||
| } | } | ||||||
|  | @ -2037,7 +2037,7 @@ _PyTrash_thread_deposit_object(PyObject *op) | ||||||
|     PyThreadState *tstate = _PyThreadState_GET(); |     PyThreadState *tstate = _PyThreadState_GET(); | ||||||
|     _PyObject_ASSERT(op, PyObject_IS_GC(op)); |     _PyObject_ASSERT(op, PyObject_IS_GC(op)); | ||||||
|     _PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(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); |     _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later); | ||||||
|     tstate->trash_delete_later = op; |     tstate->trash_delete_later = op; | ||||||
| } | } | ||||||
|  | @ -2064,7 +2064,7 @@ _PyTrash_destroy_chain(void) | ||||||
|          * assorted non-release builds calling Py_DECREF again ends |          * assorted non-release builds calling Py_DECREF again ends | ||||||
|          * up distorting allocation statistics. |          * up distorting allocation statistics. | ||||||
|          */ |          */ | ||||||
|         _PyObject_ASSERT(op, op->ob_refcnt == 0); |         _PyObject_ASSERT(op, Py_REFCNT(op) == 0); | ||||||
|         ++gcstate->trash_delete_nesting; |         ++gcstate->trash_delete_nesting; | ||||||
|         (*dealloc)(op); |         (*dealloc)(op); | ||||||
|         --gcstate->trash_delete_nesting; |         --gcstate->trash_delete_nesting; | ||||||
|  | @ -2102,7 +2102,7 @@ _PyTrash_thread_destroy_chain(void) | ||||||
|          * assorted non-release builds calling Py_DECREF again ends |          * assorted non-release builds calling Py_DECREF again ends | ||||||
|          * up distorting allocation statistics. |          * up distorting allocation statistics. | ||||||
|          */ |          */ | ||||||
|         _PyObject_ASSERT(op, op->ob_refcnt == 0); |         _PyObject_ASSERT(op, Py_REFCNT(op) == 0); | ||||||
|         (*dealloc)(op); |         (*dealloc)(op); | ||||||
|         assert(tstate->trash_delete_nesting == 1); |         assert(tstate->trash_delete_nesting == 1); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -153,7 +153,7 @@ int | ||||||
| PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) | PyTuple_SetItem(PyObject *op, Py_ssize_t i, PyObject *newitem) | ||||||
| { | { | ||||||
|     PyObject **p; |     PyObject **p; | ||||||
|     if (!PyTuple_Check(op) || op->ob_refcnt != 1) { |     if (!PyTuple_Check(op) || Py_REFCNT(op) != 1) { | ||||||
|         Py_XDECREF(newitem); |         Py_XDECREF(newitem); | ||||||
|         PyErr_BadInternalCall(); |         PyErr_BadInternalCall(); | ||||||
|         return -1; |         return -1; | ||||||
|  |  | ||||||
|  | @ -1173,8 +1173,9 @@ subtype_dealloc(PyObject *self) | ||||||
|         } |         } | ||||||
|         if (type->tp_del) { |         if (type->tp_del) { | ||||||
|             type->tp_del(self); |             type->tp_del(self); | ||||||
|             if (self->ob_refcnt > 0) |             if (Py_REFCNT(self) > 0) { | ||||||
|                 return; |                 return; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* Find the nearest base with a different tp_dealloc */ |         /* Find the nearest base with a different tp_dealloc */ | ||||||
|  | @ -1239,7 +1240,7 @@ subtype_dealloc(PyObject *self) | ||||||
|     if (type->tp_del) { |     if (type->tp_del) { | ||||||
|         _PyObject_GC_TRACK(self); |         _PyObject_GC_TRACK(self); | ||||||
|         type->tp_del(self); |         type->tp_del(self); | ||||||
|         if (self->ob_refcnt > 0) { |         if (Py_REFCNT(self) > 0) { | ||||||
|             /* Resurrected */ |             /* Resurrected */ | ||||||
|             goto endlabel; |             goto endlabel; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -952,7 +952,8 @@ PyObject_ClearWeakRefs(PyObject *object) | ||||||
| 
 | 
 | ||||||
|     if (object == NULL |     if (object == NULL | ||||||
|         || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)) |         || !PyType_SUPPORTS_WEAKREFS(Py_TYPE(object)) | ||||||
|         || object->ob_refcnt != 0) { |         || Py_REFCNT(object) != 0) | ||||||
|  |     { | ||||||
|         PyErr_BadInternalCall(); |         PyErr_BadInternalCall(); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | @ -975,8 +976,9 @@ PyObject_ClearWeakRefs(PyObject *object) | ||||||
|             current->wr_callback = NULL; |             current->wr_callback = NULL; | ||||||
|             clear_weakref(current); |             clear_weakref(current); | ||||||
|             if (callback != NULL) { |             if (callback != NULL) { | ||||||
|                 if (((PyObject *)current)->ob_refcnt > 0) |                 if (Py_REFCNT((PyObject *)current) > 0) { | ||||||
|                     handle_callback(current, callback); |                     handle_callback(current, callback); | ||||||
|  |                 } | ||||||
|                 Py_DECREF(callback); |                 Py_DECREF(callback); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -993,8 +995,7 @@ PyObject_ClearWeakRefs(PyObject *object) | ||||||
|             for (i = 0; i < count; ++i) { |             for (i = 0; i < count; ++i) { | ||||||
|                 PyWeakReference *next = current->wr_next; |                 PyWeakReference *next = current->wr_next; | ||||||
| 
 | 
 | ||||||
|                 if (((PyObject *)current)->ob_refcnt > 0) |                 if (Py_REFCNT((PyObject *)current) > 0) { | ||||||
|                 { |  | ||||||
|                     Py_INCREF(current); |                     Py_INCREF(current); | ||||||
|                     PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); |                     PyTuple_SET_ITEM(tuple, i * 2, (PyObject *) current); | ||||||
|                     PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); |                     PyTuple_SET_ITEM(tuple, i * 2 + 1, current->wr_callback); | ||||||
|  |  | ||||||
|  | @ -1656,7 +1656,7 @@ static Py_ssize_t | ||||||
| sys_getrefcount_impl(PyObject *module, PyObject *object) | sys_getrefcount_impl(PyObject *module, PyObject *object) | ||||||
| /*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/ | /*[clinic end generated code: output=5fd477f2264b85b2 input=bf474efd50a21535]*/ | ||||||
| { | { | ||||||
|     return object->ob_refcnt; |     return Py_REFCNT(object); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #ifdef Py_REF_DEBUG | #ifdef Py_REF_DEBUG | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner