mirror of
https://github.com/python/cpython.git
synced 2025-11-27 05:44:16 +00:00
_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
1 changed files with 41 additions and 5 deletions
|
|
@ -908,6 +908,31 @@ write4(void *p, ulong n)
|
||||||
q[3] = (uchar)( n & 0xff);
|
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,
|
/* The debug malloc asks for 16 extra bytes and fills them with useful stuff,
|
||||||
here calling the underlying malloc's result p:
|
here calling the underlying malloc's result p:
|
||||||
|
|
||||||
|
|
@ -1200,7 +1225,10 @@ printone(const char* msg, ulong value)
|
||||||
return origvalue;
|
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
|
void
|
||||||
_PyObject_DebugMallocStats(void)
|
_PyObject_DebugMallocStats(void)
|
||||||
{
|
{
|
||||||
|
|
@ -1262,15 +1290,23 @@ _PyObject_DebugMallocStats(void)
|
||||||
/* visit every pool in the arena */
|
/* visit every pool in the arena */
|
||||||
for (j = 0; j < poolsinarena; ++j, base += POOL_SIZE) {
|
for (j = 0; j < poolsinarena; ++j, base += POOL_SIZE) {
|
||||||
poolp p = (poolp)base;
|
poolp p = (poolp)base;
|
||||||
|
const uint sz = p->szidx;
|
||||||
|
uint freeblocks;
|
||||||
|
|
||||||
if (p->ref.count == 0) {
|
if (p->ref.count == 0) {
|
||||||
/* currently unused */
|
/* currently unused */
|
||||||
++numfreepools;
|
++numfreepools;
|
||||||
|
assert(pool_is_in_list(p, freepools));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
++numpools[p->szidx];
|
++numpools[sz];
|
||||||
numblocks[p->szidx] += p->ref.count;
|
numblocks[sz] += p->ref.count;
|
||||||
numfreeblocks[p->szidx] += NUMBLOCKS(p->szidx) -
|
freeblocks = NUMBLOCKS(sz) - p->ref.count;
|
||||||
p->ref.count;
|
numfreeblocks[sz] += freeblocks;
|
||||||
|
#ifdef Py_DEBUG
|
||||||
|
if (freeblocks > 0)
|
||||||
|
assert(pool_is_in_list(p, usedpools[sz + sz]));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue