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