glib/gvariant: Inline small gvariant data using C99 flexible arrays
Requires !4299 (merged)
Much like the change for small buffers in GBytes
, this hoists the allocation for small GVariant
like int32
, byte
, double
, and more into the GVariant
using C99 flexible arrays for suffix data.
Previously, all GVariants would allocate a GBytes for the buffered contents. This presents a challenge for small GVariant type created during the building process of GVariantBuilder as that results in an allocation for the GVariant, GBytes, and the byte buffer.
Recent changes for GBytes may reduce those 3 allocations to 2, but even that is quite substantial overhead for a 32-bit integer.
This changeset switches GVariant to use g_new/g_free allocators instead of g_slice_new/free. When benchmarked alone, this presented no measurable difference in overhead with the standard glibc allocator.
With that change in place, allocations may then become variable in size to contain small allocations at the end of the GVariant reducing things to a single allocation (plus the GVariantTypeInfo reference).
The size of GVariant is already 1 cacheline @ 64-bytes on x86_64. This uses that to guarantee our alignment of data maintains the 8-bytes guarantee of GVariant, and also extends it to match malloc().
On 32-bit systems, we are similarly aligned but reduce the amount we will inline to 32 bytes so we have a total of 1 cacheline.
This is all asserted at compile-time to enforce the guarantee.
In the end, this changeset reduces the wallclock time of building many GVariant in a loop using GVariantBuilder by 10% beyond the 10% already gained through GBytes doing the same thing.