mirror of https://github.com/python/cpython
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:
parent
24e5ad4689
commit
49932fec62
|
@ -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) {
|
||||||
|
|
|
@ -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 *
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue