diff options
author | Matthias Clasen <mclasen@redhat.com> | 2022-05-26 09:47:10 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2022-05-26 09:47:23 -0400 |
commit | ecc641de710e226a979e1a3e9e2fe605b480a490 (patch) | |
tree | 8889aee5297009c575c94a650d523e2c8af81368 | |
parent | f7119a79354d1b55f18b8158573630ab861146f8 (diff) | |
download | glib-ecc641de710e226a979e1a3e9e2fe605b480a490.tar.gz |
Avoid malloc for construct params
Stack-allocate the GObjectConstructParams (except for
extreme cases), for a small speedup of object construction.
-rw-r--r-- | gobject/gobject.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/gobject/gobject.c b/gobject/gobject.c index e44494b13..ef62a03fa 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -1881,6 +1881,7 @@ 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 cvals_used; @@ -1897,9 +1898,21 @@ g_object_new_with_custom_constructor (GObjectClass *class, * while their constructor() is running. */ - /* Create the array of GObjectConstructParams for constructor() */ - cparams = g_new (GObjectConstructParam, class->n_construct_properties); - cvalues = g_new0 (GValue, class->n_construct_properties); + /* 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; @@ -1942,10 +1955,14 @@ g_object_new_with_custom_constructor (GObjectClass *class, /* construct object from construction parameters */ 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, |