Commit graph

976 commits

Author SHA1 Message Date
devgianlu
a019efb24b LibCrypto+LibJS: Remove {Signed,Unsigned}BigInteger to_base_deprecated
Use `to_base` instead.
2025-04-28 12:05:26 +02:00
Andreas Kling
a05be67e4a LibJS: Let invokers (callers) of [[Call]] allocate ExecutionContext
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
Instead of letting every [[Call]] implementation allocate an
ExecutionContext, we now make that a responsibility of the caller.

The main point of this exercise is to allow the Call instruction
to write function arguments directly into the callee ExecutionContext
instead of copying them later.

This makes function calls significantly faster:
- 10-20% faster on micro-benchmarks (depending on argument count)
- 4% speedup on Kraken
- 2% speedup on Octane
- 5% speedup on JetStream
2025-04-28 01:23:56 +02:00
Andreas Kling
93788f8057 LibJS: Add parentheses to ALLOCATE_EXECUTION_CONTEXT_ON_NATIVE_STACK()
Just to stop clang-tidy from complaining about it every time.
2025-04-28 01:23:56 +02:00
Shannon Booth
9e44d86915 LibJS: Remove value_or from JS::Value
Some checks are pending
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
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
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
This is no longer used after 3cf5053.
2025-04-27 11:14:54 -04:00
Timothy Flynn
317cf65eb0 LibJS: Avoid naming conflict between Object's and Error's is_error
Object defines an is_error virtual method to be overridden by Error for
fast-is. This is the same name as the Error.isError constructor method.
Rename the former to avoid conflicts, as GCC 15 just started warning on
this.
2025-04-26 09:04:45 -06:00
Shannon Booth
5290ebfe19 LibJS: Switch Agent [[CanBlock]] slot to a enum member
It turns out it was a mistake to make this a virtual since
ServiceWorkerAgents are effectively the exact same as
DedicatedWorkerAgents and SharedWorkerAgents just with [[CanBlock]]
set to false.
2025-04-25 14:07:51 +02:00
Shannon Booth
7dd7e5b438 LibJS+LibWeb: Defer initialization of the Agent after VM constructor
This helps unwind a niggly depedency where the VM owns and constructs
the Heap and the Agent. But the agent wants to have customized
construction that depends on the heap. Solve this by defering
the initialization of the Agent to after we have constructed the
VM and the heap.
2025-04-25 14:07:51 +02:00
Shannon Booth
8263a9863f LibJS+LibWeb: Do not return error from VM::create
This never returns an error to propogate, also allowing ErrorOr
to be removed from creating the main thread VM.
2025-04-25 14:07:51 +02:00
aplefull
223c9c91e6 LibJS: Implement rawJSON and isRawJSON functions
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
2025-04-24 09:33:49 -04:00
Andrew Kaster
9bae24cc4a LibJS: Add and use ValidateNonRevokedProxy AO
This refactor is from two editorial changes to the spec from a while
back.

44d1cae2b2
21ffeee869
2025-04-24 10:37:39 +02:00
Aliaksandr Kalenik
e48645c83f LibJS: Cache arguments span in ExecutionContext
Allows us to avoid doing math in ExecutionContext::argument()
2025-04-24 10:30:52 +02:00
Aliaksandr Kalenik
a329868c1b LibJS: Allocate ExecutionContext memory using alloca() when possible
This should be faster than heap allocation. However, heap allocation is
still necessary in some cases, such as with generators and async
functions.
2025-04-24 10:30:52 +02:00
Aliaksandr Kalenik
5a92929282 LibJS: Put vector of regs+consts+locals+args in tail of ExecutionContext
By doing that we avoid doing separate allocation for each such vector,
which was really expensive on js heavy websites. For example this change
helps to get EC allocation down from ~17% to ~2% on Google Maps. This
comes at cost of adding extra complexity to custom execution context
allocator, because EC no longer has fixed size and we need to maintain
a list of buckets.
2025-04-24 10:30:52 +02:00
Aliaksandr Kalenik
c6cd03d7ca LibJS+LibWeb: Join arguments into vector of registers+constants+locals
This is better because:
- Better data locality
- Allocate vector for registers+constants+locals+arguments in one go
  instead of allocating two vectors separately
2025-04-24 10:30:52 +02:00
Aliaksandr Kalenik
80a8040794 LibJS+LibWeb: Calculate count of regs+consts+locals before EC allocation
This is a preparation step before joining arguments vector into vector
of registers+constants+locals.
2025-04-24 10:30:52 +02:00
Ali Mohammad Pur
eea81738cd AK+Everywhere: Recognise that surrogates in utf16 aren't all that common
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.
2025-04-23 07:56:02 -06:00
Jonne Ransijn
ca33899370 LibJS: Allow Optional<Completion> to be used in constant expressions 2025-04-22 21:19:31 -06:00
Jonne Ransijn
c63a8c0334 LibJS: Allow Optional<Value> to be used in constant expressions 2025-04-22 21:19:31 -06:00
Shannon Booth
e124ef52ee LibJS+LibWeb: Set [[CanBlock]] false to Agent for window agent
similar-origin window agents have the [[CanBlock]] flag set to false.
Achieve this by hooking up JS's concept with an agent to HTML::Agent.
For now, this is only hooked up to the similar-origin window agent
case but should be extended to the other agent types in the future.
2025-04-22 11:50:35 -04:00
Andreas Kling
669b1131ad LibJS: Streamline CreateMappedArgumentsObject [[ParameterMap]] creation
Instead of using the more generic define_native_accessor() here,
we poke directly at indexed property storage for the parameter map.

We can also construct the NativeFunction objects directly, without
giving them names like "get 0" etc, since these are not observable
by userspace.

Finally, by using default property attributes (not observable anyway),
we get simple indexed storage instead of generic (hash map) storage.
2025-04-20 18:43:11 +02:00
Andreas Kling
5290dcf650 LibJS: Don't create a GC::Function for every JS::NativeFunction
Instead, let JS::NativeFunction store the AK::Function directly, and
take care of conservatively marking its captured data.

This avoids an extra GC allocation for every JS::NativeFunction.
2025-04-20 18:43:11 +02:00
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
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
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
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
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:
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:
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:
f822dc1
2025-04-08 06:50:40 -04:00