Merge branch 'gobject-speedups3' into 'main'

gobject: Keep a count of construct params

See merge request GNOME/glib!2690
This commit is contained in:
Matthias Clasen 2022-05-26 14:07:26 +00:00
commit 694e91c130
2 changed files with 35 additions and 11 deletions

View File

@ -478,6 +478,7 @@ g_object_base_class_init (GObjectClass *class)
/* reset instance specific fields and methods that don't get inherited */ /* reset instance specific fields and methods that don't get inherited */
class->construct_properties = pclass ? g_slist_copy (pclass->construct_properties) : NULL; class->construct_properties = pclass ? g_slist_copy (pclass->construct_properties) : NULL;
class->n_construct_properties = g_slist_length (class->construct_properties);
class->get_property = NULL; class->get_property = NULL;
class->set_property = NULL; class->set_property = NULL;
} }
@ -491,6 +492,7 @@ g_object_base_class_finalize (GObjectClass *class)
g_slist_free (class->construct_properties); g_slist_free (class->construct_properties);
class->construct_properties = NULL; class->construct_properties = NULL;
class->n_construct_properties = 0;
list = g_param_spec_pool_list_owned (pspec_pool, G_OBJECT_CLASS_TYPE (class)); list = g_param_spec_pool_list_owned (pspec_pool, G_OBJECT_CLASS_TYPE (class));
for (node = list; node; node = node->next) for (node = list; node; node = node->next)
{ {
@ -627,14 +629,20 @@ validate_and_install_class_property (GObjectClass *class,
if (install_property_internal (oclass_type, property_id, pspec)) if (install_property_internal (oclass_type, property_id, pspec))
{ {
if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) if (pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
{
class->construct_properties = g_slist_append (class->construct_properties, pspec); class->construct_properties = g_slist_append (class->construct_properties, pspec);
class->n_construct_properties += 1;
}
/* for property overrides of construct properties, we have to get rid /* for property overrides of construct properties, we have to get rid
* of the overridden inherited construct property * of the overridden inherited construct property
*/ */
pspec = g_param_spec_pool_lookup (pspec_pool, pspec->name, parent_type, TRUE); pspec = g_param_spec_pool_lookup (pspec_pool, pspec->name, parent_type, TRUE);
if (pspec && pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) if (pspec && pspec->flags & (G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY))
{
class->construct_properties = g_slist_remove (class->construct_properties, pspec); class->construct_properties = g_slist_remove (class->construct_properties, pspec);
class->n_construct_properties -= 1;
}
return TRUE; return TRUE;
} }
@ -1873,9 +1881,9 @@ g_object_new_with_custom_constructor (GObjectClass *class,
GObjectNotifyQueue *nqueue = NULL; GObjectNotifyQueue *nqueue = NULL;
gboolean newly_constructed; gboolean newly_constructed;
GObjectConstructParam *cparams; GObjectConstructParam *cparams;
gboolean free_cparams = FALSE;
GObject *object; GObject *object;
GValue *cvalues; GValue *cvalues;
gint n_cparams;
gint cvals_used; gint cvals_used;
GSList *node; GSList *node;
guint i; guint i;
@ -1890,10 +1898,21 @@ g_object_new_with_custom_constructor (GObjectClass *class,
* while their constructor() is running. * while their constructor() is running.
*/ */
/* Create the array of GObjectConstructParams for constructor() */ /* Create the array of GObjectConstructParams for constructor(),
n_cparams = g_slist_length (class->construct_properties); * The 1024 here is an arbitrary, high limit that no sane code
cparams = g_new (GObjectConstructParam, n_cparams); * will ever hit, just to avoid the possibility of stack overflow.
cvalues = g_new0 (GValue, n_cparams); */
if (G_LIKELY (class->n_construct_properties < 1024))
{
cparams = g_newa0 (GObjectConstructParam, class->n_construct_properties);
cvalues = g_newa0 (GValue, class->n_construct_properties);
}
else
{
cparams = g_new0 (GObjectConstructParam, class->n_construct_properties);
cvalues = g_new0 (GValue, class->n_construct_properties);
free_cparams = TRUE;
}
cvals_used = 0; cvals_used = 0;
i = 0; i = 0;
@ -1934,12 +1953,16 @@ g_object_new_with_custom_constructor (GObjectClass *class,
} }
/* construct object from construction parameters */ /* construct object from construction parameters */
object = class->constructor (class->g_type_class.g_type, n_cparams, cparams); object = class->constructor (class->g_type_class.g_type, class->n_construct_properties, cparams);
/* free construction values */ /* free construction values */
g_free (cparams);
while (cvals_used--) while (cvals_used--)
g_value_unset (&cvalues[cvals_used]); g_value_unset (&cvalues[cvals_used]);
if (free_cparams)
{
g_free (cparams);
g_free (cvalues); g_free (cvalues);
}
/* There is code in the wild that relies on being able to return NULL /* There is code in the wild that relies on being able to return NULL
* from its custom constructor. This was never a supported operation, * from its custom constructor. This was never a supported operation,

View File

@ -369,8 +369,9 @@ struct _GObjectClass
/*< private >*/ /*< private >*/
gsize flags; gsize flags;
gsize n_construct_properties;
/* padding */ /* padding */
gpointer pdummy[6]; gpointer pdummy[5];
}; };
/** /**