]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bus: Reduce sd_bus_message size by 9.9% by dropping offset bookkeeping
authorChris Down <chris@chrisdown.name>
Sun, 2 Aug 2026 22:43:20 +0000 (15:43 -0700)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 3 Aug 2026 04:48:05 +0000 (13:48 +0900)
sd_bus_message carries an array of header field offsets and a counter,
but their only reader was part of the D-Bus v2/GVariant sealing path
removed in 0dd487681505 ("sd-bus: drop D-Bus version 2 format support").

There are three remaining callers of message_extend_fields(), for
SD_BUS_MESSAGE_HEADER_DESTINATION, _PATH, and _INTERFACE, and all of
them pass false for add_offset. The receive path does not populate the
array either, so nothing reads or writes it any more.

Let's drop the two fields and the now unused add_offset argument and
branch.

This reduces sizeof(sd_bus_message) from 792...

    $ gdb -batch build-baseline/test-bus-benchmark \
          -ex 'ptype /o struct sd_bus_message'
                              ...
                              /* 688 |     8 */ usec_t timeout;
                              /* 696 |    80 */ size_t header_offsets[10];
                              /* 776 |     4 */ unsigned int n_header_offsets;
                              /* XXX  4-byte hole */
                              /* 784 |     8 */ uint64_t read_counter;
                              /* total size (bytes):  792 */

to 704 bytes:

    $ gdb -batch build-patched/test-bus-benchmark \
          -ex 'ptype /o struct sd_bus_message'
                              ...
                              /* 688 |     8 */ usec_t timeout;
                              /* 696 |     8 */ uint64_t read_counter;
                              /* total size (bytes):  704 */

On Fedora 43 aarch64 with glibc 2.42, the usable allocation for a
method-call message falls from 808 to 728 bytes, a reduction of 9.9%.

In my tests, retaining 400,000 method-call messages reduces in median
peak RSS from 363M to 332M.

Using `test-bus-benchmark chart direct 500ms` across message sizes from
1 byte to 2 MiB one can also see things are around 1% faster, which is
another nice incidental boost.

src/libsystemd/sd-bus/bus-message.c
src/libsystemd/sd-bus/bus-message.h

index a719253fa73e6a696ecc507c669d51e726e5d487..09286f43337cfdba4650cecd81bcaffb15a8e606 100644 (file)
@@ -142,7 +142,7 @@ static sd_bus_message* message_free(sd_bus_message *m) {
         return mfree(m);
 }
 
-static void* message_extend_fields(sd_bus_message *m, size_t sz, bool add_offset) {
+static void* message_extend_fields(sd_bus_message *m, size_t sz) {
         void *op, *np;
         size_t old_size, new_size, start;
 
@@ -195,13 +195,6 @@ static void* message_extend_fields(sd_bus_message *m, size_t sz, bool add_offset
 
         m->free_header = true;
 
-        if (add_offset) {
-                if (m->n_header_offsets >= ELEMENTSOF(m->header_offsets))
-                        goto poison;
-
-                m->header_offsets[m->n_header_offsets++] = new_size - sizeof(BusMessageHeader);
-        }
-
         return (uint8_t*) np + start;
 
 poison:
@@ -233,7 +226,7 @@ static int message_append_field_string(
         /* Signature "(yv)" where the variant contains "s" */
 
         /* (field id byte + (signature length + signature 's' + NUL) + (string length + string + NUL)) */
-        p = message_extend_fields(m, 4 + 4 + l + 1, false);
+        p = message_extend_fields(m, 4 + 4 + l + 1);
         if (!p)
                 return -ENOMEM;
 
@@ -274,7 +267,7 @@ static int message_append_field_signature(
         /* Signature "(yv)" where the variant contains "g" */
 
         /* (field id byte + (signature length + signature 'g' + NUL) + (string length + string + NUL)) */
-        p = message_extend_fields(m, 4 + 1 + l + 1, false);
+        p = message_extend_fields(m, 4 + 1 + l + 1);
         if (!p)
                 return -ENOMEM;
 
@@ -301,7 +294,7 @@ static int message_append_field_uint32(sd_bus_message *m, uint64_t h, uint32_t x
                 return -EINVAL;
 
         /* (field id byte + (signature length + signature 'u' + NUL) + value) */
-        p = message_extend_fields(m, 4 + 4, false);
+        p = message_extend_fields(m, 4 + 4);
         if (!p)
                 return -ENOMEM;
 
index 94eff878e564803cfd1e66076202e3f7291e0afe..7f4dc29b8df4aadfa16a929b17a2cb08a5ed3fe8 100644 (file)
@@ -126,9 +126,6 @@ typedef struct sd_bus_message {
 
         usec_t timeout;
 
-        size_t header_offsets[_BUS_MESSAGE_HEADER_MAX];
-        unsigned n_header_offsets;
-
         uint64_t read_counter;
 } sd_bus_message;