Commit graph

1456 commits

Author SHA1 Message Date
Andreas Kling
e0b32b1863 LibJS: Use premade shape when creating mapped arguments objects
Knocks out a 0.4% profile item on Speedometer 3.
2025-04-19 01:14:02 +02:00
Ali Mohammad Pur
76f5dce3db LibRegex: Flatten capture group list in MatchState
This makes copying the capture group COWVector significantly cheaper,
as we no longer have to run any constructors for it - just memcpy.
2025-04-18 17:09:27 +02:00
Andreas Kling
d8188c9f14 LibJS+LibWeb: Add JS::Object::fast_is<T> helpers for some LibWeb types
These are slightly unfortunate as we're crossing the library boundary,
but there's precedent with Object::is_dom_node(), and these are just
knocking down a few more items that were showing up in profiles.
2025-04-18 14:45:56 +02:00
Andreas Kling
f35069d63b LibJS+LibWeb: Add fast_is<T> helpers for Realm::HostDefined class family 2025-04-18 14:45:56 +02:00
Andreas Kling
a9e415b3c4 LibJS+LibWeb: Add fast_is<T> helpers for HTML::Script class family 2025-04-18 14:45:56 +02:00
Andreas Kling
84626c7db2 LibJS: Add a bunch of fast_is<T> helpers for commonly checked types
Based on what was hitting dynamic_cast<T> on Speedometer.
2025-04-18 14:45:56 +02:00
Andrew Kaster
c471faee10 LibJS: Launder const in the parser where required with strict RefPtrs
These places should be updated to not require this hackery, but pulling
on this thread involves touching almost every method in the parser.
2025-04-16 10:41:44 -06:00
Andrew Kaster
59b1fb23a9 LibJS: Remove unused InstructionStreamIterator::source_code getter 2025-04-16 10:41:44 -06:00
Andreas Kling
81d4ed27d8 LibJS: Add cache for the string "[object Object]"
This is very frequently returned by Object.prototype.toString(),
so we benefit from caching it instead of recreating it every time.

Takes Speedometer2.1/EmberJS-Debug-TodoMVC from ~4000ms to ~3700ms
on my M3 MacBook Pro.
2025-04-15 13:08:27 +02:00
Andreas Kling
e8c351505e LibJS: Use premade shape when creating unmapped arguments objects
Takes Speedometer2.1/EmberJS-Debug-TodoMVC from ~4500ms to ~4000ms
on my M3 MacBook Pro.
2025-04-15 13:08:27 +02:00
Timothy Flynn
16559002bf LibJS: Fully qualify use of js_undefined in TRY_OR_REJECT macro
This allows this macro to be used in LibWeb.
2025-04-14 17:43:11 -04:00
Andreas Kling
5308d77600 LibRegex: Don't use Optional<T> inside regex::Match
This prevented Match from being trivially copyable, which we want it to
be for fast Vector copying.
2025-04-14 17:40:13 +02:00
Andreas Kling
54edf29f1b LibRegex: Make Match::capture_group_name an index into the string table
This removes another Match member that required destruction. The "API"
for accessing the strings is definitely a bit awkward. We'll think of
something nicer eventually.
2025-04-14 17:40:13 +02:00
Andreas Kling
6db20a9453 LibJS: Simplify ECMAScriptFunctionObject.[[Realm]] slot handling
Our engine already keeps track of the home realm for all objects.
This is stored in Shape::realm(). We can use that instead of having
a dedicated member in ESFO for the same pointer.

Since there's always a home realm these days, we can also remove some
outdated fallback code from the days when having a realm was not
guaranteed due to LibWeb shenanigans.
2025-04-12 11:07:48 +02:00
Andreas Kling
e4941a36b0 LibJS: Remove unused struct NativeStackFrame 2025-04-12 11:07:48 +02:00
Andreas Kling
d78e3590d5 LibJS: Don't convert to UTF-8 in order to compare two UTF-16 strings
If we have two PrimitiveString objects that are both backed by UTF-16
data, we don't have to convert them to UTF-8 for equality checking.
Just compare the underlying UTF-16 data. :^)
2025-04-12 11:07:48 +02:00
Andreas Kling
e80d1c1a86 LibJS: Add fast_is<T> for JS::Array (array exotic objects)
Nukes a 0.3% profile item on Speedometer 2.1.
2025-04-12 11:07:48 +02:00
Andreas Kling
4a5863bcdb LibJS: Remove unnecessary FunctionObject::name() virtual
This allows us to remove the BoundFunction::m_name field, which we
were initializing with a formatted FlyString on every function binding,
despite never using it for anything.
2025-04-10 04:01:00 +02:00
Andreas Kling
fc111537bb LibJS: Move Value::to_i32() and to_u32() back out-of-line
While good on arm64, this appears to have angered the x86_64 benchmark
runner, so let's just put them back out-of-line.
2025-04-10 00:33:54 +02:00
Andreas Kling
8c8023465b LibJS: Make use of arm64 FJCVTZS instruction if available
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
FJCVTZS (Floating-point Javascript Convert to Signed fixed-point,
rounding toward Zero) does exactly what we need for ToInt32 in the
JavaScript specification.

This isn't world-changing, but it does give a ~2% boost on compute-
heavy benchmarks like JetStream, so we should obviously use it.
2025-04-09 22:06:49 +02:00
Andreas Kling
938b1e91fe LibJS: Inline the fast path of Value::to_i32() and simplify to_u32()
The fast path of to_i32() can be neatly inlined everywhere, and we still
have to_i32_slow_case() for non-trivial conversions.

For to_u32(), it really can just be implemented as a static cast to i32!
2025-04-09 22:06:49 +02:00
Andreas Kling
4e9bc0a437 LibJS: Use a premade shape for NativeFunction with length and name
Some checks are pending
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
~2% of the Speedometer 2.1 profile was just repeatedly performing the
shape transitions to add these two properties. We can avoid all that
work by caching a premade shape.
2025-04-09 07:22:01 +02:00
Andreas Kling
dbf6f7944e LibJS: Remove unused prototype parameter for NativeFunction::create() 2025-04-09 07:22:01 +02:00
Timothy Flynn
f070264800 Everywhere: Remove sv suffix from format string literals
This prevents the compile-time checks that would catch errors in the
format invocation (which would usually lead to a runtime crash).
2025-04-08 20:00:18 -04:00
Timothy Flynn
d5222e9bba LibJS: Do not generate a format string in Number.prototype.toFixed
We can use the placeholder syntax to specify the precision dynamically.
Note that `fraction_digits` is a double, which we do not support as a
precision argument. It's safe to cast to an integer here because we
guaranteed above that the value is in the range [0, 100], and is not
fractional.
2025-04-08 20:00:18 -04:00
Timothy Flynn
64d290447c LibCore+LibJS+LibWasm: Always use a real format string
It's generally considered a security issue to use non-format string
literals. We would likely just crash in practice, but let's avoid the
issue altogether.
2025-04-08 20:00:18 -04:00
Andreas Kling
6362ec6f3d LibJS: Stop passing StringView literals as format strings
This was preventing the format string checks from running, which would
have caught a bug I was about to introduce.
2025-04-08 18:52:35 +02:00
Andreas Kling
4593e19bcf LibJS: Make class-specific members of ESFO lazily allocated
We don't need the [[Fields]] and [[PrivateMethods]] slots for most ESFO
instances, so let's reduce their impact on class size!

This shrinks ESFO from 200 bytes to 160 bytes, allowing more allocations
before we have to collect garbage.
2025-04-08 18:52:35 +02:00
Andreas Kling
2a9b6f1d97 LibJS: Move computation out of the ECMAScriptFunctionObject constructor
We were doing way too much computation every time an ESFO was
instantiated. This was particularly sad, since the results of these
computations were identical every time!

This patch adds a new SharedFunctionInstanceData object that gets
shared between all instances of an ESFO instantiated from some kind of
AST FunctionNode.

~5% speedup on Speedometer 2.1 :^)
2025-04-08 18:52:35 +02:00
Andreas Kling
4209b18b88 LibJS: Add ECMAScriptFunctionObject::create_from_function_node() helper
This gives us a shared entry point for every situation where we
instantiate a function based on a FunctionNode from the AST.
2025-04-08 18:52:35 +02:00
Andreas Kling
ef4e7b7945 LibJS: Make JS parser emit accurate this insights for constructors
This way we don't have to handle it when instantiating the constructor.
2025-04-08 18:52:35 +02:00
Andreas Kling
9c0b185ab8 LibJS: Don't track "last result" of ScopeNode if we don't need it
This prevents unnecessary bytecode register allocation.
2025-04-08 18:52:35 +02:00
Andreas Kling
c845c90e98 LibJS: Avoid GC::RootVector allocations in {Super,}CallWithArgumentArray
We can use the Interpreter::allocate_argument_values() mechanism for
this and avoid creating a temporary RootVector for every such call.
2025-04-08 18:52:35 +02:00
Andreas Kling
5cdbb8b140 LibJS: Remove unused this value from CallConstruct instruction
There's no `this` value prior in the caller context, and this was never
actually used by CallConstruct.
2025-04-08 18:52:35 +02:00
Timothy Flynn
ccf03316fa LibJS: Convert FilterLocales and CoerceOptionsToObject to GC::Ref
These never return nullptr.
2025-04-08 06:50:40 -04:00
Timothy Flynn
2729c88154 LibJS: Migrate remaining Intl objects to use ResolveOptions
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/75e67db
2025-04-08 06:50:40 -04:00
Timothy Flynn
3f55240a8e LibJS: Migrate Intl.DisplayNames to use ResolveOptions
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/5eafacd
2025-04-08 06:50:40 -04:00
Timothy Flynn
636e214326 LibJS: Migrate Intl.Collator to use ResolveOptions
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/f822dc1
2025-04-08 06:50:40 -04:00
Timothy Flynn
e40881ebb8 LibJS: Migrate Intl.DateTimeFormat to use ResolveOptions
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/9e4c922
2025-04-08 06:50:40 -04:00
Timothy Flynn
d3332d51b5 LibJS: Add an AO to implement Intl constructor locale resolution
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/9e4c922
2025-04-08 06:50:40 -04:00
Timothy Flynn
62793b1bd8 LibJS: Define constructor slots for describing how to read options
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/a2beb66

We implement this change by introducing a virtual interface that all
Intl "service" objects must implement. A future patch will make use of
the virtualized RelevantExtensionKeys and ResolutionOptionDescriptors
accessors, and we will need to be able to use those slots from a generic
instance type.
2025-04-08 06:50:40 -04:00
Timothy Flynn
19ce186f97 LibJS: Define Intl.Locale's LocaleExtensionKeys more declaratively
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/3898acf
2025-04-08 06:50:40 -04:00
Timothy Flynn
75fce14f09 LibJS: Rename Intl.Locale's RelevantExtensionKeys to LocaleExtensionKeys
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/e2a5747
2025-04-08 06:50:40 -04:00
Timothy Flynn
680f028bb8 LibJS: Simplify Intl.Collator sensitivity / ignorePunctuation defaults
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/23e2e92
2025-04-08 06:50:40 -04:00
Timothy Flynn
b81d0d3261 LibJS: Ensure Intl.Collator instances have [[Numeric]] and [[CaseFirst]]
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/243ec38
2025-04-08 06:50:40 -04:00
Timothy Flynn
0f1fa38442 LibJS: Update spec link for FormatNumericToString AO
This is an editorial change in the ECMA-402 spec. See:
https://github.com/tc39/ecma402/commit/e3f7260

Note the other changes in this commit do not apply to our implementation
as we defer to ICU for the affected steps.
2025-04-08 06:50:40 -04:00
Timothy Flynn
0a256b0a9a AK+Everywhere: Change StringView case conversions to return String
There's a bit of a UTF-8 assumption with this change. But nearly every
caller of these methods were immediately creating a String from the
resulting ByteString anyways.
2025-04-07 17:44:38 +02:00
Luke Wilde
25e343464d LibJS: Cache length identifier for GetLengthWithThis
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
We cached the length identifier for GetLength, but not
GetLengthWithThis. This caused an `has_value()` verification failure
when accessing super.length. Found by Fuzzilli.
2025-04-07 14:40:48 +02:00
Viktor Szépe
b4b8d85251 LibWeb+LibJS+Tests: Fix typos - act I 2025-04-07 11:22:13 +01:00
Andreas Kling
e695dc1405 LibJS: Don't make Bytecode::Operand::Type an u8 outside of aarch64
This is a slightly mystified attempt to recover the performance
regression seen on our JS benchmark runner after 3c2a2bb39f
and c7bba505ea.

With this change, c7bba505ea is effectively reverted from the
perspective of x86_64.
2025-04-06 20:12:58 +02:00