[glib/wip/gproperty] property: Add direct access to generated getters



commit 613421116391efa04f232d3df71e56ce65c51ddf
Author: Emmanuele Bassi <ebassi gnome org>
Date:   Mon Nov 12 19:37:56 2012 +0000

    property: Add direct access to generated getters
    
    This is mostly a WIP/proof of concept patch on top of GProperty. the
    numbers from the performance test case say that we don't gain much, if
    at all, by checking if the property maps to a direct field offset, and
    we get the pointer to the struct member.

 gobject/gproperty.c         |   69 +++++++++++++++++++++++++++++++++++++++++++
 gobject/gproperty.h         |   20 ++++++++++++-
 tests/gobject/performance.c |   12 +++++++
 3 files changed, 100 insertions(+), 1 deletions(-)
---
diff --git a/gobject/gproperty.c b/gobject/gproperty.c
index 55c69c0..d847a03 100644
--- a/gobject/gproperty.c
+++ b/gobject/gproperty.c
@@ -615,6 +615,10 @@ g_##g_t##_property_new (const gchar         *name,      \
 \
   if (setter == NULL && getter == NULL) \
     g_return_val_if_fail (offset >= 0, NULL); \
+  if (setter == NULL) \
+    flags |= G_PROPERTY_DIRECT_SET; \
+  if (getter == NULL) \
+    flags |= G_PROPERTY_DIRECT_GET; \
 \
   prop = g_param_spec_internal (_g_##g_t##_property_get_type (), \
                                 name, NULL, NULL, \
@@ -865,6 +869,23 @@ property_flags_to_param_flags (GPropertyFlags flags)
   return retval;
 }
 
+gpointer
+g_property_get_field (GProperty *property,
+                      gpointer   gobject)
+{
+  gpointer priv_p;
+
+  g_return_val_if_fail (G_IS_PROPERTY (property), NULL);
+  g_return_val_if_fail (G_IS_OBJECT (gobject), NULL);
+  g_return_val_if_fail (property->field_offset >= 0, NULL);
+
+  priv_p = get_private_pointer (gobject, property->priv_offset);
+  if (priv_p == NULL)
+    return NULL;
+
+  return G_STRUCT_MEMBER_P (priv_p, property->field_offset);
+}
+
 /* forward declaration */
 static void property_set_default (GParamSpec *pspec,
                                   GValue     *value);
@@ -1307,6 +1328,10 @@ g_enum_property_new (const gchar      *name,
 
   if (setter == NULL && getter == NULL)
     g_return_val_if_fail (offset >= 0, NULL);
+  if (setter == NULL)
+    flags |= G_PROPERTY_DIRECT_SET;
+  if (getter == NULL)
+    flags |= G_PROPERTY_DIRECT_GET;
 
   prop = g_param_spec_internal (_g_enum_property_get_type (),
                                 name, NULL, NULL,
@@ -1565,6 +1590,10 @@ g_flags_property_new (const gchar       *name,
 
   if (setter == NULL && getter == NULL)
     g_return_val_if_fail (offset >= 0, NULL);
+  if (setter == NULL)
+    flags |= G_PROPERTY_DIRECT_SET;
+  if (getter == NULL)
+    flags |= G_PROPERTY_DIRECT_GET;
 
   prop = g_param_spec_internal (_g_flags_property_get_type (),
                                 name, NULL, NULL,
@@ -1826,6 +1855,10 @@ g_float_property_new (const gchar       *name,
 
   if (setter == NULL && getter == NULL)
     g_return_val_if_fail (offset >= 0, NULL);
+  if (setter == NULL)
+    flags |= G_PROPERTY_DIRECT_SET;
+  if (getter == NULL)
+    flags |= G_PROPERTY_DIRECT_GET;
 
   prop = g_param_spec_internal (_g_float_property_get_type (),
                                 name, NULL, NULL,
@@ -2107,6 +2140,10 @@ g_double_property_new (const gchar        *name,
 
   if (setter == NULL && getter == NULL)
     g_return_val_if_fail (offset >= 0, NULL);
+  if (setter == NULL)
+    flags |= G_PROPERTY_DIRECT_SET;
+  if (getter == NULL)
+    flags |= G_PROPERTY_DIRECT_GET;
 
   prop = g_param_spec_internal (_g_double_property_get_type (),
                                 name, NULL, NULL,
@@ -2346,6 +2383,10 @@ g_string_property_new (const gchar        *name,
 
   if (setter == NULL && getter == NULL)
     g_return_val_if_fail (offset >= 0, NULL);
+  if (setter == NULL)
+    flags |= G_PROPERTY_DIRECT_SET;
+  if (getter == NULL)
+    flags |= G_PROPERTY_DIRECT_GET;
 
   prop = g_param_spec_internal (_g_string_property_get_type (),
                                 name, NULL, NULL,
@@ -2572,6 +2613,10 @@ g_boxed_property_new (const gchar       *name,
 
   if (setter == NULL && getter == NULL)
     g_return_val_if_fail (offset >= 0, NULL);
+  if (setter == NULL)
+    flags |= G_PROPERTY_DIRECT_SET;
+  if (getter == NULL)
+    flags |= G_PROPERTY_DIRECT_GET;
 
   prop = g_param_spec_internal (_g_boxed_property_get_type (),
                                 name, NULL, NULL,
@@ -2797,6 +2842,10 @@ g_object_property_new (const gchar        *name,
 
   if (setter == NULL && getter == NULL)
     g_return_val_if_fail (offset >= 0, NULL);
+  if (setter == NULL)
+    flags |= G_PROPERTY_DIRECT_SET;
+  if (getter == NULL)
+    flags |= G_PROPERTY_DIRECT_GET;
 
   prop = g_param_spec_internal (_g_object_property_get_type (),
                                 name, NULL, NULL,
@@ -3038,6 +3087,10 @@ g_pointer_property_new (const gchar        *name,
 
   if (setter == NULL && getter == NULL)
     g_return_val_if_fail (offset >= 0, NULL);
+  if (setter == NULL)
+    flags |= G_PROPERTY_DIRECT_SET;
+  if (getter == NULL)
+    flags |= G_PROPERTY_DIRECT_GET;
 
   prop = g_param_spec_internal (_g_pointer_property_get_type (),
                                 name, NULL, NULL,
@@ -5440,6 +5493,22 @@ g_property_is_copy_get (GProperty *property)
   return (property->flags & G_PROPERTY_COPY_GET) !=  0;
 }
 
+gboolean
+g_property_is_direct_set (GProperty *property)
+{
+  g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
+
+  return (property->flags & G_PROPERTY_DIRECT_SET) != 0;
+}
+
+gboolean
+g_property_is_direct_get (GProperty *property)
+{
+  g_return_val_if_fail (G_IS_PROPERTY (property), FALSE);
+
+  return (property->flags & G_PROPERTY_DIRECT_GET) != 0;
+}
+
 /**
  * g_property_lock:
  * @property: a #GProperty
diff --git a/gobject/gproperty.h b/gobject/gproperty.h
index c78e44d..8ec58a3 100644
--- a/gobject/gproperty.h
+++ b/gobject/gproperty.h
@@ -78,7 +78,10 @@ typedef enum {
   G_PROPERTY_ATOMIC         = 1 << 3,
   G_PROPERTY_COPY_SET       = 1 << 4,
   G_PROPERTY_COPY_GET       = 1 << 5,
-  G_PROPERTY_COPY           = (G_PROPERTY_COPY_SET | G_PROPERTY_COPY_GET)
+  G_PROPERTY_COPY           = (G_PROPERTY_COPY_SET | G_PROPERTY_COPY_GET),
+  G_PROPERTY_DIRECT_SET     = 1 << 6,
+  G_PROPERTY_DIRECT_GET     = 1 << 7,
+  G_PROPERTY_DIRECT         = (G_PROPERTY_DIRECT_SET | G_PROPERTY_DIRECT_GET)
 } GPropertyFlags;
 
 GLIB_AVAILABLE_IN_2_36
@@ -103,6 +106,14 @@ GLIB_AVAILABLE_IN_2_36
 gboolean        g_property_is_copy_set                  (GProperty    *property);
 GLIB_AVAILABLE_IN_2_36
 gboolean        g_property_is_copy_get                  (GProperty    *property);
+GLIB_AVAILABLE_IN_2_36
+gboolean        g_property_is_direct_set                (GProperty    *property);
+GLIB_AVAILABLE_IN_2_36
+gboolean        g_property_is_direct_get                (GProperty    *property);
+
+GLIB_AVAILABLE_IN_2_36
+gpointer        g_property_get_field                    (GProperty    *property,
+                                                         gpointer      gobject);
 
 GLIB_AVAILABLE_IN_2_36
 void            g_property_describe                     (GProperty    *property,
@@ -491,6 +502,13 @@ GParamSpec *    g_pointer_property_new  (const gchar         *name,
        return (f_t) 0; \
     } \
 \
+  if (g_property_is_direct_get (g_property) && \
+      !g_property_is_atomic (g_property)) \
+    { \
+      gpointer field_p = g_property_get_field (g_property, self); \
+      return (* (f_t *) field_p); \
+    } \
+\
   if (!g_property_get (g_property, self, &retval)) \
     { \
       g_property_get_default (g_property, self, &retval); \
diff --git a/tests/gobject/performance.c b/tests/gobject/performance.c
index 13b0ec7..87b1b7c 100644
--- a/tests/gobject/performance.c
+++ b/tests/gobject/performance.c
@@ -730,6 +730,12 @@ property_object_get_foo (PropertyObject *self)
 {
   gint value;
 
+  if (g_property_is_direct_get (((GProperty *) property_props[PROP_PROPERTY_FOO])))
+    {
+      gpointer field_p = g_property_get_field (((GProperty *) property_props[PROP_PROPERTY_FOO]), self);
+      return (* (int *) field_p);
+    }
+
   g_property_get (((GProperty *) property_props[PROP_PROPERTY_FOO]), self, &value);
 
   return value;
@@ -746,6 +752,12 @@ property_object_get_baz (PropertyObject *self)
 {
   float value;
 
+  if (g_property_is_direct_get (((GProperty *) property_props[PROP_PROPERTY_BAZ])))
+    {
+      gpointer field_p = g_property_get_field (((GProperty *) property_props[PROP_PROPERTY_BAZ]), self);
+      return (* (float *) field_p);
+    }
+
   g_property_get (((GProperty *) property_props[PROP_PROPERTY_BAZ]), self, &value);
 
   return value;



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