Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 08d8215

Browse files
committed
_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.
1 parent 64d80c9 commit 08d8215

1 file changed

Lines changed: 41 additions & 5 deletions

File tree

Objects/obmalloc.c

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,31 @@ write4(void *p, ulong n)
908908
q[3] = (uchar)( n & 0xff);
909909
}
910910

911+
#ifdef Py_DEBUG
912+
/* Is target in the list? The list is traversed via the nextpool pointers.
913+
* The list may be NULL-terminated, or circular. Return 1 if target is in
914+
* list, else 0.
915+
*/
916+
static int
917+
pool_is_in_list(const poolp target, poolp list)
918+
{
919+
poolp origlist = list;
920+
assert(target != NULL);
921+
if (list == NULL)
922+
return 0;
923+
do {
924+
if (target == list)
925+
return 1;
926+
list = list->nextpool;
927+
} while (list != NULL && list != origlist);
928+
return 0;
929+
}
930+
931+
#else
932+
#define pool_is_in_list(X, Y) 1
933+
934+
#endif /* Py_DEBUG */
935+
911936
/* The debug malloc asks for 16 extra bytes and fills them with useful stuff,
912937
here calling the underlying malloc's result p:
913938
@@ -1200,7 +1225,10 @@ printone(const char* msg, ulong value)
12001225
return origvalue;
12011226
}
12021227

1203-
/* Print summary info to stderr about the state of pymalloc's structures. */
1228+
/* Print summary info to stderr about the state of pymalloc's structures.
1229+
* In Py_DEBUG mode, also perform some expensive internal consistency
1230+
* checks.
1231+
*/
12041232
void
12051233
_PyObject_DebugMallocStats(void)
12061234
{
@@ -1262,15 +1290,23 @@ _PyObject_DebugMallocStats(void)
12621290
/* visit every pool in the arena */
12631291
for (j = 0; j < poolsinarena; ++j, base += POOL_SIZE) {
12641292
poolp p = (poolp)base;
1293+
const uint sz = p->szidx;
1294+
uint freeblocks;
1295+
12651296
if (p->ref.count == 0) {
12661297
/* currently unused */
12671298
++numfreepools;
1299+
assert(pool_is_in_list(p, freepools));
12681300
continue;
12691301
}
1270-
++numpools[p->szidx];
1271-
numblocks[p->szidx] += p->ref.count;
1272-
numfreeblocks[p->szidx] += NUMBLOCKS(p->szidx) -
1273-
p->ref.count;
1302+
++numpools[sz];
1303+
numblocks[sz] += p->ref.count;
1304+
freeblocks = NUMBLOCKS(sz) - p->ref.count;
1305+
numfreeblocks[sz] += freeblocks;
1306+
#ifdef Py_DEBUG
1307+
if (freeblocks > 0)
1308+
assert(pool_is_in_list(p, usedpools[sz + sz]));
1309+
#endif
12741310
}
12751311
}
12761312

0 commit comments

Comments
 (0)