[glib/gobject-speedup11: 1/3] Keep a separate flag for notify handlers




commit 8b328f1d6d0f50b708b58849fb968de25f6b2612
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun May 15 07:52:10 2022 -0400

    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.

 gobject/gobject.c       | 27 ++++++++++++++++++++++-----
 gobject/gsignal.c       | 10 +++++-----
 gobject/gtype-private.h |  3 ++-
 3 files changed, 29 insertions(+), 11 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index 6b7e6cede4..9399cd9660 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -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
@@ -1087,7 +1089,7 @@ object_unset_optional_flags (GObject *object,
 }
 
 gboolean
-_g_object_has_signal_handler  (GObject *object)
+_g_object_has_signal_handler (GObject *object)
 {
 #ifdef HAVE_OPTIONAL_FLAGS
   return (object_get_optional_flags (object) & OPTIONAL_FLAG_HAS_SIGNAL_HANDLER) != 0;
@@ -1096,11 +1098,26 @@ _g_object_has_signal_handler  (GObject *object)
 #endif
 }
 
+static inline gboolean
+_g_object_has_notify_handler (GObject *object)
+{
+#ifdef HAVE_OPTIONAL_FLAGS
+  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)
+_g_object_set_has_signal_handler (GObject *object,
+                                  guint    signal_id)
 {
 #ifdef HAVE_OPTIONAL_FLAGS
-  object_set_optional_flags (object, OPTIONAL_FLAG_HAS_SIGNAL_HANDLER);
+  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
 }
 
diff --git a/gobject/gsignal.c b/gobject/gsignal.c
index fb85fd6ba2..ddd23fb738 100644
--- a/gobject/gsignal.c
+++ b/gobject/gsignal.c
@@ -2422,9 +2422,9 @@ 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_seq_no = handler->sequential_number;
          handler->detail = detail;
          handler->closure = g_closure_ref (closure);
          g_closure_sink (closure);
@@ -2489,9 +2489,9 @@ 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_seq_no = handler->sequential_number;
          handler->detail = detail;
          handler->closure = g_closure_ref (closure);
          g_closure_sink (closure);
@@ -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;
diff --git a/gobject/gtype-private.h b/gobject/gtype-private.h
index 2e0afdd5d4..61e936b21f 100644
--- a/gobject/gtype-private.h
+++ b/gobject/gtype-private.h
@@ -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:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]