After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 732754 - GDBusMessage: optimise (de)serialisation of fixed arrays
GDBusMessage: optimise (de)serialisation of fixed arrays
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gdbus
unspecified
Other All
: Normal normal
: ---
Assigned To: David Zeuthen (not reading bugmail)
gtkdev
Depends on:
Blocks:
 
 
Reported: 2014-07-04 22:44 UTC by Allison Karlitskaya (desrt)
Modified: 2014-07-24 13:51 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GDBusMessage: simplify byteswapping (4.20 KB, patch)
2014-07-04 22:44 UTC, Allison Karlitskaya (desrt)
needs-work Details | Review
GDBusMessage: fast-path decoding of fixed arrays (7.37 KB, patch)
2014-07-04 22:44 UTC, Allison Karlitskaya (desrt)
none Details | Review
GDBusMessage: fast-path encoding of fixed arrays (2.48 KB, patch)
2014-07-04 22:44 UTC, Allison Karlitskaya (desrt)
committed Details | Review
GDBusMessage: simplify byteswapping (4.20 KB, patch)
2014-07-06 01:27 UTC, Allison Karlitskaya (desrt)
committed Details | Review
GDBusMessage: fast-path decoding of fixed arrays (7.37 KB, patch)
2014-07-06 01:27 UTC, Allison Karlitskaya (desrt)
committed Details | Review
Test case for regression (1.41 KB, text/x-csrc)
2014-07-22 17:10 UTC, Stef Walter
  Details
gio: Add regression test for double array encoding (4.23 KB, patch)
2014-07-22 19:20 UTC, Stef Walter
committed Details | Review
gio: Fix regression encoding an array of doubles (868 bytes, patch)
2014-07-22 19:33 UTC, Stef Walter
committed Details | Review
Properly fix encoding of double arrays (1.92 KB, patch)
2014-07-24 09:58 UTC, Allison Karlitskaya (desrt)
committed Details | Review

Description Allison Karlitskaya (desrt) 2014-07-04 22:44:42 UTC
While trying to reproduce bug 732737 I decided to store a 50MB string in
dconf.

Due to the missing features in the D-Bus serialisation format, dconf
sends all messages to the service as a GVariant-formatted blob of 'ay'.
This means that I was sending a blob of ~50MB.

Unfortunately, GDBus handles this by creating 50 million separate
one-byte GVariant instances....

Let's fix that.
Comment 1 Allison Karlitskaya (desrt) 2014-07-04 22:44:45 UTC
Created attachment 279933 [details] [review]
GDBusMessage: simplify byteswapping

Remove some duplication by simplifying our byteswap checks.
Comment 2 Allison Karlitskaya (desrt) 2014-07-04 22:44:49 UTC
Created attachment 279934 [details] [review]
GDBusMessage: fast-path decoding of fixed arrays

Instead of creating a separate GVariant for each of the 'y's in an 'ay',
use g_variant_new_fixed_array().
Comment 3 Allison Karlitskaya (desrt) 2014-07-04 22:44:52 UTC
Created attachment 279935 [details] [review]
GDBusMessage: fast-path encoding of fixed arrays

Instead of handling each item separately, handle the array as a whole.
Comment 4 Christian Persch 2014-07-05 08:17:15 UTC
Review of attachment 279934 [details] [review]:

::: gio/gdbusmessage.c
@@ +1208,2 @@
 static gboolean
+get_type_fixed_size (const GVariantType *type)

You return 0/1/2/4/8 not TRUE/FALSE. So make this return guint or gsize not gboolean.

@@ +1641,2 @@
           const GVariantType *element_type;
+          guint32 fixed_size;

In the following patch you use guint... pick one? :-)
Comment 5 Lars Karlitski 2014-07-05 14:03:45 UTC
Review of attachment 279933 [details] [review]:

::: gio/gdbusmessage.c
@@ +71,3 @@
+  return mbuf->byte_order == G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
+#else
+  return byte_order == G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;

mbuf->byte_order
Comment 6 Allison Karlitskaya (desrt) 2014-07-05 16:25:02 UTC
(In reply to comment #4)
> Review of attachment 279934 [details] [review]:
> 
> ::: gio/gdbusmessage.c
> @@ +1208,2 @@
>  static gboolean
> +get_type_fixed_size (const GVariantType *type)
> 
> You return 0/1/2/4/8 not TRUE/FALSE. So make this return guint or gsize not
> gboolean.


This was get_type_is_fixed_size() before, then I changed it.  Oops :)


> 
> @@ +1641,2 @@
>            const GVariantType *element_type;
> +          guint32 fixed_size;
> 
> In the following patch you use guint... pick one? :-)

sure.  Will redo.



(In reply to comment #5)
> Review of attachment 279933 [details] [review]:
> mbuf->byte_order

thx.
Comment 7 Allison Karlitskaya (desrt) 2014-07-06 01:27:28 UTC
Created attachment 279972 [details] [review]
GDBusMessage: simplify byteswapping

Remove some duplication by simplifying our byteswap checks.
Comment 8 Allison Karlitskaya (desrt) 2014-07-06 01:27:44 UTC
Created attachment 279973 [details] [review]
GDBusMessage: fast-path decoding of fixed arrays

Instead of creating a separate GVariant for each of the 'y's in an 'ay',
use g_variant_new_fixed_array().
Comment 9 Matthias Clasen 2014-07-07 18:59:15 UTC
Review of attachment 279973 [details] [review]:

looks reasonable. I assume we have test coverage for this path ?
Comment 10 Matthias Clasen 2014-07-07 18:59:39 UTC
Review of attachment 279972 [details] [review]:

sure, ok
Comment 11 Allison Karlitskaya (desrt) 2014-07-07 19:01:40 UTC
(In reply to comment #9)
> Review of attachment 279973 [details] [review]:
> 
> looks reasonable. I assume we have test coverage for this path ?

we do.  gdbus-serialization actually caught me when I failed to include the byteswap...
Comment 12 Allison Karlitskaya (desrt) 2014-07-07 19:03:37 UTC
Comment on attachment 279972 [details] [review]
GDBusMessage: simplify byteswapping

Attachment 279972 [details] pushed as d108ada - GDBusMessage: simplify byteswapping
Comment 13 Matthias Clasen 2014-07-09 02:48:05 UTC
Review of attachment 279973 [details] [review]:

ok then
Comment 14 Colin Walters 2014-07-09 11:35:42 UTC
Review of attachment 279973 [details] [review]:

Holy shit, how did we ship with this for so long...

::: gio/gdbusmessage.c
@@ +1407,3 @@
+  gconstpointer result;
+
+  if (mbuf->pos + len > mbuf->valid_len || mbuf->pos + len < mbuf->pos)

G_UNLIKELY?

@@ +1902,2 @@
   if (ret != NULL)
+    g_variant_take_ref (ret);

Very minor, but would prefer this as a separate patch as it's semantically unrelated.
Comment 15 Allison Karlitskaya (desrt) 2014-07-09 14:43:41 UTC
Attachment 279935 [details] pushed as 958da1e - GDBusMessage: fast-path encoding of fixed arrays
Attachment 279973 [details] pushed as 5463c8c - GDBusMessage: fast-path decoding of fixed arrays
Comment 16 Allison Karlitskaya (desrt) 2014-07-09 14:51:18 UTC
(In reply to comment #14)
> Very minor, but would prefer this as a separate patch as it's semantically
> unrelated.

Sorry that I didn't see this before the push :(

I had to make that change because of the use of g_variant_byteswap().  This returns a hard reference, not floating, which means that this had to change to g_variant_take_ref().

As for the UNLIKELY, it was a copy/paste from a similar function for handling strings, but sure -- I can do another patch... for both cases.
Comment 17 Stef Walter 2014-07-22 17:10:01 UTC
Created attachment 281404 [details]
Test case for regression

This broke encoding of an array of doubles. Attached is a rough test.
Comment 18 Colin Walters 2014-07-22 17:12:52 UTC
Downstream regression: https://bugzilla.redhat.com/show_bug.cgi?id=1122128
Comment 19 Stef Walter 2014-07-22 19:20:08 UTC
Created attachment 281417 [details] [review]
gio: Add regression test for double array encoding
Comment 20 Stef Walter 2014-07-22 19:33:24 UTC
Created attachment 281435 [details] [review]
gio: Fix regression encoding an array of doubles

Take the simple slow path in this case. Encoding a double
takes special precautions as you can see in append_value_to_blob()
and friends.
Comment 21 Allison Karlitskaya (desrt) 2014-07-23 12:33:38 UTC
Review of attachment 281435 [details] [review]:

Please commit this only with a comment mentioning that we intentionally exclude 'd' and linking to the report.
Comment 22 Allison Karlitskaya (desrt) 2014-07-23 12:35:40 UTC
Review of attachment 281417 [details] [review]:

Would prefer this in one of the many existing files (like maybe the gdbus-serialization test) but will not block you if you do not want to take the effort to do that...
Comment 23 Stef Walter 2014-07-23 14:26:19 UTC
Review of attachment 281417 [details] [review]:

Put the test in gdbus-serialization.c
Comment 24 Stef Walter 2014-07-23 14:26:27 UTC
Review of attachment 281435 [details] [review]:

Added comment.
Comment 25 Colin Walters 2014-07-23 14:48:16 UTC
But *why* is it broken?  Is the GVariant encoding of doubles different from DBus?

Something to do with alignment? 

dbus_type_is_fixed() definitely returns TRUE for DBUS_TYPE_DOUBLE.
Comment 26 Stef Walter 2014-07-23 16:17:19 UTC
(In reply to comment #25)
> But *why* is it broken?  Is the GVariant encoding of doubles different from
> DBus?
> 
> Something to do with alignment? 

Ryan probably knows better, but see https://git.gnome.org/browse/glib/tree/gio/gdbusmessage.c#n2309
Comment 27 Allison Karlitskaya (desrt) 2014-07-24 09:58:16 UTC
Created attachment 281566 [details] [review]
Properly fix encoding of double arrays

It turns out that this bug actually would (sometimes) impact any sort of
fixed-sized array with an alignment requirement of 8 due to incorrectly
counting the alignment inserted between the (aligned 4) array length and
the actual data.

Fix this properly and remove the exception for doubles.
Comment 28 Lars Karlitski 2014-07-24 12:53:38 UTC
Review of attachment 281566 [details] [review]:

Seems correct to me.
Comment 29 Colin Walters 2014-07-24 13:31:48 UTC
Ok, and that bug would cause us to write too long of an array length.  

Thanks a lot for fixing this!