Keep a separate flag for notify handlers

We currently keep a flag for whether an object has
ever had any signal handlers. But even if it had signal
handlers, it may not have any notify handlers. Keep that
information separately, so we can speed up property setting.
This commit is contained in:
Matthias Clasen 2022-05-15 07:52:10 -04:00
parent 2b437402e8
commit 8b328f1d6d
3 changed files with 30 additions and 12 deletions

View File

@ -151,6 +151,7 @@
((class)->constructor != g_object_constructor)
#define CLASS_HAS_CUSTOM_CONSTRUCTED(class) \
((class)->constructed != g_object_constructed)
#define CLASS_HAS_NOTIFY(class) ((class)->notify != NULL)
#define CLASS_HAS_DERIVED_CLASS_FLAG 0x2
#define CLASS_HAS_DERIVED_CLASS(class) \
@ -168,8 +169,9 @@ enum {
PROP_NONE
};
#define OPTIONAL_FLAG_IN_CONSTRUCTION 1<<0
#define OPTIONAL_FLAG_HAS_SIGNAL_HANDLER 1<<1 /* Set if object ever had a signal handler */
#define OPTIONAL_FLAG_IN_CONSTRUCTION (1 << 0)
#define OPTIONAL_FLAG_HAS_SIGNAL_HANDLER (1 << 1) /* Set if object ever had a signal handler */
#define OPTIONAL_FLAG_HAS_NOTIFY_HANDLER (1 << 2) /* Same, specifically for "notify" */
#if SIZEOF_INT == 4 && GLIB_SIZEOF_VOID_P == 8
#define HAVE_OPTIONAL_FLAGS
@ -1096,11 +1098,26 @@ _g_object_has_signal_handler (GObject *object)
#endif
}
void
_g_object_set_has_signal_handler (GObject *object)
static inline gboolean
_g_object_has_notify_handler (GObject *object)
{
#ifdef HAVE_OPTIONAL_FLAGS
object_set_optional_flags (object, OPTIONAL_FLAG_HAS_SIGNAL_HANDLER);
return CLASS_HAS_NOTIFY (G_OBJECT_GET_CLASS (object)) ||
(object_get_optional_flags (object) & OPTIONAL_FLAG_HAS_NOTIFY_HANDLER) != 0;
#else
return TRUE;
#endif
}
void
_g_object_set_has_signal_handler (GObject *object,
guint signal_id)
{
#ifdef HAVE_OPTIONAL_FLAGS
guint flags = OPTIONAL_FLAG_HAS_SIGNAL_HANDLER;
if (signal_id == gobject_signals[NOTIFY])
flags |= OPTIONAL_FLAG_HAS_NOTIFY_HANDLER;
object_set_optional_flags (object, flags);
#endif
}

View File

@ -2422,7 +2422,7 @@ g_signal_connect_closure_by_id (gpointer instance,
Handler *handler = handler_new (signal_id, instance, after);
if (G_TYPE_IS_OBJECT (node->itype))
_g_object_set_has_signal_handler ((GObject *)instance);
_g_object_set_has_signal_handler ((GObject *) instance, signal_id);
handler_seq_no = handler->sequential_number;
handler->detail = detail;
@ -2489,7 +2489,7 @@ g_signal_connect_closure (gpointer instance,
Handler *handler = handler_new (signal_id, instance, after);
if (G_TYPE_IS_OBJECT (node->itype))
_g_object_set_has_signal_handler ((GObject *)instance);
_g_object_set_has_signal_handler ((GObject *) instance, signal_id);
handler_seq_no = handler->sequential_number;
handler->detail = detail;
@ -2593,7 +2593,7 @@ g_signal_connect_data (gpointer instance,
Handler *handler = handler_new (signal_id, instance, after);
if (G_TYPE_IS_OBJECT (node->itype))
_g_object_set_has_signal_handler ((GObject *)instance);
_g_object_set_has_signal_handler ((GObject *) instance, signal_id);
handler_seq_no = handler->sequential_number;
handler->detail = detail;

View File

@ -94,7 +94,8 @@ void _g_closure_invoke_va (GClosure *closure,
GType *param_types);
gboolean _g_object_has_signal_handler (GObject *object);
void _g_object_set_has_signal_handler (GObject *object);
void _g_object_set_has_signal_handler (GObject *object,
guint signal_id);
/**
* _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE: