Commit Graph

71 Commits

Author SHA1 Message Date
Andreas Kling
0c5e4ebc18 LibJS: Add InterpreterStack bump allocator for execution contexts
Add a managed bump allocator backed by an 8 MB mmap region to replace
alloca-based execution context allocation. Pages are committed on
demand by the OS, so only the memory actually touched is resident.

The InterpreterStack is stored as a member of VM and provides simple
LIFO allocation and deallocation of ExecutionContext frames.
2026-03-04 18:53:12 +01:00
CountBleck
d44b239621 LibJS: Crudely implement growable SharedArrayBuffers
We treat any mention of [[ArrayBufferByteLengthData]] and related
atomic operations as FIXMEs to be fixed at a later date. We also add the
HostGrowSharedArrayBuffer abstract operation, which will be overridden
by LibWeb to grow shared WebAssembly memories.
2026-01-04 07:47:55 +01:00
Andreas Kling
72886c4999 LibJS: Don't iterate finalization registry cleanup jobs in silly way
Pop jobs from the end of the vector instead of from the front. This
avoids shifting all the memory around. Also use GC::Ref instead of Ptr.
2025-12-25 20:21:37 +01:00
Andreas Kling
ba6e7083bb LibJS: Make VM::the() be ALWAYS_INLINE
This was already getting optimized properly in distribution builds
but release builds (on macOS at least) failed to inline it unless we
do this.
2025-12-11 14:34:45 -06:00
Andreas Kling
938faff2c6 LibJS: Mark all throw_completion() helpers COLD
Throwing an exception should always be the rare case.
2025-12-09 21:44:13 -06:00
Andreas Kling
8289b24a7e LibJS: Introduce VM::the() and use it instead of caching VM pointer
In our process architecture, there's only ever one JS::VM per process.
This allows us to have a VM::the() singleton getter that optimizes
down to a single global access everywhere.

Seeing 1-2% speed-up on all JS benchmarks from this.
2025-12-09 11:58:39 -06:00
Andreas Kling
2d76e21cfd LibJS: Don't use GC::Root unnecessarily in Error stack traces
This was causing a fair bit of root registration churn on pages that
throw lots of errors.

Since there's no need for these pointers to float around freely, we can
just visit them during the mark phase as usual.
2025-11-30 11:53:56 +01:00
Andreas Kling
2492c07430 LibJS: Remove redundant VERIFYs in running_execution_context()
Vector::last() will already verify that the context stack is non-empty.
2025-10-31 08:56:02 +01:00
Andreas Kling
fb05063dde LibJS: Let bytecode instructions know whether they are in strict mode
This commits puts the strict mode flag in the header of every bytecode
instruction. This allows us to check for strict mode without looking at
the currently running execution context.
2025-10-29 21:20:10 +01:00
Rocco Corsi
44d2a74eeb LibJS: Increase the stack limit when ASAN enabled
Linux, x86_64, Sanitizer, GNU runners on GitHub Action fail randomly
with a stack overflow on recursive test called:
Libraries/LibJS/Tests/runtime-error-call-stack-size.js
2025-10-13 09:07:39 -04:00
Andreas Kling
7a2fe53c65 Revert "LibJS: Use HashMap::ensure() in VM string cache helpers"
This reverts commit 5810ddf339.

Appears to have introduced flakiness on WPT.
2025-10-06 12:15:34 +02:00
Andreas Kling
5810ddf339 LibJS: Use HashMap::ensure() in VM string cache helpers
This cuts the number of hash lookups on cache hit from 2 to 1.
2025-10-05 21:44:06 +02:00
Andreas Kling
b691f4c7af LibJS: Add number-to-string cache for numbers < 1000
We are often forced to convert numbers to strings inside LibJS, e.g when
iterating over the property names of an array, but it's also just a very
common operation in general.

This patch adds a 1000-entry string cache for the numbers 0-999 since
those appear to be by far the most common ones we convert.
2025-10-05 21:44:06 +02:00
Timothy Flynn
70db474cf0 LibJS+LibWeb: Port interned bytecode strings to UTF-16
This was almost a no-op, except we intern JS exception messages. So the
bulk of this patch is porting exception messages to UTF-16.
2025-08-14 10:27:08 +02:00
Timothy Flynn
b955c9b2a9 LibJS: Port the Identifier AST (and related) nodes to UTF-16
This eliminates quite a lot of UTF-8 / UTF-16 churn.
2025-08-13 09:56:13 -04:00
Timothy Flynn
0efa98a57a LibJS+LibWeb+WebContent: Port JS::PropertyKey to UTF-16
This has quite a lot of fall out. But the majority of it is just type or
UDL substitution, where the changes just fall through to other function
calls.

By changing property key storage to UTF-16, the main affected areas are:
* NativeFunction names must now be UTF-16
* Bytecode identifiers must now be UTF-16
* Module/binding names must now be UTF-16
2025-08-05 07:07:15 -04:00
ayeteadoe
2e2484257d LibJS: Enable EXPLICIT_SYMBOL_EXPORT and annotate minimum symbol set 2025-07-22 11:51:29 -04:00
ayeteadoe
539a675802 LibJS: Revert Enable EXPLICIT_SYMBOL_EXPORT
This reverts commit c14173f651. We
should only annotate the minimum number of symbols that external
consumers actually use, so I am starting from scratch to do that
2025-07-22 11:51:29 -04:00
Luke Wilde
0cff47828d LibWeb/CSP: Implement the script-src directive 2025-07-09 15:52:54 -06:00
Luke Wilde
3d43462ccd LibJS: Implement the Dynamic Code Brand Checks stage 3 proposal
This is an active proposal at stage 3 of the TC39 proposal process.
See: https://tc39.es/proposal-dynamic-code-brand-checks/
See: https://github.com/tc39/proposal-dynamic-code-brand-checks

This proposal essentially adds support for the TrustedScript type from
the Trusted Types specification to eval and Function. This in turn
pipes support for the type into the CSP hook to check if the CSP allows
dynamic code compilation.

However, it currently doesn't support ShadowRealms, so the
implementation here is a close approximation, using PerformEval as the
basis.
See: https://github.com/tc39/proposal-dynamic-code-brand-checks/issues/19

This is required to support the new function signature for the CSP
hook, and will allow us to slot in Trusted Types support in the future.
2025-07-09 15:52:54 -06:00
ayeteadoe
c14173f651 LibJS: Enable EXPLICIT_SYMBOL_EXPORT 2025-06-30 10:50:36 -06:00
Shannon Booth
7d44640c0f LibJS: Assume is_strict_mode called with running execution context
This should always be invoked when there is an execution context
on the stack.
2025-05-23 03:25:55 +02:00
Shannon Booth
29ac95a3e2 LibJS: Remove unused VM::on_call_stack_emptied 2025-05-10 08:19:03 -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:

https://github.com/tc39/ecma262/commit/4e3450e
2025-04-29 07:33:08 -04:00
Andreas Kling
58925887ce LibJS: Inline VM::bytecode_interpreter() 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
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
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
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
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
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
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
3cf50539ec LibJS: Make Value() default-construct the undefined value
The special empty value (that we use for array holes, Optional<Value>
when empty and a few other other placeholder/sentinel tasks) still
exists, but you now create one via JS::js_special_empty_value() and
check for it with Value::is_special_empty_value().

The main idea here is to make it very unlikely to accidentally create an
unexpected special empty value.
2025-04-05 11:20:26 +02:00
Andreas Kling
0d91363742 LibJS: Remove weird fallback behavior in VM::argument/argument_count
If there's no running execution context, let's just error out in there
instead of returning a weird empty value.
2025-04-05 11:20:26 +02:00
Andreas Kling
c71772126f LibJS: Remove ByteString internals from PrimitiveString
PrimitiveString is now internally either UTF-8, UTF-16, or both.
We no longer convert them to/from ByteString anywhere, nor does VM have
a ByteString cache.
2025-03-28 12:31:40 -04:00
Andreas Kling
46a5710238 LibJS: Use FlyString in PropertyKey instead of DeprecatedFlyString
This required dealing with *substantial* fallout.
2025-03-24 22:27:17 +00:00
Andreas Kling
3bfb0534be LibGC: Rename MarkedVector => RootVector
Let's try to make it a bit more clear that this is a Vector of GC roots.
2024-12-26 19:10:44 +01:00
Timothy Flynn
f2c19f96f8 LibJS: Implement Temporal.Now 2024-11-25 13:32:58 +01:00
Shannon Booth
f87041bf3a LibGC+Everywhere: Factor out a LibGC from LibJS
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
2024-11-15 14:49:20 +01:00
Shannon Booth
c2988a7dd5 LibJS: Don't directly teach the heap about the javascript VM or Realm
Instead, smuggle it in as a `void*` private data and let Javascript
aware code cast out that pointer to a VM&.

In order to make this split, rename JS::Cell to JS::CellImpl. Once we
have a LibGC, this will become GC::Cell. CellImpl then has no specific
knowledge of the VM& and Realm&. That knowledge is instead put into
JS::Cell, which inherits from CellImpl. JS::Cell is responsible for
JavaScript's realm initialization, as well as converting of the void*
private data to what it knows should be the VM&.
2024-11-14 15:38:45 +01:00
Shannon Booth
1e54003cb1 LibJS+LibWeb: Rename Heap::allocate_without_realm to Heap::allocate
Now that the heap has no knowledge about a JavaScript realm and is
purely for managing the memory of the heap, it does not make sense
to name this function to say that it is a non-realm variant.
2024-11-13 16:51:44 -05:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
AnotherTest
b34b681811 LibJS: Track source positions all the way down to exceptions
This makes exceptions have a trace of source positions too, which could
probably be helpful in making fancier error tracebacks.
2020-12-29 00:58:43 +01:00
Lenny Maiorani
765936ebae Everywhere: Switch from (void) to [[maybe_unused]] (#4473)
Problem:
- `(void)` simply casts the expression to void. This is understood to
  indicate that it is ignored, but this is really a compiler trick to
  get the compiler to not generate a warning.

Solution:
- Use the `[[maybe_unused]]` attribute to indicate the value is unused.

Note:
- Functions taking a `(void)` argument list have also been changed to
  `()` because this is not needed and shows up in the same grep
  command.
2020-12-21 00:09:48 +01:00
Andreas Kling
48d2545572 LibJS: Get rid of Argument and ArgumentVector
This was used for a feature where you could pass a vector of arguments
to enter_scope(). Since that way of passing arguments was not GC-aware
(as vectors use C++ heap storage), let's avoid using it and make sure
everything that needs to stay alive is either on the stack or in traced
storage instead.
2020-12-08 18:28:18 +01:00
Andreas Kling
cc14b5a6d7 LibJS: Implement a very hackish "arguments" object
We now lazily create an "arguments" array inside functions when code
tries to access it.

This doesn't follow the spec at all but still covers a lot of the
basic uses of arguments, i.e "arguments.length" and "arguments[n]"
2020-12-05 16:41:41 +01:00
Andreas Kling
01c8765519 LibJS+LibWeb: Log JavaScript exceptions raised by web content
Instead of hiding JS exceptions raised on the web, we now print them to
the debug log. This will make it a bit easier to work out why some web
pages aren't working right. :^)
2020-11-29 16:50:32 +01:00