From cc4ffe47427c8af135d93107e09dcaae95538183 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Jan 2021 13:38:18 +0100 Subject: [PATCH] gsignal: use stack allocate temporary buffer in g_signal_new_valist() g_signal_new_valist() is called by g_signal_new(), which is probably the most common way to create a signal. Also, in almost all cases is the number of signal parameters small. Let's optimize for that by using a stack allocated buffer if we have few parameters. --- gobject/gsignal.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/gobject/gsignal.c b/gobject/gsignal.c index 4e50a2be2..937e106f8 100644 --- a/gobject/gsignal.c +++ b/gobject/gsignal.c @@ -1952,30 +1952,38 @@ g_signal_new_valist (const gchar *signal_name, GSignalFlags signal_flags, GClosure *class_closure, GSignalAccumulator accumulator, - gpointer accu_data, + gpointer accu_data, GSignalCMarshaller c_marshaller, GType return_type, guint n_params, va_list args) { + /* Somewhat arbitrarily reserve 200 bytes. That should cover the majority + * of cases where n_params is small and still be small enough for what we + * want to put on the stack. */ + GType param_types_stack[200 / sizeof (GType)]; + GType *param_types_heap = NULL; GType *param_types; guint i; guint signal_id; + param_types = param_types_stack; if (n_params > 0) { - param_types = g_new (GType, n_params); + if (G_UNLIKELY (n_params > G_N_ELEMENTS (param_types_stack))) + { + param_types_heap = g_new (GType, n_params); + param_types = param_types_heap; + } for (i = 0; i < n_params; i++) - param_types[i] = va_arg (args, GType); + param_types[i] = va_arg (args, GType); } - else - param_types = NULL; signal_id = g_signal_newv (signal_name, itype, signal_flags, - class_closure, accumulator, accu_data, c_marshaller, - return_type, n_params, param_types); - g_free (param_types); + class_closure, accumulator, accu_data, c_marshaller, + return_type, n_params, param_types); + g_free (param_types_heap); return signal_id; }