AK: Remove redundant information from TypeErasedFormatParams

The array which contains the actual parameters is always located
immediately after the base `TypeErasedFormatParams` object of
`VariadicFormatParams`. Hence, storing a pointer to it inside a `Span`
is redundant. Changing it to a zero-length array saves 8 bytes.

Secondly, we limit the number of parameters to 256, so `m_size` and
`m_next_index` can be stored in a smaller data type than `size_t`,
saving us another 8 bytes.

This decreases the size of a single-element `VariadicFormatParams` from
48 to 32 bytes, thus reducing the code size overhead of setting up
parameters for `dbgln()`.

Note that [arrays of length zero][1] are a GNU extension, but it's used
elsewhere in the codebase already and is explicitly supported by Clang
and GCC.

[1]: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
This commit is contained in:
Daniel Bertalan 2023-07-08 16:08:21 +02:00 committed by Andreas Kling
parent 281e3158c0
commit aaf1b762ea
Notes: sideshowbarker 2024-07-17 02:37:08 +09:00

View File

@ -10,7 +10,6 @@
#include <AK/AllOf.h>
#include <AK/AnyOf.h>
#include <AK/Array.h>
#include <AK/Error.h>
#include <AK/Forward.h>
#include <AK/Optional.h>
@ -270,14 +269,19 @@ private:
class TypeErasedFormatParams {
public:
ReadonlySpan<TypeErasedParameter> parameters() const { return m_parameters; }
TypeErasedFormatParams(u32 size)
: m_size(size)
{
}
ReadonlySpan<TypeErasedParameter> parameters() const { return { m_parameters, m_size }; }
void set_parameters(ReadonlySpan<TypeErasedParameter> parameters) { m_parameters = parameters; }
size_t take_next_index() { return m_next_index++; }
private:
ReadonlySpan<TypeErasedParameter> m_parameters;
size_t m_next_index { 0 };
u32 m_size { 0 };
u32 m_next_index { 0 };
TypeErasedParameter m_parameters[0];
};
template<typename T>
@ -295,16 +299,16 @@ public:
static_assert(sizeof...(Parameters) <= max_format_arguments);
explicit VariadicFormatParams(Parameters const&... parameters)
: m_data({ TypeErasedParameter { &parameters, TypeErasedParameter::get_type<Parameters>(), __format_value<Parameters> }... })
: TypeErasedFormatParams(sizeof...(Parameters))
, m_parameter_storage { TypeErasedParameter { &parameters, TypeErasedParameter::get_type<Parameters>(), __format_value<Parameters> }... }
{
constexpr bool any_debug_formatters = (is_debug_only_formatter<Formatter<Parameters>>() || ...);
static_assert(!any_debug_formatters || allow_debug_formatters == AllowDebugOnlyFormatters::Yes,
"You are attempting to use a debug-only formatter outside of a debug log! Maybe one of your format values is an ErrorOr<T>?");
this->set_parameters(m_data);
}
private:
Array<TypeErasedParameter, sizeof...(Parameters)> m_data;
TypeErasedParameter m_parameter_storage[sizeof...(Parameters)];
};
// We use the same format for most types for consistency. This is taken directly from