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.
This commit is contained in:
Victor Stinner 2020-02-03 17:55:05 +01:00 committed by GitHub
parent 24e5ad4689
commit 49932fec62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 58 deletions

View File

@ -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.) 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 #ifdef Py_REF_DEBUG
PyAPI_DATA(Py_ssize_t) _Py_RefTotal; PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno, PyAPI_FUNC(void) _Py_NegativeRefcount(const char *filename, int lineno,
PyObject *op); PyObject *op);
PyAPI_FUNC(Py_ssize_t) _Py_GetRefTotal(void); 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 */ #endif /* Py_REF_DEBUG */
/* Update the Python traceback of an object. This function must be called /* 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 #ifdef Py_TRACE_REFS
/* Py_TRACE_REFS is such major surgery that we call external routines. */ /* 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_ForgetReference(PyObject *);
PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force); PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force);
#else #endif
/* Without Py_TRACE_REFS, there's little enough to do that we expand code
inline. */
static inline void _Py_NewReference(PyObject *op) static inline void _Py_NewReference(PyObject *op)
{ {
if (_Py_tracemalloc_config.tracing) { if (_Py_tracemalloc_config.tracing) {
_PyTraceMalloc_NewReference(op); _PyTraceMalloc_NewReference(op);
} }
_Py_INC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal++;
#endif
Py_REFCNT(op) = 1; 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 *); PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
static inline void _Py_INCREF(PyObject *op) static inline void _Py_INCREF(PyObject *op)
{ {
_Py_INC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal++;
#endif
op->ob_refcnt++; op->ob_refcnt++;
} }
@ -444,7 +430,9 @@ static inline void _Py_DECREF(
#endif #endif
PyObject *op) PyObject *op)
{ {
_Py_DEC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal--;
#endif
if (--op->ob_refcnt != 0) { if (--op->ob_refcnt != 0) {
#ifdef Py_REF_DEBUG #ifdef Py_REF_DEBUG
if (op->ob_refcnt < 0) { if (op->ob_refcnt < 0) {

View File

@ -3586,9 +3586,11 @@ slot_tp_del(PyObject *self)
self->ob_refcnt = refcnt; self->ob_refcnt = 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, _Py_NewReference bumped _Py_RefTotal, so /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
* we need to undo that. */ _Py_RefTotal, so we need to undo that. */
_Py_DEC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal--;
#endif
} }
static PyObject * static PyObject *

View File

@ -2948,8 +2948,12 @@ _PyBytes_Resize(PyObject **pv, Py_ssize_t newsize)
return (*pv == NULL) ? -1 : 0; return (*pv == NULL) ? -1 : 0;
} }
/* XXX UNREF/NEWREF interface should be more symmetrical */ /* 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); _Py_ForgetReference(v);
#endif
*pv = (PyObject *) *pv = (PyObject *)
PyObject_REALLOC(v, PyBytesObject_SIZE + newsize); PyObject_REALLOC(v, PyBytesObject_SIZE + newsize);
if (*pv == NULL) { if (*pv == NULL) {

View File

@ -311,7 +311,9 @@ static void free_keys_object(PyDictKeysObject *keys);
static inline void static inline void
dictkeys_incref(PyDictKeysObject *dk) dictkeys_incref(PyDictKeysObject *dk)
{ {
_Py_INC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal++;
#endif
dk->dk_refcnt++; dk->dk_refcnt++;
} }
@ -319,7 +321,9 @@ static inline void
dictkeys_decref(PyDictKeysObject *dk) dictkeys_decref(PyDictKeysObject *dk)
{ {
assert(dk->dk_refcnt > 0); assert(dk->dk_refcnt > 0);
_Py_DEC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal--;
#endif
if (--dk->dk_refcnt == 0) { if (--dk->dk_refcnt == 0) {
free_keys_object(dk); free_keys_object(dk);
} }
@ -563,7 +567,9 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size)
return NULL; return NULL;
} }
} }
_Py_INC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal++;
#endif
dk->dk_refcnt = 1; dk->dk_refcnt = 1;
dk->dk_size = size; dk->dk_size = size;
dk->dk_usable = usable; 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 /* 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 we have it now; calling dictkeys_incref would be an error as
keys->dk_refcnt is already set to 1 (after memcpy). */ keys->dk_refcnt is already set to 1 (after memcpy). */
_Py_INC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal++;
#endif
return (PyObject *)new; return (PyObject *)new;
} }
@ -1249,13 +1257,15 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize)
assert(oldkeys->dk_lookup != lookdict_split); assert(oldkeys->dk_lookup != lookdict_split);
assert(oldkeys->dk_refcnt == 1); assert(oldkeys->dk_refcnt == 1);
#ifdef Py_REF_DEBUG
_Py_RefTotal--;
#endif
if (oldkeys->dk_size == PyDict_MINSIZE && if (oldkeys->dk_size == PyDict_MINSIZE &&
numfreekeys < PyDict_MAXFREELIST) { numfreekeys < PyDict_MAXFREELIST)
_Py_DEC_REFTOTAL; {
keys_free_list[numfreekeys++] = oldkeys; keys_free_list[numfreekeys++] = oldkeys;
} }
else { else {
_Py_DEC_REFTOTAL;
PyObject_FREE(oldkeys); PyObject_FREE(oldkeys);
} }
} }

View File

@ -232,9 +232,11 @@ PyObject_CallFinalizerFromDealloc(PyObject *self)
_PyObject_ASSERT(self, _PyObject_ASSERT(self,
(!PyType_IS_GC(Py_TYPE(self)) (!PyType_IS_GC(Py_TYPE(self))
|| _PyObject_GC_IS_TRACKED(self))); || _PyObject_GC_IS_TRACKED(self)));
/* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so /* If Py_REF_DEBUG macro is defined, _Py_NewReference() increased
* we need to undo that. */ _Py_RefTotal, so we need to undo that. */
_Py_DEC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal--;
#endif
return -1; return -1;
} }
@ -1804,19 +1806,6 @@ _PyTypes_Init(void)
#ifdef Py_TRACE_REFS #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 void
_Py_ForgetReference(PyObject *op) _Py_ForgetReference(PyObject *op)
{ {

View File

@ -902,10 +902,15 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize)
} }
/* XXX UNREF/NEWREF interface should be more symmetrical */ /* XXX UNREF/NEWREF interface should be more symmetrical */
_Py_DEC_REFTOTAL; #ifdef Py_REF_DEBUG
if (_PyObject_GC_IS_TRACKED(v)) _Py_RefTotal--;
#endif
if (_PyObject_GC_IS_TRACKED(v)) {
_PyObject_GC_UNTRACK(v); _PyObject_GC_UNTRACK(v);
}
#ifdef Py_TRACE_REFS
_Py_ForgetReference((PyObject *) v); _Py_ForgetReference((PyObject *) v);
#endif
/* DECREF items deleted by shrinkage */ /* DECREF items deleted by shrinkage */
for (i = newsize; i < oldsize; i++) { for (i = newsize; i < oldsize; i++) {
Py_CLEAR(v->ob_item[i]); Py_CLEAR(v->ob_item[i]);

View File

@ -1037,8 +1037,12 @@ resize_compact(PyObject *unicode, Py_ssize_t length)
_PyUnicode_UTF8(unicode) = NULL; _PyUnicode_UTF8(unicode) = NULL;
_PyUnicode_UTF8_LENGTH(unicode) = 0; _PyUnicode_UTF8_LENGTH(unicode) = 0;
} }
_Py_DEC_REFTOTAL; #ifdef Py_REF_DEBUG
_Py_RefTotal--;
#endif
#ifdef Py_TRACE_REFS
_Py_ForgetReference(unicode); _Py_ForgetReference(unicode);
#endif
new_unicode = (PyObject *)PyObject_REALLOC(unicode, new_size); new_unicode = (PyObject *)PyObject_REALLOC(unicode, new_size);
if (new_unicode == NULL) { if (new_unicode == NULL) {