This commit changes `AK::TypeErasedParameter` to store integer,
floating-point and string types as well as characters and booleans
directly instead of through a type-erased `void const*`.
This is advantageous for binary size:
- The compiler no longer needs to push both the parameter value and a
pointer to it to the stack (which contains the argument array);
storing just the value is enough.
- Instead of instantiating `__format_value` for these types and taking
its address (which generates a GOT entry and an ADRP+LDR pair in
assembly), we just store a constant `TypeErasedParameter::Type` value.
- The biggest saving comes from the fact that we used to instantiate a
distinct `__format_value` for each length of string literal. For
LibJS, this meant 69 different functions! We can now just store them
as a `char const*`.
I opted to use a manual tagged union instead of `Variant`: the code
wouldn't be much shorter if we used a `Variant` since we'd have to
handle converting the standard integer types to `u64`/`i64` and custom
types to the type erased wrapper via explicit constructors anyway. And
compile time overhead is smaller this way.
This gives us some nice binary size savings (numbers are from arm64
macOS LibJS):
FILE SIZE VM SIZE
-------------- --------------
+52% +10.3Ki +52% +10.3Ki [__TEXT]
+5.2% +768 +5.2% +768 [__DATA_CONST]
-0.0% -7 -0.0% -7 __TEXT,__cstring
-3.0% -144 -3.0% -144 __TEXT,__stubs
-1.2% -176 -1.2% -176 Function Start Addresses
-11.6% -432 -11.6% -432 Indirect Symbol Table
-1.0% -448 -1.0% -448 Code Signature
-18.1% -768 -18.1% -768 __DATA_CONST,__got
-0.8% -6.83Ki -0.8% -6.83Ki Symbol Table
-1.0% -11.2Ki -1.0% -11.2Ki String Table
-0.9% -26.1Ki -0.9% -26.1Ki __TEXT,__text
-7.2% -20.9Ki -9.6% -28.9Ki [__LINKEDIT]
-1.0% -56.0Ki -1.1% -64.0Ki TOTAL
We now explicitly enabling support for the minimum libraries needed
to build and run the AK testsuite. 81/82 tests are running and
passing. The exception is LexicalPath, as some path behaviour on
Windows is different than Unix, so the current tests will have lots of
platform specific failures. The implementer of LexicalPathWindows
recommended windows-specific tests here, so I will do that in a
follow up.
This gives us a more human-looking serialization of numbers by default,
and in case a fixed number of decimal digits is actually wanted, we
still have the 'f' specifier.
Previously, heap-allocated `CallableWrapper` objects were destroyed in a
very roundabout way: `AK::Function` would call a virtual `destroy()`
method, which then invoked delete manually. This was unnecessary, since
`CallableWrapper` already has a virtual destructor — deleting it through
a `CallableWrapperBase*` correctly calls the closure's destructor.
This fixes GCC `-Wfree-nonheap-object` false positive warnings (#4721)
and coincidentally removes 8 KB of vtable entries (and the corresponding
relative relocations) from LibJS.
We added a weak symbol to AK to support overriding the default assertion
handler for test cases. However, on macOS, we need to explicitly mark
the possibly-null symbol as 'it's ok for this to be undefined'.
When AK is a shared library, the flag can be applied to the link step of
the dylib, but when it's a static library, we need to apply it to the
executable that links against it.
When a `VERIFY()` assertion fails `ak_verification_failed` is invoked
which means the program will invoke `__builtin_trap` and immediately
quit. But with this change we have now allowed for an optional hook
into `ak_*_failed` that lets us perform some custom
action before program exits. This foundation is what we will
(ab)use to implement death tests without the process cloning
CrashTest infrastructure.
This commit adds support in AK/Random for a high quality RNG on windows.
This requires moving the code into a cpp file not to spread windows
headers around.
We were already silencing it at the site of the delete call, but gcc in
distribution mode is more aggressive about inlining and still sees a
delete that it doesn't like.
This is a remnant from SerenityOS. Let's avoid confusion as to why we
negate errno when we call Error::from_syscall just to negate it again
when we store the error code.
This commit makes windows errors store the code instead of being a
formatted string literal. This will allow comparing against the error,
and checking what it is. The formatting is now done in the formatter,
and moved to an implementation file to avoid polluting headers with
windows.h. The kind of the error is now determined by an enum Kind which
will allow matching against the error kind.
Co-Authored-By: Andrew Kaster <andrew@ladybird.org>
By piggybacking on the already-optimized implementation in
StringBuilder, we can get simdutf for the AllowInvalidCodeUnits::Yes
case here as well.
1.03x speedup on Speedometer's TodoMVC-jQuery.
At this point, I've repeatedly felt the desire to be able to log
stacktraces to be able to see more easily what kind of call-sites exist
for a given piece of code. So this commit exposes `dump_backtrace()` in
the header so it can be used for this purpose.
We were previously unable to use simdutf for base64 decoding operations
other than "loose". Upstream has added support for the "strict" and
"stop-before-partial" operations, so let's make use of them!
Instead of going through String::formatted(), we now have a specialized
code path for base-10 serialization directly to UTF-8.
This is roughly 5-10x faster than the previous implementation, depending
on how many digits we end up outputting.
1.07x speedup on MicroBench/for-in-indexed-properties.js
NonnullRefPtr almost always has a non-null pointer internally, that's
what the class is for, after all! The one edge case where it has null
internally is after you move() it. But it's always a bug to use an
NNRP after moving from it, and we have clang-tidy yelling at us if
that ever happens.
Demoting this removes a gazillion overly paranoid null checks.
For the slight cost of counting code points when converting between
encodings and a teeny bit of memory, this commit adds a fast path for
all-happy utf-16 substrings and code point operations.
This seems to be a significant chunk of time spent in many regex
benchmarks.
This will change behaviour for moved-from `Optional<T>`s, since they
will now no longer clear their value if `T` is trivial. However, a
moved-from value should be considered to be in an unspecified state.
Use `Optional<T>::clear` or `Optional<T>::release_value` instead.
If a type is non-move constructible but move assignable,
its container type may still be move assignable.
Similairly, if a type is non-copy constructible but copy assignable,
its container type may still be copy assignable.
There are parts of the codebase where properly const-correctifying the
the code would be a giant spaghetti mess, so add this loud workaround
to defer the refactoring for later.