summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen W. Taylor <otaylor@fishsoup.net>2014-10-09 16:38:10 -0400
committerMatthias Clasen <mclasen@redhat.com>2014-10-11 13:54:29 -0400
commit011bf876e75c93c6b3fb9dd24d9458d881d4b36b (patch)
treed927c00c7f21f8cb0f4774b80450ff775dc4a6a1
parentaa401aef878eb0dc02e0c4523cadceaa714ac012 (diff)
downloadglib-011bf876e75c93c6b3fb9dd24d9458d881d4b36b.tar.gz
Add simple instance count facility
Add GOBJECT_DEBUG=instance-count which enables internal accounting of the number of instances of each GType, and g_type_get_instance_count() to retrieve the result. https://bugzilla.gnome.org/show_bug.cgi?id=354457
-rw-r--r--gobject/gtype.c51
-rw-r--r--gobject/gtype.h6
2 files changed, 55 insertions, 2 deletions
diff --git a/gobject/gtype.c b/gobject/gtype.c
index dff5b4ac6..a11ef27c4 100644
--- a/gobject/gtype.c
+++ b/gobject/gtype.c
@@ -33,6 +33,9 @@
#include "gconstructor.h"
+#ifdef G_ENABLE_DEBUG
+#define IF_DEBUG(debug_type) if (_g_type_debug_flags & G_TYPE_DEBUG_ ## debug_type)
+#endif
/**
* SECTION:gtype
@@ -223,6 +226,9 @@ typedef enum
struct _TypeNode
{
guint volatile ref_count;
+#ifdef G_ENABLE_DEBUG
+ guint volatile instance_count;
+#endif
GTypePlugin *plugin;
guint n_children; /* writable with lock */
guint n_supers : 8;
@@ -506,7 +512,6 @@ type_node_any_new_W (TypeNode *pnode,
node->data = NULL;
node->qname = g_quark_from_string (name);
node->global_gdata = NULL;
-
g_hash_table_insert (static_type_nodes_ht,
(gpointer) g_quark_to_string (node->qname),
(gpointer) type);
@@ -1864,6 +1869,13 @@ g_type_create_instance (GType type)
if (node->data->instance.instance_init)
node->data->instance.instance_init (instance, class);
+#ifdef G_ENABLE_DEBUG
+ IF_DEBUG (INSTANCE_COUNT)
+ {
+ g_atomic_int_inc ((int *) &node->instance_count);
+ }
+#endif
+
TRACE(GOBJECT_OBJECT_NEW(instance, type));
return instance;
@@ -1934,6 +1946,13 @@ g_type_free_instance (GTypeInstance *instance)
else
g_slice_free1 (private_size + ivar_size, allocated);
+#ifdef G_ENABLE_DEBUG
+ IF_DEBUG (INSTANCE_COUNT)
+ {
+ g_atomic_int_add ((int *) &node->instance_count, -1);
+ }
+#endif
+
g_type_class_unref (class);
}
@@ -3807,6 +3826,34 @@ g_type_query (GType type,
}
}
+/**
+ * g_type_get_instance_count:
+ * @type: a #GType
+ *
+ * Returns the number of instances allocated of the particular type;
+ * this is only available if GLib is built with debugging support and
+ * the instance_count debug flag is set (by setting the GOBJECT_DEBUG
+ * variable to include instance-count).
+ *
+ * Returns: the number of instances allocated of the given type;
+ * if instance counts are not available, returns 0.
+ *
+ * Since: 2.44
+ */
+int
+g_type_get_instance_count (GType type)
+{
+#ifdef G_ENABLE_DEBUG
+ TypeNode *node;
+
+ node = lookup_type_node_I (type);
+ g_return_if_fail (node != NULL);
+
+ return g_atomic_int_get (&node->instance_count);
+#else
+ return 0;
+#endif
+}
/* --- implementation details --- */
gboolean
@@ -4337,6 +4384,7 @@ gobject_init_ctor (void)
{
GDebugKey debug_keys[] = {
{ "objects", G_TYPE_DEBUG_OBJECTS },
+ { "instance-count", G_TYPE_DEBUG_INSTANCE_COUNT },
{ "signals", G_TYPE_DEBUG_SIGNALS },
};
@@ -4817,3 +4865,4 @@ g_type_ensure (GType type)
if (G_UNLIKELY (type == (GType)-1))
g_error ("can't happen");
}
+
diff --git a/gobject/gtype.h b/gobject/gtype.h
index 3db7f2eed..a7cecedcc 100644
--- a/gobject/gtype.h
+++ b/gobject/gtype.h
@@ -656,6 +656,7 @@ struct _GTypeQuery
* @G_TYPE_DEBUG_OBJECTS: Print messages about object bookkeeping
* @G_TYPE_DEBUG_SIGNALS: Print messages about signal emissions
* @G_TYPE_DEBUG_MASK: Mask covering all debug flags
+ * @G_TYPE_DEBUG_INSTANCE_COUNT: Keep a count of instances of each type
*
* These flags used to be passed to g_type_init_with_debug_flags() which
* is now deprecated.
@@ -670,7 +671,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_INSTANCE_COUNT = 1 << 2,
+ G_TYPE_DEBUG_MASK = 0x07
} GTypeDebugFlags;
@@ -738,6 +740,8 @@ GLIB_AVAILABLE_IN_ALL
void g_type_query (GType type,
GTypeQuery *query);
+GLIB_AVAILABLE_IN_2_44
+int g_type_get_instance_count (GType type);
/* --- type registration --- */
/**