mirror of https://github.com/python/cpython
_PyObject_DebugMallocStats(): Added some potentially expensive internal
consistency checks, enabled only in a debug (Py_DEBUG) build. Note that this never gets called automatically unless PYMALLOC_DEBUG is #define'd too, and the envar PYTHONMALLOCSTATS exists.
This commit is contained in:
parent
64d80c9f40
commit
08d821582f
|
@ -908,6 +908,31 @@ write4(void *p, ulong n)
|
|||
q[3] = (uchar)( n & 0xff);
|
||||
}
|
||||
|
||||
#ifdef Py_DEBUG
|
||||
/* Is target in the list? The list is traversed via the nextpool pointers.
|
||||
* The list may be NULL-terminated, or circular. Return 1 if target is in
|
||||
* list, else 0.
|
||||
*/
|
||||
static int
|
||||
pool_is_in_list(const poolp target, poolp list)
|
||||
{
|
||||
poolp origlist = list;
|
||||
assert(target != NULL);
|
||||
if (list == NULL)
|
||||
return 0;
|
||||
do {
|
||||
if (target == list)
|
||||
return 1;
|
||||
list = list->nextpool;
|
||||
} while (list != NULL && list != origlist);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define pool_is_in_list(X, Y) 1
|
||||
|
||||
#endif /* Py_DEBUG */
|
||||
|
||||
/* The debug malloc asks for 16 extra bytes and fills them with useful stuff,
|
||||
here calling the underlying malloc's result p:
|
||||
|
||||
|
@ -1200,7 +1225,10 @@ printone(const char* msg, ulong value)
|
|||
return origvalue;
|
||||
}
|
||||
|
||||
/* Print summary info to stderr about the state of pymalloc's structures. */
|
||||
/* Print summary info to stderr about the state of pymalloc's structures.
|
||||
* In Py_DEBUG mode, also perform some expensive internal consistency
|
||||
* checks.
|
||||
*/
|
||||
void
|
||||
_PyObject_DebugMallocStats(void)
|
||||
{
|
||||
|
@ -1262,15 +1290,23 @@ _PyObject_DebugMallocStats(void)
|
|||
/* visit every pool in the arena */
|
||||
for (j = 0; j < poolsinarena; ++j, base += POOL_SIZE) {
|
||||
poolp p = (poolp)base;
|
||||
const uint sz = p->szidx;
|
||||
uint freeblocks;
|
||||
|
||||
if (p->ref.count == 0) {
|
||||
/* currently unused */
|
||||
++numfreepools;
|
||||
assert(pool_is_in_list(p, freepools));
|
||||
continue;
|
||||
}
|
||||
++numpools[p->szidx];
|
||||
numblocks[p->szidx] += p->ref.count;
|
||||
numfreeblocks[p->szidx] += NUMBLOCKS(p->szidx) -
|
||||
p->ref.count;
|
||||
++numpools[sz];
|
||||
numblocks[sz] += p->ref.count;
|
||||
freeblocks = NUMBLOCKS(sz) - p->ref.count;
|
||||
numfreeblocks[sz] += freeblocks;
|
||||
#ifdef Py_DEBUG
|
||||
if (freeblocks > 0)
|
||||
assert(pool_is_in_list(p, usedpools[sz + sz]));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue