mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
bpo-39489: Remove COUNT_ALLOCS special build (GH-18259)
Remove: * COUNT_ALLOCS macro * sys.getcounts() function * SHOW_ALLOC_COUNT code in listobject.c * SHOW_TRACK_COUNT code in tupleobject.c * PyConfig.show_alloc_count field * -X showalloccount command line option * @test.support.requires_type_collecting decorator
This commit is contained in:
parent
869c0c99b9
commit
c6e5c1123b
34 changed files with 24 additions and 469 deletions
126
Objects/object.c
126
Objects/object.c
|
@ -113,120 +113,6 @@ _Py_AddToAllObjects(PyObject *op, int force)
|
|||
}
|
||||
#endif /* Py_TRACE_REFS */
|
||||
|
||||
#ifdef COUNT_ALLOCS
|
||||
static PyTypeObject *type_list;
|
||||
/* All types are added to type_list, at least when
|
||||
they get one object created. That makes them
|
||||
immortal, which unfortunately contributes to
|
||||
garbage itself. If unlist_types_without_objects
|
||||
is set, they will be removed from the type_list
|
||||
once the last object is deallocated. */
|
||||
static int unlist_types_without_objects;
|
||||
extern Py_ssize_t _Py_tuple_zero_allocs, _Py_fast_tuple_allocs;
|
||||
extern Py_ssize_t _Py_quick_int_allocs, _Py_quick_neg_int_allocs;
|
||||
extern Py_ssize_t _Py_null_strings, _Py_one_strings;
|
||||
void
|
||||
_Py_dump_counts(FILE* f)
|
||||
{
|
||||
PyInterpreterState *interp = _PyInterpreterState_Get();
|
||||
if (!interp->config.show_alloc_count) {
|
||||
return;
|
||||
}
|
||||
|
||||
PyTypeObject *tp;
|
||||
for (tp = type_list; tp; tp = tp->tp_next)
|
||||
fprintf(f, "%s alloc'd: %" PY_FORMAT_SIZE_T "d, "
|
||||
"freed: %" PY_FORMAT_SIZE_T "d, "
|
||||
"max in use: %" PY_FORMAT_SIZE_T "d\n",
|
||||
tp->tp_name, tp->tp_allocs, tp->tp_frees,
|
||||
tp->tp_maxalloc);
|
||||
fprintf(f, "fast tuple allocs: %" PY_FORMAT_SIZE_T "d, "
|
||||
"empty: %" PY_FORMAT_SIZE_T "d\n",
|
||||
_Py_fast_tuple_allocs, _Py_tuple_zero_allocs);
|
||||
fprintf(f, "fast int allocs: pos: %" PY_FORMAT_SIZE_T "d, "
|
||||
"neg: %" PY_FORMAT_SIZE_T "d\n",
|
||||
_Py_quick_int_allocs, _Py_quick_neg_int_allocs);
|
||||
fprintf(f, "null strings: %" PY_FORMAT_SIZE_T "d, "
|
||||
"1-strings: %" PY_FORMAT_SIZE_T "d\n",
|
||||
_Py_null_strings, _Py_one_strings);
|
||||
}
|
||||
|
||||
PyObject *
|
||||
_Py_get_counts(void)
|
||||
{
|
||||
PyTypeObject *tp;
|
||||
PyObject *result;
|
||||
PyObject *v;
|
||||
|
||||
result = PyList_New(0);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
for (tp = type_list; tp; tp = tp->tp_next) {
|
||||
v = Py_BuildValue("(snnn)", tp->tp_name, tp->tp_allocs,
|
||||
tp->tp_frees, tp->tp_maxalloc);
|
||||
if (v == NULL) {
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
if (PyList_Append(result, v) < 0) {
|
||||
Py_DECREF(v);
|
||||
Py_DECREF(result);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(v);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
_Py_inc_count(PyTypeObject *tp)
|
||||
{
|
||||
if (tp->tp_next == NULL && tp->tp_prev == NULL) {
|
||||
/* first time; insert in linked list */
|
||||
if (type_list)
|
||||
type_list->tp_prev = tp;
|
||||
tp->tp_next = type_list;
|
||||
/* Note that as of Python 2.2, heap-allocated type objects
|
||||
* can go away, but this code requires that they stay alive
|
||||
* until program exit. That's why we're careful with
|
||||
* refcounts here. type_list gets a new reference to tp,
|
||||
* while ownership of the reference type_list used to hold
|
||||
* (if any) was transferred to tp->tp_next in the line above.
|
||||
* tp is thus effectively immortal after this.
|
||||
*/
|
||||
Py_INCREF(tp);
|
||||
type_list = tp;
|
||||
#ifdef Py_TRACE_REFS
|
||||
/* Also insert in the doubly-linked list of all objects,
|
||||
* if not already there.
|
||||
*/
|
||||
_Py_AddToAllObjects((PyObject *)tp, 0);
|
||||
#endif
|
||||
}
|
||||
tp->tp_allocs++;
|
||||
if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc)
|
||||
tp->tp_maxalloc = tp->tp_allocs - tp->tp_frees;
|
||||
}
|
||||
|
||||
void _Py_dec_count(PyTypeObject *tp)
|
||||
{
|
||||
tp->tp_frees++;
|
||||
if (unlist_types_without_objects &&
|
||||
tp->tp_allocs == tp->tp_frees) {
|
||||
/* unlink the type from type_list */
|
||||
if (tp->tp_prev)
|
||||
tp->tp_prev->tp_next = tp->tp_next;
|
||||
else
|
||||
type_list = tp->tp_next;
|
||||
if (tp->tp_next)
|
||||
tp->tp_next->tp_prev = tp->tp_prev;
|
||||
tp->tp_next = tp->tp_prev = NULL;
|
||||
Py_DECREF(tp);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef Py_REF_DEBUG
|
||||
/* Log a fatal error; doesn't return. */
|
||||
void
|
||||
|
@ -349,15 +235,6 @@ PyObject_CallFinalizerFromDealloc(PyObject *self)
|
|||
/* If Py_REF_DEBUG, _Py_NewReference bumped _Py_RefTotal, so
|
||||
* we need to undo that. */
|
||||
_Py_DEC_REFTOTAL;
|
||||
/* If Py_TRACE_REFS, _Py_NewReference re-added self to the object
|
||||
* chain, so no more to do there.
|
||||
* If COUNT_ALLOCS, the original decref bumped tp_frees, and
|
||||
* _Py_NewReference bumped tp_allocs: both of those need to be
|
||||
* undone. */
|
||||
#ifdef COUNT_ALLOCS
|
||||
--Py_TYPE(self)->tp_frees;
|
||||
--Py_TYPE(self)->tp_allocs;
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1970,7 +1847,6 @@ _Py_ForgetReference(PyObject *op)
|
|||
op->_ob_next->_ob_prev = op->_ob_prev;
|
||||
op->_ob_prev->_ob_next = op->_ob_next;
|
||||
op->_ob_next = op->_ob_prev = NULL;
|
||||
_Py_INC_TPFREES(op);
|
||||
}
|
||||
|
||||
/* Print all live objects. Because PyObject_Print is called, the
|
||||
|
@ -2289,8 +2165,6 @@ _Py_Dealloc(PyObject *op)
|
|||
destructor dealloc = Py_TYPE(op)->tp_dealloc;
|
||||
#ifdef Py_TRACE_REFS
|
||||
_Py_ForgetReference(op);
|
||||
#else
|
||||
_Py_INC_TPFREES(op);
|
||||
#endif
|
||||
(*dealloc)(op);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue