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.
This commit is contained in:
Thomas Haller 2021-01-26 13:38:18 +01:00
parent abd1f4b32b
commit cc4ffe4742

View File

@ -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;
}