diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2020-11-21 22:55:55 +0000 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2020-11-21 22:55:55 +0000 |
commit | 9f041c9e0559db8aa7ec5d867761cfdc97129541 (patch) | |
tree | c9857ae521bda103561ddd84f849af7cd3e6d352 | |
parent | fa8a39c6c65b808a0e65e43227618ad4dafb818b (diff) | |
parent | fb3977e9b4fb0b731d01bb4cff99a8f6be6e75c8 (diff) | |
download | glib-9f041c9e0559db8aa7ec5d867761cfdc97129541.tar.gz |
Merge branch 'th/gobject-new-parameter-list' into 'master'
gobject: allocate parameter list for g_object_new_valist() entirely on stack
See merge request GNOME/glib!1385
-rw-r--r-- | gobject/gobject.c | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/gobject/gobject.c b/gobject/gobject.c index a3a32be9f..6ab662eaa 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -2005,9 +2005,10 @@ g_object_new_is_valid_property (GType object_type, GParamSpec *pspec, const char *name, GObjectConstructParam *params, - int n_params) + guint n_params) { - gint i; + guint i; + if (G_UNLIKELY (pspec == NULL)) { g_critical ("%s: object class '%s' has no property named '%s'", @@ -2217,13 +2218,15 @@ g_object_new_valist (GType object_type, if (first_property_name) { - GObjectConstructParam stack_params[16]; - GObjectConstructParam *params; + GObjectConstructParam params_stack[16]; + GValue values_stack[G_N_ELEMENTS (params_stack)]; const gchar *name; - gint n_params = 0; + GObjectConstructParam *params = params_stack; + GValue *values = values_stack; + guint n_params = 0; + guint n_params_alloc = G_N_ELEMENTS (params_stack); name = first_property_name; - params = stack_params; do { @@ -2235,24 +2238,39 @@ g_object_new_valist (GType object_type, if (!g_object_new_is_valid_property (object_type, pspec, name, params, n_params)) break; - if (n_params == 16) + if (G_UNLIKELY (n_params == n_params_alloc)) { - params = g_new (GObjectConstructParam, n_params + 1); - memcpy (params, stack_params, sizeof stack_params); + guint i; + + if (n_params_alloc == G_N_ELEMENTS (params_stack)) + { + n_params_alloc = G_N_ELEMENTS (params_stack) * 2u; + params = g_new (GObjectConstructParam, n_params_alloc); + values = g_new (GValue, n_params_alloc); + memcpy (params, params_stack, sizeof (GObjectConstructParam) * n_params); + memcpy (values, values_stack, sizeof (GValue) * n_params); + } + else + { + n_params_alloc *= 2u; + params = g_realloc (params, sizeof (GObjectConstructParam) * n_params_alloc); + values = g_realloc (values, sizeof (GValue) * n_params_alloc); + } + + for (i = 0; i < n_params; i++) + params[i].value = &values[i]; } - else if (n_params > 16) - params = g_renew (GObjectConstructParam, params, n_params + 1); params[n_params].pspec = pspec; - params[n_params].value = g_newa (GValue, 1); - memset (params[n_params].value, 0, sizeof (GValue)); + params[n_params].value = &values[n_params]; + memset (&values[n_params], 0, sizeof (GValue)); - G_VALUE_COLLECT_INIT (params[n_params].value, pspec->value_type, var_args, 0, &error); + G_VALUE_COLLECT_INIT (&values[n_params], pspec->value_type, var_args, 0, &error); if (error) { g_critical ("%s: %s", G_STRFUNC, error); - g_value_unset (params[n_params].value); + g_value_unset (&values[n_params]); g_free (error); break; } @@ -2266,8 +2284,11 @@ g_object_new_valist (GType object_type, while (n_params--) g_value_unset (params[n_params].value); - if (params != stack_params) - g_free (params); + if (G_UNLIKELY (n_params_alloc != G_N_ELEMENTS (params_stack))) + { + g_free (params); + g_free (values); + } } else /* Fast case: no properties passed in. */ |