diff options
author | Tim Peters <tim.peters@gmail.com> | 2002-04-18 22:25:03 (GMT) |
---|---|---|
committer | Tim Peters <tim.peters@gmail.com> | 2002-04-18 22:25:03 (GMT) |
commit | 08d821582faab8f3b6eeab1b1fd7520417b82b80 (patch) | |
tree | 6a3a04ff2da63cca2ab214b49855f586763c3119 /Objects/obmalloc.c | |
parent | 64d80c9f40465f9bed18712bc2b792f28dcac162 (diff) | |
download | cpython-08d821582faab8f3b6eeab1b1fd7520417b82b80.zip cpython-08d821582faab8f3b6eeab1b1fd7520417b82b80.tar.gz cpython-08d821582faab8f3b6eeab1b1fd7520417b82b80.tar.bz2 |
_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.
Diffstat (limited to 'Objects/obmalloc.c')
-rw-r--r-- | Objects/obmalloc.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 602b3c3..c39a823 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -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 } } |