Shannon Booth
29ac95a3e2
LibJS: Remove unused VM::on_call_stack_emptied
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-05-10 08:19:03 -04:00
Aliaksandr Kalenik
6530f55f34
LibJS: Cache rejected/fulfilled callbacks in AsyncFunctionDriverWrapper
...
Saves us two NativeFunction allocations per each `await`.
With this change, following function goes 80% faster on my computer:
```js
(async () => {
const resolved = Promise.resolve();
for (let i = 0; i < 5_000_000; i++) {
await resolved;
}
})();
```
2025-05-09 12:30:15 +02:00
Aliaksandr Kalenik
4c789ac689
LibJS: Skip iteration result allocation in AsyncFunctionDriverWrapper
...
- Create less GC pressure by making each `await` in async function skip
iteration result object allocation.
- Skip uncached `Object::get()` calls to extract `value` and `done` from
the iteration result object.
With this change, following function goes 30% faster on my computer:
```js
(async () => {
const resolved = Promise.resolve();
for (let i = 0; i < 5_000_000; i++) {
await resolved;
}
})();
```
2025-05-09 12:30:15 +02:00
Shannon Booth
19bf897116
LibJS: Avoid roundtrip through Value for comparison bytecode evaluation
...
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
1.1x speedup on strictly-equals-object.js
2025-05-08 20:39:29 +02:00
Andreas Kling
74f133293d
LibJS: Avoid redundant ExecutionContext allocation for bound functions
...
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 creating a second ExecutionContext in BoundFunction.[[Call]],
we now implement BoundFunction::get_stack_frame_size() and combine
information from the target + the bound arguments list.
This allows BoundFunction.[[Call]] to reuse the already-established
ExecutionContext for the callee.
1.20x speedup on MicroBench/bound-call-04-args.js
2025-05-07 13:20:41 +02:00
Aliaksandr Kalenik
db480b1f0c
LibJS: Preserve information about local variables declaration kind
...
This is required for upcoming change where we want to emit ThrowIfTDZ
for assignment expressions only for lexical declarations.
2025-05-06 12:06:23 +02:00
Andreas Kling
183c847c80
LibJS: Cache PutById to setters in the prototype chain
...
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
This is *extremely* common on the web, but barely shows up at all in
JavaScript benchmarks.
A typical example is setting Element.innerHTML on a HTMLDivElement.
HTMLDivElement doesn't have innerHTML, so it has to travel up the
prototype chain until it finds it.
Before this change, we didn't cache this at all, so we had to travel
the prototype chain every time a setter like this was used.
We now use the same mechanism we already had for GetBydId and cache
PutById setter accesses in the prototype chain as well.
1.74x speedup on MicroBench/setter-in-prototype-chain.js
2025-05-05 15:21:43 +02:00
Andreas Kling
bf1b754e91
LibJS: Optimize reading known-to-be-initialized var
bindings
...
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
`var` bindings are never in the temporal dead zone (TDZ), and so we
know accessing them will not throw.
We now take advantage of this by having a specialized environment
binding value getter that doesn't check for exceptional cases.
1.08x speedup on JetStream.
2025-05-04 02:31:18 +02:00
Andreas Kling
570d1e8811
LibJS: Use PrimitiveString more instead of Utf16String in String code
...
This avoids a whole lot of unnecessary roundtrips from UTF8 <=> UTF16.
2025-05-03 20:01:20 +02:00
Andreas Kling
98fef16972
LibJS: Use PrimitiveString more instead of Utf16String in RegExp code
...
PrimitiveString has an internal UTF-16 string cache anyway, and so this
actually avoids repeatedly converting between UTF-8 and UTF-16.
2025-05-03 20:01:20 +02:00
Timothy Flynn
8a80ff7b3b
AK+LibJS: Use simdutf for all base64 operations
...
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!
2025-05-03 11:21:10 -04:00
Shannon Booth
e476d21ed0
LibJS: Add and use PrimitiveString::length_in_utf16_code_units
...
I was investigating an optimization in this area, and while it
didn't seem to have a noticable improvement, it still seems
useful to apply this change.
2025-05-03 16:18:47 +02:00
Andreas Kling
0ef6444824
LibJS: Replace some use of ByteString with String
...
1.19x speedup on MicroBench/for-in-indexed-properties.js
2025-05-03 08:08:04 +02:00
Aliaksandr Kalenik
6426586052
LibJS: Skip "return" method call while closing built-in iterators
...
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
"return" method is not defined on any of builtin iterators, so we could
skip it, avoiding method lookup.
I measured 10% improvement in array-destructuring-assignment.js micro
benchmark with this change.
2025-05-01 18:17:06 +02:00
Aliaksandr Kalenik
ab52d86a69
LibJS: Allow advancing built-in iterators without result object creation
...
Expose a method on built-in iterators that allows retrieving the next
iteration result without allocating a JS::Object. This change is a
preparation for optimizing for..of and for..in loops.
2025-04-30 20:51:39 +02:00
Timothy Flynn
6b4b7a54de
LibJS: Revert ArrayIterator and RegExpStringIterator to manual iterators
...
This is a normative change in the ECMA-262 spec. See:
de62e8d
This did not actually seem to affect our implementation as we were not
using generators here to begin with. So this patch is basically just
adding spec comments.
2025-04-30 07:29:34 -04:00
Timothy Flynn
4d70f6ce1c
LibJS: Ensure iterator parameter validation closes underlying iterator
...
This is a normative change in the ECMA-262 spec. See:
9552f29
f2bad00
2025-04-29 07:33:08 -04:00
Timothy Flynn
908349f8fe
LibJS: Add a TRY_OR_CLOSE_ITERATOR macro for IfAbruptCloseIterator
...
Behaves just like TRY_OR_REJECT for promises.
2025-04-29 07:33:08 -04:00
Timothy Flynn
568524f8ba
LibJS: Close sync iterator when async wrapper yields rejection
...
This is a normative change in the ECMA-262 spec. See:
ff129b1
2025-04-29 07:33:08 -04:00
Timothy Flynn
15faaeb2bb
LibJS: Remove [[VarNames]] from GlobalEnvironment
...
This is a normative change in the ECMA-262 spec. See:
ed75310
2025-04-29 07:33:08 -04:00
Timothy Flynn
9c85a16aeb
LibJS: Standardize spec prose for Math.sumPrecise
2025-04-29 07:33:08 -04:00
Timothy Flynn
9674210ef8
LibJS: Update spec steps / links for the Float16Array proposal
...
This proposal has reached stage 4 and been merged into the main ECMA-262
spec. See:
d430ace
2025-04-29 07:33:08 -04:00
Timothy Flynn
adf6024805
LibJS: Update spec steps / links for the RegExp.escape proposal
...
This proposal has reached stage 4 and been merged into the main ECMA-262
spec. See:
e2da759
2025-04-29 07:33:08 -04:00
Timothy Flynn
2401764697
LibJS: Update spec steps / links for the JSON modules proposal
...
This proposal has reached stage 4 and been merged into the main ECMA-262
spec. See:
3feb1ba
2025-04-29 07:33:08 -04:00
Timothy Flynn
3867a192a1
LibJS: Update spec steps / links for the import-assertions proposal
...
This proposal has reached stage 4 and been merged into the main ECMA-262
spec. See:
4e3450e
2025-04-29 07:33:08 -04:00
Andreas Kling
a2b7e04da3
LibJS: Defer looking up the realm in ordinary_call_evaluate_body()
...
We don't actually need the realm for normal function calls, so we
can avoid looking it up on the EC stack in that case.
2025-04-29 02:09:35 +02:00
Andreas Kling
0f1be720bb
LibJS: Mark exception path [[unlikely]] in ordinary_call_evaluate_body()
2025-04-29 02:09:35 +02:00
Andreas Kling
58925887ce
LibJS: Inline VM::bytecode_interpreter()
2025-04-29 02:09:35 +02:00
Andreas Kling
35275651e3
LibJS: Skip stack overflow check in ESFO::prepare_for_ordinary_call()
...
We already do a stack overflow check when entering run_bytecode(),
which is the first thing that happens when we actually invoke the ESFO
executable.
2025-04-29 02:09:35 +02:00
Andreas Kling
4d17707b26
LibJS: Store bytecode VM program counter in ExecutionContext
...
This way it's always automatically correct, and we don't have to
manually flush it in push_execution_context().
~7% speedup on the MicroBench/call* tests :^)
2025-04-28 21:12:48 +02:00
Andreas Kling
233097c250
LibJS: Inline part of VM::run_queued_promise_jobs()
...
Most of the time there are no queued promise jobs to run after exiting
a stack frame. By moving the check inline, leaving a function call gets
a measurable speedup in the common case.
2025-04-28 10:39:42 -04:00
Andreas Kling
b4554c01db
LibJS: Mark ESFO path for [[Call]] on a class constructor [[unlikely]]
...
This is an exception path that's not supposed to be called normally,
so let's mark it unlikely.
2025-04-28 10:39:42 -04:00
Andreas Kling
6ec4d0f5ba
LibJS: Mark stack overflow exception code path as [[unlikely]]
...
This is supposed to be exceedingly rare, so a great candidate for
[[unlikely]] annotation.
2025-04-28 10:39:42 -04:00
Andreas Kling
074ca5d5b4
LibJS: Make ESFO::ordinary_call_evaluate_body() return TCO<Value>
...
This matches what the caller wants to return and allows us to simplify
a bunch of logic around returning a value or throwing.
2025-04-28 12:44:49 +02:00
Andreas Kling
670e439e1e
LibJS: Put FLATTEN on ECMAScriptFunctionObject.[[Call]]
...
This makes function calls ~5% faster in micro-benchmarks on my MBP.
Basically free money on the table. Let's take it!
2025-04-28 12:44:49 +02:00
Andreas Kling
d0d87d3aed
LibJS: Demote some overly paranoid VERIFY()s in ESFO [[Call]] flow
2025-04-28 12:44:49 +02:00
Andreas Kling
403ae86fd9
LibJS: Pass VM& to ECMAScriptFunctionObject [[Call]] helpers
...
This avoids fetching the VM from the Cell::private_data() repeatedly.
2025-04-28 12:44:49 +02:00
devgianlu
5f1a30197c
LibCrypto: Remove the concept of invalid big integers
...
This concept is rarely used in codebase and very much error-prone
if you forget to check it.
Instead, make it so that operations that would produce invalid integers
return an error instead.
2025-04-28 12:05:26 +02:00
devgianlu
dd0cced92f
LibJS: Prevent huge memory allocations for bigint left shift
2025-04-28 12:05:26 +02:00
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
...
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
...
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
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