#include "gtype-private.h"
#include "gtypeplugin.h"
#include "gvaluecollector.h"
-#include "gbsearcharray.h"
#include "gatomicarray.h"
#include "gobject_trace.h"
#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
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;
static GType static_fundamental_next = G_TYPE_RESERVED_USER_FIRST;
static inline TypeNode*
-lookup_type_node_I (register GType utype)
+lookup_type_node_I (GType utype)
{
if (utype > G_TYPE_FUNDAMENTAL_MAX)
return (TypeNode*) (utype & ~TYPE_ID_MASK);
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);
{
g_warning ("attempting to add an interface (%s) to class (%s) after class_init",
NODE_NAME (iface), NODE_NAME (node));
-
- /* See https://bugzilla.gnome.org/show_bug.cgi?id=697229,
- * https://bugzilla.gnome.org/show_bug.cgi?id=687659
- */
- if (!g_str_has_prefix (NODE_NAME (node), "gtkmm__CustomObject_") && !strstr (NODE_NAME (node), "_gtksharp_"))
- return FALSE;
+ return FALSE;
}
tnode = lookup_type_node_I (NODE_PARENT_TYPE (iface));
if (NODE_PARENT_TYPE (tnode) && !type_lookup_iface_entry_L (node, tnode))
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;
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);
}
{
TypeNode *node, *iface_node;
gboolean is_a;
+
+ if (type == iface_type)
+ return TRUE;
node = lookup_type_node_I (type);
iface_node = lookup_type_node_I (iface_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_val_if_fail (node != NULL, 0);
+
+ return g_atomic_int_get (&node->instance_count);
+#else
+ return 0;
+#endif
+}
/* --- implementation details --- */
gboolean
g_type_check_instance_is_fundamentally_a (GTypeInstance *type_instance,
GType fundamental_type)
{
+ TypeNode *node;
if (!type_instance || !type_instance->g_class)
return FALSE;
- return NODE_FUNDAMENTAL_TYPE(lookup_type_node_I (type_instance->g_class->g_type)) == fundamental_type;
+ node = lookup_type_node_I (type_instance->g_class->g_type);
+ return node && (NODE_FUNDAMENTAL_TYPE(node) == fundamental_type);
}
gboolean
{
GDebugKey debug_keys[] = {
{ "objects", G_TYPE_DEBUG_OBJECTS },
+ { "instance-count", G_TYPE_DEBUG_INSTANCE_COUNT },
{ "signals", G_TYPE_DEBUG_SIGNALS },
};
if (G_UNLIKELY (type == (GType)-1))
g_error ("can't happen");
}
+