This necessitated making the JIT::Compiler aware of the current
Bytecode::Executable, since that's where all the string literals are
held, but that seems like a good thing.
These push a "valid" unwind context on the stack and check_exception()
now knows how to jump to the (catch) handler if present.
(finally) finalizers will require some more work, but with this change,
we now have basic support for try...catch. :^)
We now establish a stack of "unwind contexts" similar to what the
bytecode interpreter does, but here, it's a stack of structs with
addresses to the catch and finally blocks.
Unwind contexts also have a "valid" flag, and the root unwind context
(always present, pushed on JIT code entry) has valid=false, which we
interpret in check_exception() as "return and let our caller deal with
the exception".
Anything in Compiler that may generate an exception should now also
call check_exception() ASAP to emit the code for handling this.
As of https://tc39.es/ecma262/#sec-yearfromtime, YearFromTime(t) should
return `y` such that `TimeFromYear(YearFromTime(t)) <= t`. This wasn't
held, since the approximation contained decimal digits that would nudge
the final value in the wrong direction.
Adapted from Kiesel:
6548a85743
Co-authored-by: Linus Groh <mail@linusgroh.de>
The spec asks us to perform some calculations that quickly exceed an
`u64`, but instead of jumping through hoops we can rely on our AK
implementation of floating point formatting to come up with the
correctly rounded result.
Note that most other JS engines seem to diverge from the spec as well
and fall back to a generic dtoa path.
This commit removes DeprecatedString's "null" state, and replaces all
its users with one of the following:
- A normal, empty DeprecatedString
- Optional<DeprecatedString>
Note that null states of DeprecatedFlyString/StringView/etc are *not*
affected by this commit. However, DeprecatedString::empty() is now
considered equal to a null StringView.
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 :^)
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.
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 :^)
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 :^)
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)
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 :^)
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).
These are normative changes in the ECMA-402 spec. See:
896ffccaf4ec46e25c455
(This combines the above commits into one patch as they each do not work
on their own).
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.
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.
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)
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)
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.
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 :^)
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. :^)
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.)