@@ -1026,7 +1026,11 @@ _PyMalloc_DebugRealloc(void *p, size_t nbytes)
10261026 return fresh ;
10271027}
10281028
1029- void
1029+ /* Check the forbidden bytes on both ends of the memory allocated for p.
1030+ * If anything is wrong, print info to stderr via _PyMalloc_DebugDumpAddress,
1031+ * and call Py_FatalError to kill the program.
1032+ */
1033+ void
10301034_PyMalloc_DebugCheckAddress (const void * p )
10311035{
10321036 const uchar * q = (const uchar * )p ;
@@ -1063,6 +1067,7 @@ _PyMalloc_DebugCheckAddress(const void *p)
10631067 Py_FatalError (msg );
10641068}
10651069
1070+ /* Display info to stderr about the memory block at p. */
10661071void
10671072_PyMalloc_DebugDumpAddress (const void * p )
10681073{
@@ -1149,4 +1154,95 @@ _PyMalloc_DebugDumpAddress(const void *p)
11491154 }
11501155}
11511156
1157+ /* Print summary info to stderr about the state of pymalloc's structures. */
1158+ void
1159+ _PyMalloc_DebugDumpStats (void )
1160+ {
1161+ uint i ;
1162+ const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT ;
1163+ uint numfreepools = 0 ;
1164+ /* # of pools per class index */
1165+ ulong numpools [SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT ];
1166+ /* # of allocated blocks per class index */
1167+ ulong numblocks [SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT ];
1168+ /* # of free blocks per class index */
1169+ ulong numfreeblocks [SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT ];
1170+ ulong grandtotal ; /* total # of allocated bytes */
1171+ ulong freegrandtotal ; /* total # of available bytes in used blocks */
1172+
1173+ fprintf (stderr , "%u arenas * %d bytes/arena = %lu total bytes.\n" ,
1174+ narenas , ARENA_SIZE , narenas * (ulong )ARENA_SIZE );
1175+ fprintf (stderr , "Small block threshold = %d, in %u size classes.\n" ,
1176+ SMALL_REQUEST_THRESHOLD , numclasses );
1177+ fprintf (stderr , "pymalloc malloc+realloc called %lu times.\n" ,
1178+ serialno );
1179+
1180+ for (i = 0 ; i < numclasses ; ++ i )
1181+ numpools [i ] = numblocks [i ] = numfreeblocks [i ] = 0 ;
1182+
1183+ /* Because empty pools aren't linked to from anything, it's easiest
1184+ * to march over all the arenas.
1185+ */
1186+ for (i = 0 ; i < narenas ; ++ i ) {
1187+ uint poolsinarena ;
1188+ uint j ;
1189+ uptr base = arenas [i ];
1190+
1191+ /* round up to pool alignment */
1192+ poolsinarena = ARENA_SIZE / POOL_SIZE ;
1193+ if (base & (uptr )POOL_SIZE_MASK ) {
1194+ -- poolsinarena ;
1195+ base &= ~(uptr )POOL_SIZE_MASK ;
1196+ base += POOL_SIZE ;
1197+ }
1198+
1199+ if (i == narenas - 1 ) {
1200+ /* current arena may have raw memory at the end */
1201+ numfreepools += nfreepools ;
1202+ poolsinarena -= nfreepools ;
1203+ }
1204+
1205+ /* visit every pool in the arena */
1206+ for (j = 0 ; j < poolsinarena ; ++ j , base += POOL_SIZE ) {
1207+ poolp p = (poolp )base ;
1208+ if (p -> ref .count == 0 ) {
1209+ /* currently unused */
1210+ ++ numfreepools ;
1211+ continue ;
1212+ }
1213+ ++ numpools [p -> szidx ];
1214+ numblocks [p -> szidx ] += p -> ref .count ;
1215+ numfreeblocks [p -> szidx ] += p -> capacity - p -> ref .count ;
1216+ }
1217+ }
1218+
1219+ fputc ('\n' , stderr );
1220+ fprintf (stderr , "Number of unused pools: %u\n" , numfreepools );
1221+ fputc ('\n' , stderr );
1222+ fputs ("class num bytes num pools blocks in use avail blocks\n"
1223+ "----- --------- --------- ------------- ------------\n" ,
1224+ stderr );
1225+
1226+ grandtotal = freegrandtotal = 0 ;
1227+ for (i = 0 ; i < numclasses ; ++ i ) {
1228+ ulong p = numpools [i ];
1229+ ulong b = numblocks [i ];
1230+ ulong f = numfreeblocks [i ];
1231+ uint size = (i + 1 ) << ALIGNMENT_SHIFT ;
1232+ if (p == 0 ) {
1233+ assert (b == 0 && f == 0 );
1234+ continue ;
1235+ }
1236+ fprintf (stderr , "%5u %11u %11lu %15lu %13lu\n" ,
1237+ i , size , p , b , f );
1238+ grandtotal += b * size ;
1239+ freegrandtotal += f * size ;
1240+ }
1241+ fputc ('\n' , stderr );
1242+ fprintf (stderr , "Total bytes in allocated blocks: %lu\n" ,
1243+ grandtotal );
1244+ fprintf (stderr , "Total free bytes in used pools: %lu\n" ,
1245+ freegrandtotal );
1246+ }
1247+
11521248#endif /* PYMALLOC_DEBUG */
0 commit comments