@@ -74,23 +74,30 @@ _Py_AddToAllObjects(PyObject *op, int force)
7474
7575#ifdef COUNT_ALLOCS
7676static PyTypeObject * type_list ;
77+ /* All types are added to type_list, atleast when
78+ they get one object created. That makes them
79+ immortal, which unfortunately contributes to
80+ garbage itself. If unlist_types_without_objects
81+ is set, they will be removed from the type_list
82+ once the last object is deallocated. */
83+ int unlist_types_without_objects ;
7784extern int tuple_zero_allocs , fast_tuple_allocs ;
7885extern int quick_int_allocs , quick_neg_int_allocs ;
7986extern int null_strings , one_strings ;
8087void
81- dump_counts (void )
88+ dump_counts (FILE * f )
8289{
8390 PyTypeObject * tp ;
8491
8592 for (tp = type_list ; tp ; tp = tp -> tp_next )
86- fprintf (stderr , "%s alloc'd: %d, freed: %d, max in use: %d\n" ,
93+ fprintf (f , "%s alloc'd: %d, freed: %d, max in use: %d\n" ,
8794 tp -> tp_name , tp -> tp_allocs , tp -> tp_frees ,
8895 tp -> tp_maxalloc );
89- fprintf (stderr , "fast tuple allocs: %d, empty: %d\n" ,
96+ fprintf (f , "fast tuple allocs: %d, empty: %d\n" ,
9097 fast_tuple_allocs , tuple_zero_allocs );
91- fprintf (stderr , "fast int allocs: pos: %d, neg: %d\n" ,
98+ fprintf (f , "fast int allocs: pos: %d, neg: %d\n" ,
9299 quick_int_allocs , quick_neg_int_allocs );
93- fprintf (stderr , "null strings: %d, 1-strings: %d\n" ,
100+ fprintf (f , "null strings: %d, 1-strings: %d\n" ,
94101 null_strings , one_strings );
95102}
96103
@@ -124,10 +131,12 @@ get_counts(void)
124131void
125132inc_count (PyTypeObject * tp )
126133{
127- if (tp -> tp_allocs == 0 ) {
134+ if (tp -> tp_next == NULL && tp -> tp_prev == NULL ) {
128135 /* first time; insert in linked list */
129136 if (tp -> tp_next != NULL ) /* sanity check */
130137 Py_FatalError ("XXX inc_count sanity check" );
138+ if (type_list )
139+ type_list -> tp_prev = tp ;
131140 tp -> tp_next = type_list ;
132141 /* Note that as of Python 2.2, heap-allocated type objects
133142 * can go away, but this code requires that they stay alive
@@ -150,6 +159,24 @@ inc_count(PyTypeObject *tp)
150159 if (tp -> tp_allocs - tp -> tp_frees > tp -> tp_maxalloc )
151160 tp -> tp_maxalloc = tp -> tp_allocs - tp -> tp_frees ;
152161}
162+
163+ void dec_count (PyTypeObject * tp )
164+ {
165+ tp -> tp_frees ++ ;
166+ if (unlist_types_without_objects &&
167+ tp -> tp_allocs == tp -> tp_frees ) {
168+ /* unlink the type from type_list */
169+ if (tp -> tp_prev )
170+ tp -> tp_prev -> tp_next = tp -> tp_next ;
171+ else
172+ type_list = tp -> tp_next ;
173+ if (tp -> tp_next )
174+ tp -> tp_next -> tp_prev = tp -> tp_prev ;
175+ tp -> tp_next = tp -> tp_prev = NULL ;
176+ Py_DECREF (tp );
177+ }
178+ }
179+
153180#endif
154181
155182#ifdef Py_REF_DEBUG
0 commit comments