Avoid malloc for construct params

Stack-allocate the GObjectConstructParams (except for
extreme cases), for a small speedup of object construction.
This commit is contained in:
Matthias Clasen 2022-05-26 09:47:10 -04:00
parent f7119a7935
commit ecc641de71

View File

@ -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,