Index: docs/reference/gobject/tmpl/gtype.sgml
===================================================================
RCS file: /cvs/gnome/glib/docs/reference/gobject/tmpl/gtype.sgml,v
retrieving revision 1.52
diff -p -u -r1.52 gtype.sgml
--- docs/reference/gobject/tmpl/gtype.sgml	9 Aug 2006 21:32:11 -0000	1.52
+++ docs/reference/gobject/tmpl/gtype.sgml	4 Sep 2006 12:31:43 -0000
@@ -628,13 +628,14 @@ The <type>GTypeDebugFlags</type> enumera
 g_type_init_with_debug_flags() to trigger debugging messages during runtime.
 Note that the messages can also be triggered by setting the
 <envar>GOBJECT_DEBUG</envar> environment variable to a ':'-separated list of 
-"objects" and "signals".
+"objects", "signals" and "types".
 
 </para>
 
 @G_TYPE_DEBUG_NONE: Print no messages.
 @G_TYPE_DEBUG_OBJECTS: Print messages about object bookkeeping.
 @G_TYPE_DEBUG_SIGNALS: Print messages about signal emissions.
+@G_TYPE_DEBUG_TYPES: Print messages about type bookkeeping.
 @G_TYPE_DEBUG_MASK: Mask covering all debug flags.
 
 <!-- ##### FUNCTION g_type_init_with_debug_flags ##### -->
Index: gobject/gtype.c
===================================================================
RCS file: /cvs/gnome/glib/gobject/gtype.c,v
retrieving revision 1.88
diff -p -u -r1.88 gtype.c
--- gobject/gtype.c	15 Jun 2006 19:18:51 -0000	1.88
+++ gobject/gtype.c	4 Sep 2006 12:31:44 -0000
@@ -306,6 +306,50 @@ static GQuark          static_quark_ifac
 static GQuark          static_quark_dependants_array = 0;
 GTypeDebugFlags	       _g_type_debug_flags = 0;
 
+#ifdef G_ENABLE_DEBUG
+#define IF_DEBUG(debug_type)    if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type)
+G_LOCK_DEFINE_STATIC (debug_types);
+static GTree *debug_types_tree = NULL;
+
+typedef struct {
+  guint num_created;
+  guint num_destroyed;
+  guint max_population;
+} DebugTypeStats;
+
+static gint
+debug_types_compare (gconstpointer a, gconstpointer b)
+{
+  return strcmp (g_type_name (GPOINTER_TO_SIZE (a)),
+                 g_type_name (GPOINTER_TO_SIZE (b)));
+}
+
+static gboolean
+debug_types_foreach (gpointer key,
+                     gpointer value,
+                     gpointer user_data)
+{
+  GType type = GPOINTER_TO_SIZE (key);
+  DebugTypeStats *stats = value;
+
+  g_message ("%s (%u created / %u destroyed), max population=%u",
+             g_type_name (type), stats->num_created, stats->num_destroyed,
+             stats->max_population);
+  return FALSE;
+}
+
+static void
+debug_types_atexit (void)
+{
+  IF_DEBUG (TYPES)
+    {
+      G_LOCK (debug_types);
+      g_tree_foreach (debug_types_tree, debug_types_foreach, NULL);
+      G_UNLOCK (debug_types);
+    }
+}
+#endif /* G_ENABLE_DEBUG */
+
 
 /* --- type nodes --- */
 static GHashTable       *static_type_nodes_ht = NULL;
@@ -1565,6 +1609,30 @@ g_type_create_instance (GType type)
   instance->g_class = class;
   if (node->data->instance.instance_init)
     node->data->instance.instance_init (instance, class);
+
+#ifdef G_ENABLE_DEBUG
+  IF_DEBUG (TYPES)
+    {
+      DebugTypeStats *stats;
+      gpointer key = GSIZE_TO_POINTER (type);
+
+      G_LOCK (debug_types);
+      stats = g_tree_lookup (debug_types_tree, key);
+      if (stats)
+        {
+          guint cur_population;
+          cur_population = ++stats->num_created - stats->num_destroyed;
+          stats->max_population = MAX (cur_population, stats->max_population);
+        }
+      else
+        {
+          stats = g_new0 (DebugTypeStats, 1);
+          stats->max_population = stats->num_created = 1;
+          g_tree_insert (debug_types_tree, key, stats);
+        }
+      G_UNLOCK (debug_types);
+    }
+#endif
   
   return instance;
 }
@@ -1596,6 +1664,18 @@ g_type_free_instance (GTypeInstance *ins
   instance->g_class = NULL;
 #ifdef G_ENABLE_DEBUG  
   memset (instance, 0xaa, type_total_instance_size_I (node));
+
+  IF_DEBUG (TYPES)
+    {
+      DebugTypeStats *stats;
+      gpointer key = GSIZE_TO_POINTER (class->g_type);
+
+      G_LOCK (debug_types);
+      stats = g_tree_lookup (debug_types_tree, key);
+      if (stats)
+        stats->num_destroyed++;
+      G_UNLOCK (debug_types);
+    }
 #endif
   g_slice_free1 (type_total_instance_size_I (node), instance);
 
@@ -3390,6 +3470,7 @@ g_type_init_with_debug_flags (GTypeDebug
       static GDebugKey debug_keys[] = {
 	{ "objects", G_TYPE_DEBUG_OBJECTS },
 	{ "signals", G_TYPE_DEBUG_SIGNALS },
+	{ "types",   G_TYPE_DEBUG_TYPES }
       };
       
       _g_type_debug_flags |= g_parse_debug_string (env_string,
@@ -3463,6 +3544,14 @@ g_type_init_with_debug_flags (GTypeDebug
   /* Signal system
    */
   g_signal_init ();
+
+#ifdef G_ENABLE_DEBUG
+  IF_DEBUG (TYPES)
+    {
+      debug_types_tree = g_tree_new (debug_types_compare);
+      g_atexit (debug_types_atexit);
+    }
+#endif
   
   G_UNLOCK (type_init_lock);
 }
Index: gobject/gtype.h
===================================================================
RCS file: /cvs/gnome/glib/gobject/gtype.h,v
retrieving revision 1.67
diff -p -u -r1.67 gtype.h
--- gobject/gtype.h	16 May 2006 12:02:29 -0000	1.67
+++ gobject/gtype.h	4 Sep 2006 12:31:45 -0000
@@ -159,7 +159,8 @@ typedef enum	/*< skip >*/
   G_TYPE_DEBUG_NONE	= 0,
   G_TYPE_DEBUG_OBJECTS	= 1 << 0,
   G_TYPE_DEBUG_SIGNALS	= 1 << 1,
-  G_TYPE_DEBUG_MASK	= 0x03
+  G_TYPE_DEBUG_TYPES	= 1 << 2,
+  G_TYPE_DEBUG_MASK	= 0x07
 } GTypeDebugFlags;
 
 
