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, GSignalFlags signal_flags,
GClosure *class_closure, GClosure *class_closure,
GSignalAccumulator accumulator, GSignalAccumulator accumulator,
gpointer accu_data, gpointer accu_data,
GSignalCMarshaller c_marshaller, GSignalCMarshaller c_marshaller,
GType return_type, GType return_type,
guint n_params, guint n_params,
va_list args) 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; GType *param_types;
guint i; guint i;
guint signal_id; guint signal_id;
param_types = param_types_stack;
if (n_params > 0) 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++) 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, signal_id = g_signal_newv (signal_name, itype, signal_flags,
class_closure, accumulator, accu_data, c_marshaller, class_closure, accumulator, accu_data, c_marshaller,
return_type, n_params, param_types); return_type, n_params, param_types);
g_free (param_types); g_free (param_types_heap);
return signal_id; return signal_id;
} }