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.
This commit is contained in:
Emmanuele Bassi 2012-11-12 19:37:56 +00:00
parent 72e08fb87b
commit 6134211163
3 changed files with 100 additions and 1 deletions

View File

@ -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

View File

@ -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,
@ -490,6 +501,13 @@ GParamSpec * g_pointer_property_new (const gchar *name,
g_critical (G_STRLOC ": The property " #f_n " is not readable"); \
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)) \
{ \

View File

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