[Python-checkins] bpo-39542: Simplify _Py_NewReference() (GH-18332)

Victor Stinner webhook-mailer at python.org
Mon Feb 3 11:55:09 EST 2020


https://github.com/python/cpython/commit/49932fec62c616ec88da52642339d83ae719e924
commit: 49932fec62c616ec88da52642339d83ae719e924
branch: master
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2020-02-03T17:55:04+01:00
summary:

bpo-39542: Simplify _Py_NewReference() (GH-18332)

* Remove _Py_INC_REFTOTAL and _Py_DEC_REFTOTAL macros: modify
  directly _Py_RefTotal.
* _Py_ForgetReference() is no longer defined if the Py_TRACE_REFS
  macro is not defined.
* Remove _Py_NewReference() implementation from object.c:
  unify the two implementations in object.h inline function.
* Fix Py_TRACE_REFS build: _Py_INC_TPALLOCS() macro has been removed.

files:
M Include/object.h
M Modules/_testcapimodule.c
M Objects/bytesobject.c
M Objects/dictobject.c
M Objects/object.c
M Objects/tupleobject.c
M Objects/unicodeobject.c

diff --git a/Include/object.h b/Include/object.h
index e1cc47aeb3d5c..175a208f0d2d7 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -379,25 +379,11 @@ decision that's up to the implementer of each new type so if you want,
 you can count such references to the type object.)
 */
 
-/* First define a pile of simple helper macros, one set per special
- * build symbol.  These either expand to the obvious things, or to
- * nothing at all when the special mode isn't in effect.  The main
- * macros can later be defined just once then, yet expand to different
- * things depending on which special build options are and aren't in effect.
- * Trust me <wink>:  while painful, this is 20x easier to understand than,
- * e.g, defining _Py_NewReference five different times in a maze of nested
- * #ifdefs (we used to do that -- it was impenetrable).
- */
 #ifdef Py_REF_DEBUG
 PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
 PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno,
                                       PyObject *op);
 PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void);
-#define _Py_INC_REFTOTAL        _Py_RefTotal++
-#define _Py_DEC_REFTOTAL        _Py_RefTotal--
-#else
-#define _Py_INC_REFTOTAL
-#define _Py_DEC_REFTOTAL
 #endif /* Py_REF_DEBUG */
 
 /* Update the Python traceback of an object. This function must be called
@@ -406,33 +392,33 @@ PyAPI_FUNC(int) _PyTraceMalloc_NewReference(PyObject *op);
 
 #ifdef Py_TRACE_REFS
 /* Py_TRACE_REFS is such major surgery that we call external routines. */
-PyAPI_FUNC(void) _Py_NewReference(PyObject *);
 PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
 PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force);
-#else
-/* Without Py_TRACE_REFS, there's little enough to do that we expand code
-   inline. */
+#endif
+
+
 static inline void _Py_NewReference(PyObject *op)
 {
     if (_Py_tracemalloc_config.tracing) {
         _PyTraceMalloc_NewReference(op);
     }
-    _Py_INC_REFTOTAL;
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal++;
+#endif
     Py_REFCNT(op) = 1;
+#ifdef Py_TRACE_REFS
+    _Py_AddToAllObjects(op, 1);
+#endif
 }
 
-static inline void _Py_ForgetReference(PyObject *Py_UNUSED(op))
-{
-    /* nothing to do */
-}
-#endif /* !Py_TRACE_REFS */
-
 
 PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
 
 static inline void _Py_INCREF(PyObject *op)
 {
-    _Py_INC_REFTOTAL;
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal++;
+#endif
     op->ob_refcnt++;
 }
 
@@ -444,7 +430,9 @@ static inline void _Py_DECREF(
 #endif
     PyObject *op)
 {
-    _Py_DEC_REFTOTAL;
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal--;
+#endif
     if (--op->ob_refcnt != 0) {
 #ifdef Py_REF_DEBUG
         if (op->ob_refcnt < 0) {
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 4dcfde4543730..c5812f827dfeb 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -3586,9 +3586,11 @@ slot_tp_del(PyObject *self)
         self->ob_refcnt = refcnt;
     }
     assert(!PyType_IS_GC(Py_TYPE(self)) || _PyObject_GC_IS_TRACKED(self));
-    /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
-     * we need to undo that. */
-    _Py_DEC_REFTOTAL;
+    /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
+       _Py_RefTotal, so we need to undo that. */
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal--;
+#endif
 }
 
 static PyObject *
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index 00151b8256615..5334eca7f33e6 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -2948,8 +2948,12 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
         return (*pv == NULL) ? -1 : 0;
     }
     /* XXX UNREF/NEWREF interface should be more symmetrical */
-    _Py_DEC_REFTOTAL;
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal--;
+#endif
+#ifdef Py_TRACE_REFS
     _Py_ForgetReference(v);
+#endif
     *pv = (PyObject *)
         PyObject_REALLOC(v, PyBytesObject_SIZE + newsize);
     if (*pv == NULL) {
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 87f88abbe53bd..ae6b50ff27245 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -311,7 +311,9 @@ static void free_keys_object(PyDictKeysObject *keys);
 static inline void
 dictkeys_incref(PyDictKeysObject *dk)
 {
-    _Py_INC_REFTOTAL;
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal++;
+#endif
     dk->dk_refcnt++;
 }
 
@@ -319,7 +321,9 @@ static inline void
 dictkeys_decref(PyDictKeysObject *dk)
 {
     assert(dk->dk_refcnt > 0);
-    _Py_DEC_REFTOTAL;
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal--;
+#endif
     if (--dk->dk_refcnt == 0) {
         free_keys_object(dk);
     }
@@ -563,7 +567,9 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size)
             return NULL;
         }
     }
-    _Py_INC_REFTOTAL;
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal++;
+#endif
     dk->dk_refcnt = 1;
     dk->dk_size = size;
     dk->dk_usable = usable;
@@ -687,10 +693,12 @@ clone_combined_dict(PyDictObject *orig)
     }
 
     /* Since we copied the keys table we now have an extra reference
-       in the system.  Manually call _Py_INC_REFTOTAL to signal that
+       in the system.  Manually call increment _Py_RefTotal to signal that
        we have it now; calling dictkeys_incref would be an error as
        keys->dk_refcnt is already set to 1 (after memcpy). */
-    _Py_INC_REFTOTAL;
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal++;
+#endif
 
     return (PyObject *)new;
 }
@@ -1249,13 +1257,15 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize)
 
         assert(oldkeys->dk_lookup != lookdict_split);
         assert(oldkeys->dk_refcnt == 1);
+#ifdef Py_REF_DEBUG
+        _Py_RefTotal--;
+#endif
         if (oldkeys->dk_size == PyDict_MINSIZE &&
-            numfreekeys < PyDict_MAXFREELIST) {
-            _Py_DEC_REFTOTAL;
+            numfreekeys < PyDict_MAXFREELIST)
+        {
             keys_free_list[numfreekeys++] = oldkeys;
         }
         else {
-            _Py_DEC_REFTOTAL;
             PyObject_FREE(oldkeys);
         }
     }
diff --git a/Objects/object.c b/Objects/object.c
index 2154d119a0206..085605ae36714 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -232,9 +232,11 @@ PyObject_CallFinalizerFromDealloc(PyObject *self)
     _PyObject_ASSERT(self,
                      (!PyType_IS_GC(Py_TYPE(self))
                       || _PyObject_GC_IS_TRACKED(self)));
-    /* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
-     * we need to undo that. */
-    _Py_DEC_REFTOTAL;
+    /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
+       _Py_RefTotal, so we need to undo that. */
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal--;
+#endif
     return -1;
 }
 
@@ -1804,19 +1806,6 @@ _PyTypes_Init(void)
 
 
 #ifdef Py_TRACE_REFS
-
-void
-_Py_NewReference(PyObject *op)
-{
-    if (_Py_tracemalloc_config.tracing) {
-        _PyTraceMalloc_NewReference(op);
-    }
-    _Py_INC_REFTOTAL;
-    op->ob_refcnt = 1;
-    _Py_AddToAllObjects(op, 1);
-    _Py_INC_TPALLOCS(op);
-}
-
 void
 _Py_ForgetReference(PyObject *op)
 {
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 2708b9aad3120..8c8c66f266f9d 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -902,10 +902,15 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
     }
 
     /* XXX UNREF/NEWREF interface should be more symmetrical */
-    _Py_DEC_REFTOTAL;
-    if (_PyObject_GC_IS_TRACKED(v))
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal--;
+#endif
+    if (_PyObject_GC_IS_TRACKED(v)) {
         _PyObject_GC_UNTRACK(v);
+    }
+#ifdef Py_TRACE_REFS
     _Py_ForgetReference((PyObject *) v);
+#endif
     /* DECREF items deleted by shrinkage */
     for (i = newsize; i < oldsize; i++) {
         Py_CLEAR(v->ob_item[i]);
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 8e1161e5387b4..5f10437a1524c 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -1037,8 +1037,12 @@ resize_compact(PyObject *unicode, Py_ssize_t length)
         _PyUnicode_UTF8(unicode) = NULL;
         _PyUnicode_UTF8_LENGTH(unicode) = 0;
     }
-    _Py_DEC_REFTOTAL;
+#ifdef Py_REF_DEBUG
+    _Py_RefTotal--;
+#endif
+#ifdef Py_TRACE_REFS
     _Py_ForgetReference(unicode);
+#endif
 
     new_unicode = (PyObject *)PyObject_REALLOC(unicode, new_size);
     if (new_unicode == NULL) {



More information about the Python-checkins mailing list