mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-21 09:42:10 +01:00
gobject/gtype: Avoid duplicate GType to TypeNode lookups
There are some cases where we perform the same lookup_type_node_I() twice. Additionally, if we stash the parent TypeNode pointer in our TypeNode rather than just the GType in supers[], then we can avoid that parent type lookup as well in g_type_class_ref().
This commit is contained in:
parent
17124abc7e
commit
436f4c9c7b
@ -170,6 +170,8 @@ static void type_iface_vtable_iface_init_Wm (TypeNod
|
||||
TypeNode *node);
|
||||
static gboolean type_node_is_a_L (TypeNode *node,
|
||||
TypeNode *iface_node);
|
||||
static gpointer type_class_ref_with_node (GType type,
|
||||
TypeNode *node);
|
||||
|
||||
|
||||
/* --- enumeration --- */
|
||||
@ -207,6 +209,9 @@ struct _TypeNode
|
||||
guint is_final : 1;
|
||||
guint mutatable_check_cache : 1; /* combines some common path checks */
|
||||
|
||||
/* up-pointer to parent */
|
||||
struct _TypeNode *pnode;
|
||||
|
||||
GType *children; /* writable with lock */
|
||||
TypeData *data;
|
||||
GQuark qname;
|
||||
@ -226,6 +231,7 @@ struct _TypeNode
|
||||
#define MAX_N_PREREQUISITES (511)
|
||||
#define NODE_TYPE(node) (node->supers[0])
|
||||
#define NODE_PARENT_TYPE(node) (node->supers[1])
|
||||
#define NODE_PARENT(node) (node->pnode)
|
||||
#define NODE_FUNDAMENTAL_TYPE(node) (node->supers[node->n_supers])
|
||||
#define NODE_NAME(node) (g_quark_to_string (node->qname))
|
||||
#define NODE_REFCOUNT(node) ((guint) g_atomic_int_get ((int *) &(node)->ref_count))
|
||||
@ -492,6 +498,7 @@ type_node_any_new_W (TypeNode *pnode,
|
||||
node->plugin = plugin;
|
||||
node->n_children = 0;
|
||||
node->children = NULL;
|
||||
node->pnode = pnode;
|
||||
node->data = NULL;
|
||||
node->qname = g_quark_from_string (name);
|
||||
node->global_gdata = NULL;
|
||||
@ -1892,7 +1899,7 @@ g_type_create_instance (GType type)
|
||||
maybe_issue_deprecation_warning (type);
|
||||
}
|
||||
|
||||
class = g_type_class_ref (type);
|
||||
class = type_class_ref_with_node (type, node);
|
||||
|
||||
/* We allocate the 'private' areas before the normal instance data, in
|
||||
* reverse order. This allows the private area of a particular class
|
||||
@ -2976,28 +2983,15 @@ g_type_add_interface_dynamic (GType instance_type,
|
||||
}
|
||||
|
||||
|
||||
/* --- public API functions --- */
|
||||
/**
|
||||
* g_type_class_ref:
|
||||
* @type: type ID of a classed type
|
||||
*
|
||||
* Increments the reference count of the class structure belonging to
|
||||
* @type. This function will demand-create the class if it doesn't
|
||||
* exist already.
|
||||
*
|
||||
* Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
|
||||
* structure for the given type ID
|
||||
*/
|
||||
gpointer
|
||||
g_type_class_ref (GType type)
|
||||
static gpointer
|
||||
type_class_ref_with_node (GType type,
|
||||
TypeNode *node)
|
||||
{
|
||||
TypeNode *node;
|
||||
GType ptype;
|
||||
gboolean holds_ref;
|
||||
GTypeClass *pclass;
|
||||
|
||||
/* optimize for common code path */
|
||||
node = lookup_type_node_I (type);
|
||||
if (!node || !node->is_classed)
|
||||
{
|
||||
g_critical ("cannot retrieve class for invalid (unclassed) type '%s'",
|
||||
@ -3013,7 +3007,7 @@ g_type_class_ref (GType type)
|
||||
}
|
||||
else
|
||||
holds_ref = FALSE;
|
||||
|
||||
|
||||
/* here, we either have node->data->class.class == NULL, or a recursive
|
||||
* call to g_type_class_ref() with a partly initialized class, or
|
||||
* node->data->class.init_state == INITIALIZED, because any
|
||||
@ -3023,7 +3017,7 @@ g_type_class_ref (GType type)
|
||||
|
||||
/* we need an initialized parent class for initializing derived classes */
|
||||
ptype = NODE_PARENT_TYPE (node);
|
||||
pclass = ptype ? g_type_class_ref (ptype) : NULL;
|
||||
pclass = ptype ? type_class_ref_with_node (ptype, NODE_PARENT (node)) : NULL;
|
||||
|
||||
G_WRITE_LOCK (&type_rw_lock);
|
||||
|
||||
@ -3043,6 +3037,24 @@ g_type_class_ref (GType type)
|
||||
return node->data->class.class;
|
||||
}
|
||||
|
||||
/* --- public API functions --- */
|
||||
/**
|
||||
* g_type_class_ref:
|
||||
* @type: type ID of a classed type
|
||||
*
|
||||
* Increments the reference count of the class structure belonging to
|
||||
* @type. This function will demand-create the class if it doesn't
|
||||
* exist already.
|
||||
*
|
||||
* Returns: (type GObject.TypeClass) (transfer none): the #GTypeClass
|
||||
* structure for the given type ID
|
||||
*/
|
||||
gpointer
|
||||
g_type_class_ref (GType type)
|
||||
{
|
||||
return type_class_ref_with_node (type, lookup_type_node_I (type));
|
||||
}
|
||||
|
||||
/**
|
||||
* g_type_class_unref:
|
||||
* @g_class: (type GObject.TypeClass): a #GTypeClass structure to unref
|
||||
@ -4055,8 +4067,8 @@ g_type_interface_get_plugin (GType instance_type,
|
||||
TypeNode *iface;
|
||||
|
||||
g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface_type), NULL); /* G_TYPE_IS_INTERFACE() is an external call: _U */
|
||||
|
||||
node = lookup_type_node_I (instance_type);
|
||||
|
||||
node = lookup_type_node_I (instance_type);
|
||||
iface = lookup_type_node_I (interface_type);
|
||||
if (node && iface)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user