mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-06 17:36:14 +01:00
glib/gvariant: Avoid extraneous GBytes ref counting
Right now we create a bunch of GBytes which then get their reference count incremented and immediately decremented. This causes quite a bit of disruption for cacheline re-use. Instead, this change creates an internal helper to transfer ownership of GBytes to the new GVariant directly. Surprisingly, this reduced wallclock time by about 6% for a contrived benchmark of building "as" variant with GVariantBuilder.
This commit is contained in:
parent
842c828535
commit
9a380ee918
@ -593,6 +593,26 @@ GVariant *
|
|||||||
g_variant_new_from_bytes (const GVariantType *type,
|
g_variant_new_from_bytes (const GVariantType *type,
|
||||||
GBytes *bytes,
|
GBytes *bytes,
|
||||||
gboolean trusted)
|
gboolean trusted)
|
||||||
|
{
|
||||||
|
return g_variant_new_take_bytes (type, g_bytes_ref (bytes), trusted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -- internal -- */
|
||||||
|
|
||||||
|
/* < internal >
|
||||||
|
* g_variant_new_take_bytes:
|
||||||
|
* @bytes: (transfer full): a #GBytes
|
||||||
|
* @trusted: if the contents of @bytes are trusted
|
||||||
|
*
|
||||||
|
* The same as g_variant_new_from_bytes() but takes ownership
|
||||||
|
* of @bytes.
|
||||||
|
*
|
||||||
|
* Returns: a new #GVariant with a floating reference
|
||||||
|
*/
|
||||||
|
GVariant *
|
||||||
|
g_variant_new_take_bytes (const GVariantType *type,
|
||||||
|
GBytes *bytes,
|
||||||
|
gboolean trusted)
|
||||||
{
|
{
|
||||||
GVariant *value;
|
GVariant *value;
|
||||||
guint alignment;
|
guint alignment;
|
||||||
@ -639,7 +659,8 @@ g_variant_new_from_bytes (const GVariantType *type,
|
|||||||
if (aligned_size != 0)
|
if (aligned_size != 0)
|
||||||
memcpy (aligned_data, g_bytes_get_data (bytes, NULL), aligned_size);
|
memcpy (aligned_data, g_bytes_get_data (bytes, NULL), aligned_size);
|
||||||
|
|
||||||
bytes = owned_bytes = g_bytes_new_with_free_func (aligned_data,
|
owned_bytes = bytes;
|
||||||
|
bytes = g_bytes_new_with_free_func (aligned_data,
|
||||||
aligned_size,
|
aligned_size,
|
||||||
free, aligned_data);
|
free, aligned_data);
|
||||||
aligned_data = NULL;
|
aligned_data = NULL;
|
||||||
@ -648,12 +669,13 @@ g_variant_new_from_bytes (const GVariantType *type,
|
|||||||
* have malloc() that returns non-8-aligned. if so, we need to try
|
* have malloc() that returns non-8-aligned. if so, we need to try
|
||||||
* harder here.
|
* harder here.
|
||||||
*/
|
*/
|
||||||
bytes = owned_bytes = g_bytes_new (g_bytes_get_data (bytes, NULL),
|
owned_bytes = bytes;
|
||||||
|
bytes = g_bytes_new (g_bytes_get_data (bytes, NULL),
|
||||||
g_bytes_get_size (bytes));
|
g_bytes_get_size (bytes));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
value->contents.serialised.bytes = g_bytes_ref (bytes);
|
value->contents.serialised.bytes = bytes;
|
||||||
|
|
||||||
if (size && g_bytes_get_size (bytes) != size)
|
if (size && g_bytes_get_size (bytes) != size)
|
||||||
{
|
{
|
||||||
@ -682,8 +704,6 @@ g_variant_new_from_bytes (const GVariantType *type,
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -- internal -- */
|
|
||||||
|
|
||||||
/* < internal >
|
/* < internal >
|
||||||
* g_variant_new_from_children:
|
* g_variant_new_from_children:
|
||||||
* @type: a #GVariantType
|
* @type: a #GVariantType
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
|
|
||||||
/* gvariant-core.c */
|
/* gvariant-core.c */
|
||||||
|
|
||||||
|
GVariant * g_variant_new_take_bytes (const GVariantType *type,
|
||||||
|
GBytes *bytes,
|
||||||
|
gboolean trusted);
|
||||||
GVariant * g_variant_new_from_children (const GVariantType *type,
|
GVariant * g_variant_new_from_children (const GVariantType *type,
|
||||||
GVariant **children,
|
GVariant **children,
|
||||||
gsize n_children,
|
gsize n_children,
|
||||||
|
@ -321,14 +321,7 @@ g_variant_new_from_trusted (const GVariantType *type,
|
|||||||
gconstpointer data,
|
gconstpointer data,
|
||||||
gsize size)
|
gsize size)
|
||||||
{
|
{
|
||||||
GVariant *value;
|
return g_variant_new_take_bytes (type, g_bytes_new (data, size), TRUE);
|
||||||
GBytes *bytes;
|
|
||||||
|
|
||||||
bytes = g_bytes_new (data, size);
|
|
||||||
value = g_variant_new_from_bytes (type, bytes, TRUE);
|
|
||||||
g_bytes_unref (bytes);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1311,14 +1304,8 @@ g_variant_new_take_string (gchar *string)
|
|||||||
|
|
||||||
if G_LIKELY (g_utf8_validate (string, -1, &end))
|
if G_LIKELY (g_utf8_validate (string, -1, &end))
|
||||||
{
|
{
|
||||||
GVariant *value;
|
GBytes *bytes = g_bytes_new_take (string, end - string + 1);
|
||||||
GBytes *bytes;
|
return g_variant_new_take_bytes (G_VARIANT_TYPE_STRING, g_steal_pointer (&bytes), TRUE);
|
||||||
|
|
||||||
bytes = g_bytes_new_take (string, end - string + 1);
|
|
||||||
value = g_variant_new_from_bytes (G_VARIANT_TYPE_STRING, bytes, TRUE);
|
|
||||||
g_bytes_unref (bytes);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_critical ("g_variant_new_take_string(): requires valid UTF-8");
|
g_critical ("g_variant_new_take_string(): requires valid UTF-8");
|
||||||
@ -1358,8 +1345,7 @@ g_variant_new_printf (const gchar *format_string,
|
|||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
bytes = g_bytes_new_take (string, strlen (string) + 1);
|
bytes = g_bytes_new_take (string, strlen (string) + 1);
|
||||||
value = g_variant_new_from_bytes (G_VARIANT_TYPE_STRING, bytes, TRUE);
|
value = g_variant_new_take_bytes (G_VARIANT_TYPE_STRING, g_steal_pointer (&bytes), TRUE);
|
||||||
g_bytes_unref (bytes);
|
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -6167,8 +6153,7 @@ g_variant_byteswap (GVariant *value)
|
|||||||
g_variant_serialised_byteswap (serialised);
|
g_variant_serialised_byteswap (serialised);
|
||||||
|
|
||||||
bytes = g_bytes_new_take (serialised.data, serialised.size);
|
bytes = g_bytes_new_take (serialised.data, serialised.size);
|
||||||
new = g_variant_ref_sink (g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE));
|
new = g_variant_ref_sink (g_variant_new_take_bytes (g_variant_get_type (value), g_steal_pointer (&bytes), TRUE));
|
||||||
g_bytes_unref (bytes);
|
|
||||||
}
|
}
|
||||||
else if (alignment)
|
else if (alignment)
|
||||||
/* (potentially) contains multi-byte numeric data */
|
/* (potentially) contains multi-byte numeric data */
|
||||||
@ -6233,7 +6218,6 @@ g_variant_new_from_data (const GVariantType *type,
|
|||||||
GDestroyNotify notify,
|
GDestroyNotify notify,
|
||||||
gpointer user_data)
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GVariant *value;
|
|
||||||
GBytes *bytes;
|
GBytes *bytes;
|
||||||
|
|
||||||
g_return_val_if_fail (g_variant_type_is_definite (type), NULL);
|
g_return_val_if_fail (g_variant_type_is_definite (type), NULL);
|
||||||
@ -6244,10 +6228,7 @@ g_variant_new_from_data (const GVariantType *type,
|
|||||||
else
|
else
|
||||||
bytes = g_bytes_new_static (data, size);
|
bytes = g_bytes_new_static (data, size);
|
||||||
|
|
||||||
value = g_variant_new_from_bytes (type, bytes, trusted);
|
return g_variant_new_take_bytes (type, g_steal_pointer (&bytes), trusted);
|
||||||
g_bytes_unref (bytes);
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Epilogue {{{1 */
|
/* Epilogue {{{1 */
|
||||||
|
Loading…
Reference in New Issue
Block a user