From c30c0bb34d80013489897c49bef36cc56972d5d9 Mon Sep 17 00:00:00 2001 From: Ryan Lortie Date: Tue, 23 Apr 2013 10:38:23 -0400 Subject: [PATCH] GType: add accessor for instance private offset Since instance private data is now always at a constant offset to the instance pointer, we can add an accessor for it that doesn't also require an instance. The idea is that classes can call this from their class_init and store it in a file-scoped static variable and use that to find their private data on instances very quickly, without a priv pointer. https://bugzilla.gnome.org/show_bug.cgi?id=698056 --- docs/reference/gobject/gobject-sections.txt | 1 + gobject/gtype.c | 48 +++++++++++++++++++++++++++++ gobject/gtype.h | 2 ++ 3 files changed, 51 insertions(+) diff --git a/docs/reference/gobject/gobject-sections.txt b/docs/reference/gobject/gobject-sections.txt index a85699bc3..9a190e027 100644 --- a/docs/reference/gobject/gobject-sections.txt +++ b/docs/reference/gobject/gobject-sections.txt @@ -125,6 +125,7 @@ g_type_check_is_value_type g_type_check_value g_type_check_value_holds g_type_instance_get_private +g_type_class_get_instance_private_offset g_type_class_get_private g_type_test_flags g_type_name_from_instance diff --git a/gobject/gtype.c b/gobject/gtype.c index c3f4374b1..6cd8ac46b 100644 --- a/gobject/gtype.c +++ b/gobject/gtype.c @@ -4529,6 +4529,54 @@ g_type_instance_get_private (GTypeInstance *instance, } /** + * g_type_class_get_instance_private_offset: (skip) + * @g_class: a #GTypeClass + * + * Gets the offset of the private data for instances of @g_class. + * + * This is how many bytes you should add to the instance pointer of a + * class in order to get the private data for the type represented by + * @g_class. + * + * You can only call this function after you have registered a private + * data area for @g_class using g_type_class_add_private(). + * + * Returns: the offset, in bytes + * + * Since: 2.38 + **/ +gint +g_type_class_get_instance_private_offset (gpointer g_class) +{ + GType instance_type; + guint16 parent_size; + TypeNode *node; + + g_assert (g_class != NULL); + + instance_type = ((GTypeClass *) g_class)->g_type; + node = lookup_type_node_I (instance_type); + + g_assert (node != NULL); + g_assert (node->is_instantiatable); + + if (NODE_PARENT_TYPE (node)) + { + TypeNode *pnode = lookup_type_node_I (NODE_PARENT_TYPE (node)); + + parent_size = pnode->data->instance.private_size; + } + else + parent_size = 0; + + if (node->data->instance.private_size == parent_size) + g_error ("g_type_class_get_instance_private_offset() called on class %s but it has no private data", + g_type_name (instance_type)); + + return -(gint) node->data->instance.private_size; +} + +/** * g_type_add_class_private: * @class_type: GType of an classed type. * @private_size: size of private structure. diff --git a/gobject/gtype.h b/gobject/gtype.h index f6f6f9338..a0a57f03e 100644 --- a/gobject/gtype.h +++ b/gobject/gtype.h @@ -1294,6 +1294,8 @@ void g_type_add_class_private (GType class_type, GLIB_AVAILABLE_IN_ALL gpointer g_type_class_get_private (GTypeClass *klass, GType private_type); +GLIB_AVAILABLE_IN_2_38 +gint g_type_class_get_instance_private_offset (gpointer g_class); GLIB_AVAILABLE_IN_2_34 void g_type_ensure (GType type); -- 2.11.4.GIT