+++ /dev/null
-diff -up Python-2.7.2/Include/dictobject.h.add-debug-malloc-stats Python-2.7.2/Include/dictobject.h
---- Python-2.7.2/Include/dictobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/dictobject.h 2011-09-16 19:03:25.105821625 -0400
-@@ -150,6 +150,8 @@ PyAPI_FUNC(PyObject *) PyDict_GetItemStr
- PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item);
- PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key);
-
-+PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out);
-+
- #ifdef __cplusplus
- }
- #endif
-diff -up Python-2.7.2/Include/floatobject.h.add-debug-malloc-stats Python-2.7.2/Include/floatobject.h
---- Python-2.7.2/Include/floatobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/floatobject.h 2011-09-16 19:03:25.106821625 -0400
-@@ -132,6 +132,7 @@ PyAPI_FUNC(PyObject *) _PyFloat_FormatAd
- failure. Used in builtin_round in bltinmodule.c. */
- PyAPI_FUNC(PyObject *) _Py_double_round(double x, int ndigits);
-
-+PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out);
-
-
- #ifdef __cplusplus
-diff -up Python-2.7.2/Include/frameobject.h.add-debug-malloc-stats Python-2.7.2/Include/frameobject.h
---- Python-2.7.2/Include/frameobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/frameobject.h 2011-09-16 19:03:25.107821625 -0400
-@@ -80,6 +80,8 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(Py
-
- PyAPI_FUNC(int) PyFrame_ClearFreeList(void);
-
-+PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out);
-+
- /* Return the line of code the frame is currently executing. */
- PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *);
-
-diff -up Python-2.7.2/Include/intobject.h.add-debug-malloc-stats Python-2.7.2/Include/intobject.h
---- Python-2.7.2/Include/intobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/intobject.h 2011-09-16 19:03:25.107821625 -0400
-@@ -74,6 +74,8 @@ PyAPI_FUNC(PyObject *) _PyInt_FormatAdva
- char *format_spec,
- Py_ssize_t format_spec_len);
-
-+PyAPI_FUNC(void) _PyInt_DebugMallocStats(FILE *out);
-+
- #ifdef __cplusplus
- }
- #endif
-diff -up Python-2.7.2/Include/listobject.h.add-debug-malloc-stats Python-2.7.2/Include/listobject.h
---- Python-2.7.2/Include/listobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/listobject.h 2011-09-16 19:03:25.107821625 -0400
-@@ -62,6 +62,8 @@ PyAPI_FUNC(PyObject *) _PyList_Extend(Py
- #define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v))
- #define PyList_GET_SIZE(op) Py_SIZE(op)
-
-+PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out);
-+
- #ifdef __cplusplus
- }
- #endif
-diff -up Python-2.7.2/Include/methodobject.h.add-debug-malloc-stats Python-2.7.2/Include/methodobject.h
---- Python-2.7.2/Include/methodobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/methodobject.h 2011-09-16 19:03:25.108821625 -0400
-@@ -87,6 +87,10 @@ typedef struct {
-
- PyAPI_FUNC(int) PyCFunction_ClearFreeList(void);
-
-+PyAPI_FUNC(void) _PyCFunction_DebugMallocStats(FILE *out);
-+PyAPI_FUNC(void) _PyMethod_DebugMallocStats(FILE *out);
-+
-+
- #ifdef __cplusplus
- }
- #endif
-diff -up Python-2.7.2/Include/object.h.add-debug-malloc-stats Python-2.7.2/Include/object.h
---- Python-2.7.2/Include/object.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/object.h 2011-09-16 19:03:25.108821625 -0400
-@@ -980,6 +980,13 @@ PyAPI_DATA(PyObject *) _PyTrash_delete_l
- _PyTrash_thread_deposit_object((PyObject*)op); \
- } while (0);
-
-+PyAPI_FUNC(void)
-+_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks,
-+ size_t sizeof_block);
-+
-+PyAPI_FUNC(void)
-+_PyObject_DebugTypeStats(FILE *out);
-+
- #ifdef __cplusplus
- }
- #endif
-diff -up Python-2.7.2/Include/objimpl.h.add-debug-malloc-stats Python-2.7.2/Include/objimpl.h
---- Python-2.7.2/Include/objimpl.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/objimpl.h 2011-09-16 19:03:25.108821625 -0400
-@@ -101,13 +101,13 @@ PyAPI_FUNC(void) PyObject_Free(void *);
-
- /* Macros */
- #ifdef WITH_PYMALLOC
-+PyAPI_FUNC(void) _PyObject_DebugMallocStats(FILE *out);
- #ifdef PYMALLOC_DEBUG /* WITH_PYMALLOC && PYMALLOC_DEBUG */
- PyAPI_FUNC(void *) _PyObject_DebugMalloc(size_t nbytes);
- PyAPI_FUNC(void *) _PyObject_DebugRealloc(void *p, size_t nbytes);
- PyAPI_FUNC(void) _PyObject_DebugFree(void *p);
- PyAPI_FUNC(void) _PyObject_DebugDumpAddress(const void *p);
- PyAPI_FUNC(void) _PyObject_DebugCheckAddress(const void *p);
--PyAPI_FUNC(void) _PyObject_DebugMallocStats(void);
- PyAPI_FUNC(void *) _PyObject_DebugMallocApi(char api, size_t nbytes);
- PyAPI_FUNC(void *) _PyObject_DebugReallocApi(char api, void *p, size_t nbytes);
- PyAPI_FUNC(void) _PyObject_DebugFreeApi(char api, void *p);
-diff -up Python-2.7.2/Include/stringobject.h.add-debug-malloc-stats Python-2.7.2/Include/stringobject.h
---- Python-2.7.2/Include/stringobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/stringobject.h 2011-09-16 19:03:25.109821625 -0400
-@@ -204,6 +204,8 @@ PyAPI_FUNC(PyObject *) _PyBytes_FormatAd
- char *format_spec,
- Py_ssize_t format_spec_len);
-
-+PyAPI_FUNC(void) _PyString_DebugMallocStats(FILE *out);
-+
- #ifdef __cplusplus
- }
- #endif
-diff -up Python-2.7.2/Include/unicodeobject.h.add-debug-malloc-stats Python-2.7.2/Include/unicodeobject.h
---- Python-2.7.2/Include/unicodeobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
-+++ Python-2.7.2/Include/unicodeobject.h 2011-09-16 19:03:25.109821625 -0400
-@@ -1406,6 +1406,8 @@ PyAPI_FUNC(int) _PyUnicode_IsAlpha(
- Py_UNICODE ch /* Unicode character */
- );
-
-+PyAPI_FUNC(void) _PyUnicode_DebugMallocStats(FILE *out);
-+
- #ifdef __cplusplus
- }
- #endif
-diff -up Python-2.7.2/Lib/test/test_sys.py.add-debug-malloc-stats Python-2.7.2/Lib/test/test_sys.py
---- Python-2.7.2/Lib/test/test_sys.py.add-debug-malloc-stats 2011-09-16 19:03:25.048821626 -0400
-+++ Python-2.7.2/Lib/test/test_sys.py 2011-09-16 19:03:25.110821625 -0400
-@@ -473,6 +473,32 @@ class SysModuleTest(unittest.TestCase):
- p.wait()
- self.assertIn(executable, ["''", repr(sys.executable)])
-
-+ def test_debugmallocstats(self):
-+ # Test sys._debugmallocstats()
-+
-+ import subprocess
-+
-+ # Verify the default of writing to stderr:
-+ p = subprocess.Popen([sys.executable,
-+ '-c', 'import sys; sys._debugmallocstats()'],
-+ stderr=subprocess.PIPE)
-+ out, err = p.communicate()
-+ p.wait()
-+ self.assertIn("arenas allocated current", err)
-+
-+ # Verify that we can redirect the output to a file (not a file-like
-+ # object, though):
-+ with open('mallocstats.txt', 'w') as out:
-+ sys._debugmallocstats(out)
-+ result = open('mallocstats.txt').read()
-+ self.assertIn("arenas allocated current", result)
-+ os.unlink('mallocstats.txt')
-+
-+ # Verify that the destination must be a file:
-+ with self.assertRaises(TypeError):
-+ sys._debugmallocstats(42)
-+
-+
- @test.test_support.cpython_only
- class SizeofTest(unittest.TestCase):
-
-diff -up Python-2.7.2/Objects/classobject.c.add-debug-malloc-stats Python-2.7.2/Objects/classobject.c
---- Python-2.7.2/Objects/classobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/classobject.c 2011-09-16 19:03:25.110821625 -0400
-@@ -2670,3 +2670,12 @@ PyMethod_Fini(void)
- {
- (void)PyMethod_ClearFreeList();
- }
-+
-+/* Print summary info about the state of the optimized allocator */
-+void
-+_PyMethod_DebugMallocStats(FILE *out)
-+{
-+ _PyDebugAllocatorStats(out,
-+ "free PyMethodObject",
-+ numfree, sizeof(PyMethodObject));
-+}
-diff -up Python-2.7.2/Objects/dictobject.c.add-debug-malloc-stats Python-2.7.2/Objects/dictobject.c
---- Python-2.7.2/Objects/dictobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/dictobject.c 2011-09-16 19:03:25.111821625 -0400
-@@ -225,6 +225,15 @@ show_track(void)
- static PyDictObject *free_list[PyDict_MAXFREELIST];
- static int numfree = 0;
-
-+/* Print summary info about the state of the optimized allocator */
-+void
-+_PyDict_DebugMallocStats(FILE *out)
-+{
-+ _PyDebugAllocatorStats(out,
-+ "free PyDictObject", numfree, sizeof(PyDictObject));
-+}
-+
-+
- void
- PyDict_Fini(void)
- {
-diff -up Python-2.7.2/Objects/floatobject.c.add-debug-malloc-stats Python-2.7.2/Objects/floatobject.c
---- Python-2.7.2/Objects/floatobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/floatobject.c 2011-09-16 19:03:25.111821625 -0400
-@@ -35,6 +35,22 @@ typedef struct _floatblock PyFloatBlock;
- static PyFloatBlock *block_list = NULL;
- static PyFloatObject *free_list = NULL;
-
-+/* Print summary info about the state of the optimized allocator */
-+void
-+_PyFloat_DebugMallocStats(FILE *out)
-+{
-+ int num_blocks = 0;
-+ PyFloatBlock *block;
-+
-+ /* Walk the block list, counting */
-+ for (block = block_list; block ; block = block->next) {
-+ num_blocks++;
-+ }
-+
-+ _PyDebugAllocatorStats(out,
-+ "PyFloatBlock", num_blocks, sizeof(PyFloatBlock));
-+}
-+
- static PyFloatObject *
- fill_free_list(void)
- {
-diff -up Python-2.7.2/Objects/frameobject.c.add-debug-malloc-stats Python-2.7.2/Objects/frameobject.c
---- Python-2.7.2/Objects/frameobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/frameobject.c 2011-09-16 19:03:25.112821625 -0400
-@@ -980,3 +980,13 @@ PyFrame_Fini(void)
- Py_XDECREF(builtin_object);
- builtin_object = NULL;
- }
-+
-+/* Print summary info about the state of the optimized allocator */
-+void
-+_PyFrame_DebugMallocStats(FILE *out)
-+{
-+ _PyDebugAllocatorStats(out,
-+ "free PyFrameObject",
-+ numfree, sizeof(PyFrameObject));
-+}
-+
-diff -up Python-2.7.2/Objects/intobject.c.add-debug-malloc-stats Python-2.7.2/Objects/intobject.c
---- Python-2.7.2/Objects/intobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/intobject.c 2011-09-16 19:03:25.112821625 -0400
-@@ -44,6 +44,23 @@ typedef struct _intblock PyIntBlock;
- static PyIntBlock *block_list = NULL;
- static PyIntObject *free_list = NULL;
-
-+
-+/* Print summary info about the state of the optimized allocator */
-+void
-+_PyInt_DebugMallocStats(FILE *out)
-+{
-+ int num_blocks = 0;
-+ PyIntBlock *block;
-+
-+ /* Walk the block list, counting */
-+ for (block = block_list; block ; block = block->next) {
-+ num_blocks++;
-+ }
-+
-+ _PyDebugAllocatorStats(out,
-+ "PyIntBlock", num_blocks, sizeof(PyIntBlock));
-+}
-+
- static PyIntObject *
- fill_free_list(void)
- {
-diff -up Python-2.7.2/Objects/listobject.c.add-debug-malloc-stats Python-2.7.2/Objects/listobject.c
---- Python-2.7.2/Objects/listobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/listobject.c 2011-09-16 19:03:25.113821625 -0400
-@@ -109,6 +109,15 @@ PyList_Fini(void)
- }
- }
-
-+/* Print summary info about the state of the optimized allocator */
-+void
-+_PyList_DebugMallocStats(FILE *out)
-+{
-+ _PyDebugAllocatorStats(out,
-+ "free PyListObject",
-+ numfree, sizeof(PyListObject));
-+}
-+
- PyObject *
- PyList_New(Py_ssize_t size)
- {
-diff -up Python-2.7.2/Objects/methodobject.c.add-debug-malloc-stats Python-2.7.2/Objects/methodobject.c
---- Python-2.7.2/Objects/methodobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/methodobject.c 2011-09-16 19:03:25.113821625 -0400
-@@ -412,6 +412,15 @@ PyCFunction_Fini(void)
- (void)PyCFunction_ClearFreeList();
- }
-
-+/* Print summary info about the state of the optimized allocator */
-+void
-+_PyCFunction_DebugMallocStats(FILE *out)
-+{
-+ _PyDebugAllocatorStats(out,
-+ "free PyCFunction",
-+ numfree, sizeof(PyCFunction));
-+}
-+
- /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
- but it's part of the API so we need to keep a function around that
- existing C extensions can call.
-diff -up Python-2.7.2/Objects/object.c.add-debug-malloc-stats Python-2.7.2/Objects/object.c
---- Python-2.7.2/Objects/object.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/object.c 2011-09-16 19:04:46.463820849 -0400
-@@ -2334,6 +2334,23 @@ PyMem_Free(void *p)
- PyMem_FREE(p);
- }
-
-+void
-+_PyObject_DebugTypeStats(FILE *out)
-+{
-+ _PyString_DebugMallocStats(out);
-+ _PyCFunction_DebugMallocStats(out);
-+ _PyDict_DebugMallocStats(out);
-+ _PyFloat_DebugMallocStats(out);
-+ _PyFrame_DebugMallocStats(out);
-+ _PyInt_DebugMallocStats(out);
-+ _PyList_DebugMallocStats(out);
-+ _PyMethod_DebugMallocStats(out);
-+ _PySet_DebugMallocStats(out);
-+ _PyTuple_DebugMallocStats(out);
-+#if Py_USING_UNICODE
-+ _PyUnicode_DebugMallocStats(out);
-+#endif
-+}
-
- /* These methods are used to control infinite recursion in repr, str, print,
- etc. Container objects that may recursively contain themselves,
-diff -up Python-2.7.2/Objects/obmalloc.c.add-debug-malloc-stats Python-2.7.2/Objects/obmalloc.c
---- Python-2.7.2/Objects/obmalloc.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/obmalloc.c 2011-09-16 19:03:25.114821625 -0400
-@@ -508,12 +508,10 @@ static struct arena_object* usable_arena
- /* Number of arenas allocated that haven't been free()'d. */
- static size_t narenas_currently_allocated = 0;
-
--#ifdef PYMALLOC_DEBUG
- /* Total number of times malloc() called to allocate an arena. */
- static size_t ntimes_arena_allocated = 0;
- /* High water mark (max value ever seen) for narenas_currently_allocated. */
- static size_t narenas_highwater = 0;
--#endif
-
- /* Allocate a new arena. If we run out of memory, return NULL. Else
- * allocate a new arena, and return the address of an arena_object
-@@ -528,7 +526,7 @@ new_arena(void)
-
- #ifdef PYMALLOC_DEBUG
- if (Py_GETENV("PYTHONMALLOCSTATS"))
-- _PyObject_DebugMallocStats();
-+ _PyObject_DebugMallocStats(stderr);
- #endif
- if (unused_arena_objects == NULL) {
- uint i;
-@@ -588,11 +586,9 @@ new_arena(void)
- arenaobj->address = (uptr)address;
-
- ++narenas_currently_allocated;
--#ifdef PYMALLOC_DEBUG
- ++ntimes_arena_allocated;
- if (narenas_currently_allocated > narenas_highwater)
- narenas_highwater = narenas_currently_allocated;
--#endif
- arenaobj->freepools = NULL;
- /* pool_address <- first pool-aligned address in the arena
- nfreepools <- number of whole pools that fit after alignment */
-@@ -1694,17 +1690,19 @@ _PyObject_DebugDumpAddress(const void *p
- }
- }
-
-+#endif /* PYMALLOC_DEBUG */
-+
- static size_t
--printone(const char* msg, size_t value)
-+printone(FILE *out, const char* msg, size_t value)
- {
- int i, k;
- char buf[100];
- size_t origvalue = value;
-
-- fputs(msg, stderr);
-+ fputs(msg, out);
- for (i = (int)strlen(msg); i < 35; ++i)
-- fputc(' ', stderr);
-- fputc('=', stderr);
-+ fputc(' ', out);
-+ fputc('=', out);
-
- /* Write the value with commas. */
- i = 22;
-@@ -1725,17 +1723,32 @@ printone(const char* msg, size_t value)
-
- while (i >= 0)
- buf[i--] = ' ';
-- fputs(buf, stderr);
-+ fputs(buf, out);
-
- return origvalue;
- }
-
--/* Print summary info to stderr about the state of pymalloc's structures.
-+void
-+_PyDebugAllocatorStats(FILE *out,
-+ const char *block_name, int num_blocks, size_t sizeof_block)
-+{
-+ char buf1[128];
-+ char buf2[128];
-+ PyOS_snprintf(buf1, sizeof(buf1),
-+ "%d %ss * %zd bytes each",
-+ num_blocks, block_name, sizeof_block);
-+ PyOS_snprintf(buf2, sizeof(buf2),
-+ "%48s ", buf1);
-+ (void)printone(out, buf2, num_blocks * sizeof_block);
-+}
-+
-+
-+/* Print summary info to "out" about the state of pymalloc's structures.
- * In Py_DEBUG mode, also perform some expensive internal consistency
- * checks.
- */
- void
--_PyObject_DebugMallocStats(void)
-+_PyObject_DebugMallocStats(FILE *out)
- {
- uint i;
- const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT;
-@@ -1764,7 +1777,7 @@ _PyObject_DebugMallocStats(void)
- size_t total;
- char buf[128];
-
-- fprintf(stderr, "Small block threshold = %d, in %u size classes.\n",
-+ fprintf(out, "Small block threshold = %d, in %u size classes.\n",
- SMALL_REQUEST_THRESHOLD, numclasses);
-
- for (i = 0; i < numclasses; ++i)
-@@ -1818,10 +1831,10 @@ _PyObject_DebugMallocStats(void)
- }
- assert(narenas == narenas_currently_allocated);
-
-- fputc('\n', stderr);
-+ fputc('\n', out);
- fputs("class size num pools blocks in use avail blocks\n"
- "----- ---- --------- ------------- ------------\n",
-- stderr);
-+ out);
-
- for (i = 0; i < numclasses; ++i) {
- size_t p = numpools[i];
-@@ -1832,7 +1845,7 @@ _PyObject_DebugMallocStats(void)
- assert(b == 0 && f == 0);
- continue;
- }
-- fprintf(stderr, "%5u %6u "
-+ fprintf(out, "%5u %6u "
- "%11" PY_FORMAT_SIZE_T "u "
- "%15" PY_FORMAT_SIZE_T "u "
- "%13" PY_FORMAT_SIZE_T "u\n",
-@@ -1842,36 +1855,35 @@ _PyObject_DebugMallocStats(void)
- pool_header_bytes += p * POOL_OVERHEAD;
- quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size);
- }
-- fputc('\n', stderr);
-- (void)printone("# times object malloc called", serialno);
--
-- (void)printone("# arenas allocated total", ntimes_arena_allocated);
-- (void)printone("# arenas reclaimed", ntimes_arena_allocated - narenas);
-- (void)printone("# arenas highwater mark", narenas_highwater);
-- (void)printone("# arenas allocated current", narenas);
-+ fputc('\n', out);
-+#ifdef PYMALLOC_DEBUG
-+ (void)printone(out, "# times object malloc called", serialno);
-+#endif
-+ (void)printone(out, "# arenas allocated total", ntimes_arena_allocated);
-+ (void)printone(out, "# arenas reclaimed", ntimes_arena_allocated - narenas);
-+ (void)printone(out, "# arenas highwater mark", narenas_highwater);
-+ (void)printone(out, "# arenas allocated current", narenas);
-
- PyOS_snprintf(buf, sizeof(buf),
- "%" PY_FORMAT_SIZE_T "u arenas * %d bytes/arena",
- narenas, ARENA_SIZE);
-- (void)printone(buf, narenas * ARENA_SIZE);
-+ (void)printone(out, buf, narenas * ARENA_SIZE);
-
-- fputc('\n', stderr);
-+ fputc('\n', out);
-
-- total = printone("# bytes in allocated blocks", allocated_bytes);
-- total += printone("# bytes in available blocks", available_bytes);
-+ total = printone(out, "# bytes in allocated blocks", allocated_bytes);
-+ total += printone(out, "# bytes in available blocks", available_bytes);
-
- PyOS_snprintf(buf, sizeof(buf),
- "%u unused pools * %d bytes", numfreepools, POOL_SIZE);
-- total += printone(buf, (size_t)numfreepools * POOL_SIZE);
-+ total += printone(out, buf, (size_t)numfreepools * POOL_SIZE);
-
-- total += printone("# bytes lost to pool headers", pool_header_bytes);
-- total += printone("# bytes lost to quantization", quantization);
-- total += printone("# bytes lost to arena alignment", arena_alignment);
-- (void)printone("Total", total);
-+ total += printone(out, "# bytes lost to pool headers", pool_header_bytes);
-+ total += printone(out, "# bytes lost to quantization", quantization);
-+ total += printone(out, "# bytes lost to arena alignment", arena_alignment);
-+ (void)printone(out, "Total", total);
- }
-
--#endif /* PYMALLOC_DEBUG */
--
- #ifdef Py_USING_MEMORY_DEBUGGER
- /* Make this function last so gcc won't inline it since the definition is
- * after the reference.
-diff -up Python-2.7.2/Objects/setobject.c.add-debug-malloc-stats Python-2.7.2/Objects/setobject.c
---- Python-2.7.2/Objects/setobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/setobject.c 2011-09-16 19:03:25.115821625 -0400
-@@ -1088,6 +1088,16 @@ PySet_Fini(void)
- Py_CLEAR(emptyfrozenset);
- }
-
-+/* Print summary info about the state of the optimized allocator */
-+void
-+_PySet_DebugMallocStats(FILE *out)
-+{
-+ _PyDebugAllocatorStats(out,
-+ "free PySetObject",
-+ numfree, sizeof(PySetObject));
-+}
-+
-+
- static PyObject *
- set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
- {
-diff -up Python-2.7.2/Objects/stringobject.c.add-debug-malloc-stats Python-2.7.2/Objects/stringobject.c
---- Python-2.7.2/Objects/stringobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/stringobject.c 2011-09-16 19:03:25.116821625 -0400
-@@ -4822,3 +4822,43 @@ void _Py_ReleaseInternedStrings(void)
- PyDict_Clear(interned);
- Py_CLEAR(interned);
- }
-+
-+void _PyString_DebugMallocStats(FILE *out)
-+{
-+ ssize_t i;
-+ int num_immortal = 0, num_mortal = 0;
-+ ssize_t immortal_size = 0, mortal_size = 0;
-+
-+ if (interned == NULL || !PyDict_Check(interned))
-+ return;
-+
-+ for (i = 0; i <= ((PyDictObject*)interned)->ma_mask; i++) {
-+ PyDictEntry *ep = ((PyDictObject*)interned)->ma_table + i;
-+ PyObject *pvalue = ep->me_value;
-+ if (pvalue != NULL) {
-+ PyStringObject *s = (PyStringObject *)ep->me_key;
-+
-+ switch (s->ob_sstate) {
-+ case SSTATE_NOT_INTERNED:
-+ /* XXX Shouldn't happen */
-+ break;
-+ case SSTATE_INTERNED_IMMORTAL:
-+ num_immortal ++;
-+ immortal_size += s->ob_size;
-+ break;
-+ case SSTATE_INTERNED_MORTAL:
-+ num_mortal ++;
-+ mortal_size += s->ob_size;
-+ break;
-+ default:
-+ Py_FatalError("Inconsistent interned string state.");
-+ }
-+ }
-+ }
-+
-+ fprintf(out, "%d mortal interned strings\n", num_mortal);
-+ fprintf(out, "%d immortal interned strings\n", num_immortal);
-+ fprintf(out, "total size of all interned strings: "
-+ "%zi/%zi "
-+ "mortal/immortal\n", mortal_size, immortal_size);
-+}
-diff -up Python-2.7.2/Objects/tupleobject.c.add-debug-malloc-stats Python-2.7.2/Objects/tupleobject.c
---- Python-2.7.2/Objects/tupleobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/tupleobject.c 2011-09-16 19:03:25.116821625 -0400
-@@ -44,6 +44,22 @@ show_track(void)
- }
- #endif
-
-+/* Print summary info about the state of the optimized allocator */
-+void
-+_PyTuple_DebugMallocStats(FILE *out)
-+{
-+#if PyTuple_MAXSAVESIZE > 0
-+ int i;
-+ char buf[128];
-+ for (i = 1; i < PyTuple_MAXSAVESIZE; i++) {
-+ PyOS_snprintf(buf, sizeof(buf),
-+ "free %d-sized PyTupleObject", i);
-+ _PyDebugAllocatorStats(out,
-+ buf,
-+ numfree[i], _PyObject_VAR_SIZE(&PyTuple_Type, i));
-+ }
-+#endif
-+}
-
- PyObject *
- PyTuple_New(register Py_ssize_t size)
-diff -up Python-2.7.2/Objects/unicodeobject.c.add-debug-malloc-stats Python-2.7.2/Objects/unicodeobject.c
---- Python-2.7.2/Objects/unicodeobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
-+++ Python-2.7.2/Objects/unicodeobject.c 2011-09-16 19:03:25.118821625 -0400
-@@ -8883,6 +8883,12 @@ _PyUnicode_Fini(void)
- (void)PyUnicode_ClearFreeList();
- }
-
-+void _PyUnicode_DebugMallocStats(FILE *out)
-+{
-+ _PyDebugAllocatorStats(out, "free PyUnicodeObject", numfree,
-+ sizeof(PyUnicodeObject));
-+}
-+
- #ifdef __cplusplus
- }
- #endif
-diff -up Python-2.7.2/Python/pythonrun.c.add-debug-malloc-stats Python-2.7.2/Python/pythonrun.c
---- Python-2.7.2/Python/pythonrun.c.add-debug-malloc-stats 2011-09-16 19:03:25.025821626 -0400
-+++ Python-2.7.2/Python/pythonrun.c 2011-09-16 19:03:25.118821625 -0400
-@@ -549,7 +549,7 @@ Py_Finalize(void)
- #endif /* Py_TRACE_REFS */
- #ifdef PYMALLOC_DEBUG
- if (Py_GETENV("PYTHONMALLOCSTATS"))
-- _PyObject_DebugMallocStats();
-+ _PyObject_DebugMallocStats(stderr);
- #endif
-
- call_ll_exitfuncs();
-diff -up Python-2.7.2/Python/sysmodule.c.add-debug-malloc-stats Python-2.7.2/Python/sysmodule.c
---- Python-2.7.2/Python/sysmodule.c.add-debug-malloc-stats 2011-09-16 19:03:25.007821626 -0400
-+++ Python-2.7.2/Python/sysmodule.c 2011-09-16 19:03:25.119821625 -0400
-@@ -872,6 +872,57 @@ a 11-tuple where the entries in the tupl
- extern "C" {
- #endif
-
-+static PyObject *
-+sys_debugmallocstats(PyObject *self, PyObject *args)
-+{
-+ PyObject *file = NULL;
-+ FILE *fp;
-+
-+ if (!PyArg_ParseTuple(args, "|O!",
-+ &PyFile_Type, &file)) {
-+ return NULL;
-+ }
-+ if (!file) {
-+ /* Default to sys.stderr: */
-+ file = PySys_GetObject("stderr");
-+ if (!file) {
-+ PyErr_SetString(PyExc_ValueError, "sys.stderr not set");
-+ return NULL;
-+ }
-+ if (!PyFile_Check(file)) {
-+ PyErr_SetString(PyExc_TypeError, "sys.stderr is not a file");
-+ return NULL;
-+ }
-+ }
-+
-+ Py_INCREF(file);
-+ /* OK, we now own a ref on non-NULL "file" */
-+
-+ fp = PyFile_AsFile(file);
-+ if (!fp) {
-+ PyErr_SetString(PyExc_ValueError, "file is closed");
-+ Py_DECREF(file);
-+ return NULL;
-+ }
-+
-+ _PyObject_DebugMallocStats(fp);
-+ fputc('\n', fp);
-+ _PyObject_DebugTypeStats(fp);
-+
-+ Py_DECREF(file);
-+
-+ Py_RETURN_NONE;
-+}
-+PyDoc_STRVAR(debugmallocstats_doc,
-+"_debugmallocstats([file])\n\
-+\n\
-+Print summary info to the given file (or sys.stderr) about the state of\n\
-+pymalloc's structures.\n\
-+\n\
-+In Py_DEBUG mode, also perform some expensive internal consistency\n\
-+checks.\n\
-+");
-+
- #ifdef Py_TRACE_REFS
- /* Defined in objects.c because it uses static globals if that file */
- extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
-@@ -970,6 +1021,8 @@ static PyMethodDef sys_methods[] = {
- {"settrace", sys_settrace, METH_O, settrace_doc},
- {"gettrace", sys_gettrace, METH_NOARGS, gettrace_doc},
- {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc},
-+ {"_debugmallocstats", sys_debugmallocstats, METH_VARARGS,
-+ debugmallocstats_doc},
- {NULL, NULL} /* sentinel */
- };
-