@@ -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+ */
12041232void
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