[glib/gobject-speedups: 4/13] Keep a count of construct params
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/gobject-speedups: 4/13] Keep a count of construct params
- Date: Mon, 16 May 2022 12:09:26 +0000 (UTC)
commit 5ca46aa94efa670c904ab9709d46e9ab1b1610f7
Author: Matthias Clasen <mclasen redhat com>
Date: Sat May 14 22:38:09 2022 -0400
Keep a count of construct params
This avoids walking the construct params list
one extra time just to count when constructing
objects.
gobject/gobject.c | 43 +++++++++++++++++++++++++++++++++----------
gobject/gobject.h | 3 ++-
2 files changed, 35 insertions(+), 11 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index f720e1c9c1..de46f7187c 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -478,6 +478,7 @@ g_object_base_class_init (GObjectClass *class)
/* reset instance specific fields and methods that don't get inherited */
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->set_property = NULL;
}
@@ -491,6 +492,7 @@ g_object_base_class_finalize (GObjectClass *class)
g_slist_free (class->construct_properties);
class->construct_properties = NULL;
+ class->n_construct_properties = 0;
list = g_param_spec_pool_list_owned (pspec_pool, G_OBJECT_CLASS_TYPE (class));
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 (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
* of the overridden inherited construct property
*/
pspec = g_param_spec_pool_lookup (pspec_pool, pspec->name, parent_type, TRUE);
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;
}
@@ -1872,9 +1880,9 @@ g_object_new_with_custom_constructor (GObjectClass *class,
GObjectNotifyQueue *nqueue = NULL;
gboolean newly_constructed;
GObjectConstructParam *cparams;
+ gboolean free_cparams = FALSE;
GObject *object;
GValue *cvalues;
- gint n_cparams;
gint cvals_used;
GSList *node;
guint i;
@@ -1889,10 +1897,21 @@ g_object_new_with_custom_constructor (GObjectClass *class,
* while their constructor() is running.
*/
- /* Create the array of GObjectConstructParams for constructor() */
- n_cparams = g_slist_length (class->construct_properties);
- cparams = g_new (GObjectConstructParam, n_cparams);
- cvalues = g_new0 (GValue, n_cparams);
+ /* Create the array of GObjectConstructParams for constructor(),
+ * The 1024 here is an arbitrary, high limit that no sane code
+ * will ever hit, just to avoid the possibility of stack overflow.
+ */
+ 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;
i = 0;
@@ -1933,12 +1952,16 @@ g_object_new_with_custom_constructor (GObjectClass *class,
}
/* 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 */
- g_free (cparams);
while (cvals_used--)
g_value_unset (&cvalues[cvals_used]);
- g_free (cvalues);
+
+ if (free_cparams)
+ {
+ g_free (cparams);
+ g_free (cvalues);
+ }
/* There is code in the wild that relies on being able to return NULL
* from its custom constructor. This was never a supported operation,
diff --git a/gobject/gobject.h b/gobject/gobject.h
index 3dc4f7f480..c67794ae50 100644
--- a/gobject/gobject.h
+++ b/gobject/gobject.h
@@ -369,8 +369,9 @@ struct _GObjectClass
/*< private >*/
gsize flags;
+ gsize n_construct_properties;
/* padding */
- gpointer pdummy[6];
+ gpointer pdummy[5];
};
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]