1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-25 07:15:07 +00:00
Commit graph

4674 commits

Author SHA1 Message Date
Andreas Kling
13057812d5 LibJS: Remove inline capacity from MarkedVector
Turns out this was hurting performance instead of helping it.
By removing the inline capacity, we shrink the size of ExecutionContext
by 512 bytes, which substantially reduces the stack pressure created by
JS recursion (each call creates a new ExecutionContext on the stack).

4.4% speed-up on the entire Kraken benchmark :^)
2023-10-09 09:32:24 +02:00
Karol Kosek
2ea45f4881 LibJS: Forward-declare RegexTable and BasicBlock in Executable.h
Previously every file that included Executable.h (which is pretty much
most LibJS and LibHTML files, given that VM.h needs it) had the whole
definition of LibRegex, which was slowing down source parsing.
2023-10-09 07:29:27 +02:00
Andreas Kling
6a3f27509f LibJS: Avoid IdentifierTable lookup in cached GetGlobal op
When we hit the cache in GetGlobal, we don't need the identifier string
at all, so let's defer fetching it until after the cache miss.

7% speed-up on Kraken/imaging-gaussian-blur.js :^)
2023-10-08 11:55:27 +02:00
Andreas Kling
ae4e46a037 LibJS: Do less work in successfully cached GetByValue* ops
If we have a cached environment coordinate that hasn't been screwed
by eval(), we can get the value directly without instantiating a
Reference.

15% speed-up on Octane/zlib.js :^)
2023-10-07 20:01:52 +02:00
Andreas Kling
8a727abd23 LibJS: Move Heap intrusive list manipulation inline
The functions for registering and unregistering MarkedVector, Handle,
etc. were quite prominent in benchmark profiles.

4% speed-up on the entire Kraken benchmark :^)
(including: 7% speed-up on Kraken/imaging-gaussian-blur.js, the current
slowest subtest)
2023-10-07 11:36:28 +02:00
Andreas Kling
65717e3b75 LibJS: Inline fast case for Value::to_{boolean,number,numeric,primitive}
These functions all have a very common case that can be dealt with a
very simple inline check, often avoiding the need to call an out-of-line
function. This patch moves the common case to inline functions in a new
ValueInlines.h header (necessary due to header dependency issues..)

8% speed-up on the entire Kraken benchmark :^)
2023-10-07 07:13:52 +02:00
Andreas Kling
3fb406b97e LibJS: Avoid ByteBuffer copying in NumericToRawBytes
Another 4% speed-up on Octane/gbemu.js :^)
2023-10-06 07:32:48 +02:00
Andreas Kling
285484874d LibJS: Avoid ByteBuffer copying in RawBytesToNumeric
4% speed-up on Octane/gbemu.js :^)
2023-10-06 07:32:48 +02:00
Timothy Flynn
03be26317f LibJS: Alphabetize handling some Intl.NumberFormat/PluralRules options
This is a normative change in the ECMA-402 spec. See:
5a43090
2023-10-05 17:01:02 +02:00
Timothy Flynn
eeb16f03bb LibLocale: Parse day-period hour cycle preferences
For example, the locale "fr-FR" will have the preferred hour cycle list
of "H hB", meaning h23 and h12-with-day-periods. Whether date-times are
actually formatted with day-periods is up to the user, but we need to
parse the hour cycle as h12 to know that the FR region supports h12.

This bug was revealed by LibJS no longer blindly falling back to h12 (if
the `hour12` option is true) or h24 (if the `hour12` option is false).
2023-10-05 17:01:02 +02:00
Timothy Flynn
05e080c4ba LibJS: Correctly resolve locale hour cycles in Intl.DateTimeFormat
This is a normative change in the ECMA-402 spec. See:
2f002b2
2023-10-05 17:01:02 +02:00
Timothy Flynn
39be5cb73a LibJS: Allow formatting UTC-offset time zones with Intl.DateTimeFormat
These are normative changes in the ECMA-402 spec. See:
896ffcc
af4ec46
e25c455

(This combines the above commits into one patch as they each do not work
on their own).
2023-10-05 17:01:02 +02:00
Timothy Flynn
f31540e419 LibJS: Implement time zone identifier AOs centrally within Date
This is an editorial change in the ECMA-262 spec. See:
73926a5

The idea here is to reduce duplication of these AOs between ECMA-262,
ECMA-402, and Temporal. This patch contains only the ECMA-262 changes.
2023-10-05 17:01:02 +02:00
Timothy Flynn
0bc401a1d6 LibTimeZone+Userland: Include Link entries when returning all time zones
We currently only return primary time zones, i.e. time zones that are
not a Link. LibJS will require knowledge of Link entries, and whether
each entry is or is not a Link.
2023-10-05 17:01:02 +02:00
Timothy Flynn
ddaba88340 LibJS: Convert Date-related equations into proper AOs
This is an editorial change in the ECMA-262 spec. See:
7178fa8
2023-10-05 17:01:02 +02:00
Andreas Kling
021a141b53 LibJS: Make array-like Put access on ordinary objects much faster
This patch adds a fast path to the PutByValue bytecode op that bypasses
a ton of things *if* a set of assumptions hold:

- The property key must be a non-negative Int32
- The base object must not interfere with indexed property access
- The base object must have simple indexed property storage
- The property key must already be present as an own property
- The existing value must not have any accessors defined

If this holds (which it should in many common cases), we can skip all
kinds of checks and poke directly at the property storage, saving time.

16% speed-up on the entire Kraken benchmark :^)
(including: 88% speed-up on Kraken/imaging-desaturate.js)
(including: 55% speed-up on Kraken/audio-fft.js)
(including: 54% speed-up on Kraken/audio-beat-detection.js)
2023-10-05 16:57:45 +02:00
Andreas Kling
27a83f7e5e LibJS: Make array-like Get access on ordinary objects much faster
This patch adds a fast path to the GetByValue bytecode op that bypasses
a ton of things *if* a set of assumptions hold:

- The property key must be a non-negative Int32
- The base object must not interfere with indexed property access
- The property key must already be present as an own property
- The existing value must not have any accessors defined

If this holds (which it should in the common case), we can poke directly
at the indexed property storage and save a boatload of time.

10% speed-up on the entire Kraken benchmark :^)
(including: 31% speed-up on Kraken/audio-dft.js)
(including: 23% speed-up on Kraken/stanford-crypto-aes.js)
2023-10-05 16:57:45 +02:00
Andreas Kling
a3ee8ff377 LibJS: Add IndexedProperties::storage() to access the underlying storage
This will be used in GetByValue and PutByValue fast paths.
2023-10-05 16:57:45 +02:00
Andreas Kling
7df1692580 LibJS: Add Object::may_interfere_with_indexed_property_access() virtual
This function must return true if the object may intercept and customize
access to indexed properties (properties where the property name is a
non-negative integer.)

This will be used to implement fast path optimizations for array-like
accesses in subsequent commits.
2023-10-05 16:57:45 +02:00
Andreas Kling
feef542c73 LibJS: Don't worry about deduplicating bytecode string tables
The strings will get deduplicated when actually turned into
PrimitiveString objects at runtime anyway, and keeping the string
tables deduplicated was actually wasting a lot of time.

4.4% speed-up on Kraken/stanford-crypto-ccm.js :^)
2023-10-04 20:10:12 +02:00
Andreas Kling
111622a164 LibJS: Add fast path for multiplying two Int32 values
We can avoid a lot of work here, as long as the result doesn't overflow
the Int32 range.

5% speed-up on Kraken/imaging-gaussian-blur.js :^)
2023-10-04 20:10:12 +02:00
Andreas Kling
14a9cfef4d LibJS: Add fast-path for Int32 values in Math.abs()
This function becomes very simple when the input is already an Int32.

2.3% speed-up on Kraken/imaging-gaussian-blur.js :^)
2023-10-04 20:10:12 +02:00
Andreas Kling
732b39d120 LibJS: Don't evaluate computed MemberExpression LHS twice in assignments
The following snippet would cause "i" to be incremented twice(!):

    let a = []
    let i = 0
    a[++i] += 0

This patch solves the issue by remembering the base object and property
name for computed MemberExpression LHS in codegen. We the store the
result of the assignment to the same object and property (instead of
computing the LHS again).

3 new passes on test262. :^)
2023-10-04 18:58:29 +02:00
Andreas Kling
2083376618 LibJS: Use MUST instead of TRY for infallible calls to TrimString
When the spec says to call "! TrimString", we should use MUST instead
of TRY. (We were previously using TRY in order to propagate OOM errors,
but we don't care about such OOMs anymore.)
2023-10-04 15:21:37 +02:00
Andreas Kling
c14db6ab12 LibJS: Make Executable ref-counted and let instruction iterator co-own it
This ensures that the instruction stream pointed at by the instruction
iterator remains valid as long as the iterator exists.
2023-10-03 08:23:33 +02:00
Andreas Kling
a54e283901 LibJS: Fix two bugs in the GC fast rejection of possible pointers
- Convert to FlatPtr instead of doing pointer arithmetic on a too-large
  pointer type in find_min_and_max_block_addresses(). This makes the
  range more accurate.

- Untag possible cell pointers in add_possible_value() before doing the
  rejection. Otherwise we end up rejecting most pointers since the tags
  sit in the highest bits!

This fixes a crash when running the Speedometer benchmark.
2023-09-30 09:50:55 +02:00
Andreas Kling
f388d2362a LibJS: Pad the capacity of BasicBlock while growing it
Just using Vector::resize() meant that we allocated exact capacity
instead of leaving padding at the end. This patch adds a call to
grow_capacity() before resize(), which ensures that we grow with the
usual extra padding.
2023-09-30 09:33:11 +02:00
Aliaksandr Kalenik
e79d4f3462 LibJS: Early reject pointers outside of allocated blocks range in GC
This change adds a check to discard pointers that are lower than the
minimum address of all allocated blocks or higher than the maximum
address of all blocks. By doing this we avoid executing plenty of set()
operations on the HashMap in the add_possible_value().

With this change gather_conservative_roots() run 10x times faster in
Speedometer React-Redux-TodoMVC test.
2023-09-30 08:07:12 +02:00
Aliaksandr Kalenik
66b7da4fc7 LibJS: Remove unused make_super_property_reference()
This function is no longer used anywhere after we removed AST
interpreter.
2023-09-28 20:34:47 +02:00
Aliaksandr Kalenik
42e9dfedc2 LibJS: Pre-calculate the number of bindings for function environments
We can use `ensure_capacity` for binding vectors if we know their sizes
in advance. This ensures that binding vectors aren't reallocated during
the `function_declaration_instantiation` execution.

With this change, `try_grow_capacity()` and `shrink_to_fit()` are no
longer visible in the `function_declaration_instantiation()` profiles
when running React-Redux-TodoMVC from Speedometer.
2023-09-28 15:33:43 +02:00
Aliaksandr Kalenik
98f479318a LibJS: Do not create environment bindings for local variables
If variable is local it is not stored in an environment so we don't
need a binding.
2023-09-28 15:33:43 +02:00
Aliaksandr Kalenik
4561469d52 LibJS: Fix BindingPattern::contains_expression() is name is expression
If any of binding pattern entry's name is expession
`contains_expression()` should return true.

For example:
```js
function evalInComputedPropertyKey(
  {[eval("var x = 'inner'")]: ignored}
) {}
```

`contains_expression()` should return true for the binding param in
this function.
2023-09-28 15:33:43 +02:00
Andreas Kling
aeb8b5685f LibJS: Make Bytecode::Generator::emit() return void
There are no callers left that use the return value.
2023-09-28 14:52:03 +02:00
Andreas Kling
887183cad6 LibJS: Remove last user of Op::Jump::set_targets() and API itself
This was just a matter of instantiating a BasicBlock earlier so we
can reference it when making the jump.
2023-09-28 14:52:03 +02:00
Andreas Kling
bdd21cf9db LibJS: Remove almost all uses of Op::Jump::set_targets()
We should initialize jump targets when constructing the jump instruction
instead of doing it later. This was already the case in all construction
sites but one. This first patch converts all those sites to pass final
targets to the constructor directly.
2023-09-28 14:52:03 +02:00
Andreas Kling
84850700a0 LibJS: Make BC::Generator::emit_with_extra_register_slots() return void
Nobody was using the return value.
2023-09-28 14:52:03 +02:00
Shannon Booth
2d8b2328fd LibJS: Syntax error for a unary expression followed by exponentiation
This change makes LibJS correctly report a syntax error when a unary
expression is followed by exponentiation, as the spec requires.
Apparently this is due to that expression being ambiguous ordering.

Strangely this check does not seem to apply in the same way for '++' and
'--' for reasons that I don't fully understand. For example

```
let x = 5;
++x ** 2
```

Since `--5` and `++5` on it's own results in a syntax error anyway, it
seems we do not need to perform this exponentiation check in those
places.

Diff Tests:
    +6     -6 
2023-09-28 13:11:11 +02:00
Andreas Kling
d24e07579f LibJS: Use a Vector<u8> for BasicBlock instruction storage
This reduces the minimum size of a basic block from 4 KiB to 0 bytes.
With this change, memory usage at the end of Speedometer is 1.2 GiB,
down from 1.8 GiB.
2023-09-28 11:25:19 +02:00
Andreas Kling
feedbd6a01 LibJS: Put __builtin_unreachable() in unused bytecode opcode handlers
For the opcodes that are handled directly in the interpreter loop,
we want the compiler to know that there's nothing to inline here.
2023-09-28 06:09:16 +02:00
Andreas Kling
f3606adc58 LibJS: Inline bytecode ops for direct local/register access
These can do a lot less stuff if we put them directly in the interpreter
loop and allow them to access the locals/registers arrays directly.
2023-09-28 06:09:16 +02:00
Andreas Kling
ae1ac9871b LibJS: Move all bytecode instruction implementations to Interpreter.cpp
This allows aggressive inlining without LTO.
2023-09-28 06:09:16 +02:00
Andreas Kling
e5474c384d LibJS: Inline flow control ops in the bytecode interpreter loop
Instead of calling out to helper functions for flow control (and then
checking control flags on every iteration), we now simply inline those
ops in the interpreter loop directly.
2023-09-28 06:09:16 +02:00
Andreas Kling
39cfb64269 LibJS: Return early from Interpreter on unhandled exception
If we don't have a local unwind context to handle the exception, we can
just return right away. This allows us to remove one check from the
inner loop.
2023-09-28 06:09:16 +02:00
Andreas Kling
c9eff35b96 LibJS: Use goto instead of bool will_jump in interpreter loop
This is honestly less spaghetti-ish.
2023-09-28 06:09:16 +02:00
Andreas Kling
9fe38245b2 LibJS: Move bytecode interpreter's inner loop to its own function 2023-09-28 06:09:16 +02:00
Andreas Kling
951a85992b LibJS: Mark the exception path as [[unlikely]] in the interpreter loop 2023-09-28 06:09:16 +02:00
Andreas Kling
031ec98803 LibJS: Streamline InstructionStreamIterator
Nuke all the per-instruction bounds checking when iterating instructions
by using raw pointers instead of indexing into a ReadonlyBytes.

The interpreter loop already checks that we're in-bounds anyway.
2023-09-28 06:09:16 +02:00
Andreas Kling
213b835b57 LibJS: Remove Bytecode::Interpreter::debug_position()
This was only used in one place, and that place is already covered
by a VERIFY anyway.
2023-09-28 06:09:16 +02:00
Andreas Kling
0c746366cc LibJS: Keep return value in a call frame register 2023-09-28 06:09:16 +02:00
Andreas Kling
c833885fb5 LibJS: Keep cached this value in a call frame register
Just moving more things to call frame registers..
2023-09-28 06:09:16 +02:00