For example, this:
```
Exception handlers:
from 678 to 698 handler 658 finalizer 0
from 698 to 6f8 handler 658 finalizer 0
from 6f8 to 708 handler 658 finalizer 0
from 708 to 750 handler 658 finalizer 0
from 750 to 788 handler 658 finalizer 0
from 788 to 7a0 handler 658 finalizer 0
from 7a0 to 7a8 handler 658 finalizer 0
```
Becomes:
```
Exception handlers:
from 678 to 7a8 handler 658 finalizer 0
```
If neither block is a Shared Data Block we can use memcpy rather than
copying one byte at a time. Currently, we are using `memcpy`
unconditionally, as Shared Data Blocks are not yet supported in this
method.
With this change, `GetIterator` no longer GC-allocates an
`IteratorRecord`. Instead, it stores the iterator record fields in
bytecode registers. This avoids per-iteration allocations in patterns
like: `for (let [x] of array) {}`.
`IteratorRecord` now inherits from `IteratorRecordImpl`, which holds the
iteration state. This allows the existing iteration helpers
(`iterator_next()`, `iterator_step()`, etc.) operate on both the
GC-allocated and the register-backed forms.
Microbenchmarks:
1.1x array-destructuring-assignment-rest.js
1.226x array-destructuring-assignment.js
This reverts commit cdcbbcf48b.
It made MicroBench/call-*-args.js faster, but some of the macro
benchmarks got significantly slower on macOS, so let's revert until we
understand it better.
Instead of always checking if we're about to return an empty completion
value in Interpreter::run_executable(), we now coerce empty completions
to the undefined value earlier instead.
This simplifies the most common path through run_executable(), giving us
a small speedup.
Instead of using this span, we can just use the getter that calculates
the base of the register/constant/local/argument array based on the
ExecutionContext's own address.
We don't need to return two values; running an executable only ever
produces a throw completion, or a normal completion, i.e a Value.
This necessitated a few minor changes, such as adding a way to check
if a JS::Cell is a GeneratorResult.
By handling call instructions in an inline (C++) function, we were
breaking the alloca() optimization and adding stack overhead. We fix
this by using a macro instead. It looks awful but it works.
1.07x speedup on MicroBench/call-00-args.js
This simplifies function entry/exit and lets us just walk away from the
used ExecutionContext instead of resetting a bunch of its state when
returning control to the caller.
Instead of having ExecutionContext track function names separately,
we give FunctionObject a virtual function that returns an appropriate
name string for use in call stacks.
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.
The GC::Ref smart pointer is always non-null, so there's no need for it
to be convertible to bool.
This exposed a small number of unnecessary null checks which we remove.
This shrinks every Statement and ECMAScriptFunctionObject by one
pointer, and puts the bytecode cache in the only place that actually
makes use of it anyway: functions.
Previously, both string_position and view_index used code unit offsets
regardless of mode. Now in unicode mode, these variables track code
point positions while string_position_in_code_units is properly
updated to reflect code unit offsets.
When an object becomes too big (currently 64 properties or more), we
change its shape to a dictionary and don't do any further transitions.
However, this means the Shape of the object no longer changes, so the
cache invalidation check of `current_shape != cache.shape` is no longer
a valid check.
This fixes that by keeping track of a generation number for the Shape
both on the Shape object and in the cache, allowing that to be checked
instead of the Shape identity. The generation is incremented whenever
the dictionary is mutated.
Fixes stale cache lookups on Gmail preventing emails from being
displayed.
I was not able to produce a reproduction for this, plus the generation
count was over the 20k mark on Gmail.
This commit implements support for forward references to named capture
groups. We now allow patterns like \k<name>(?<name>x) and
self-references like (?<name>\k<name>x).