The code in this patch lines up fairly closely with the old version of PrepareAndExecuteRegexp, but not so closely that I wanted to unify them, particularly since the old version will be going away. Aside from the changes to the layout of the input data, the main difference is that the return value is now being passed in a register instead of on the stack.
Differential Revision: https://phabricator.services.mozilla.com/D71081
PrepareAndExecuteRegexp has to be updated to call the new engine. In preparation, this patch factors out a couple of helper functions that a) can be shared between the two versions, and b) make sense as standalone functions in the future when we remove the old implementation.
Differential Revision: https://phabricator.services.mozilla.com/D71080
The baseline compiler needs to adjust its virtual stack to match the
machine stack at control-flow joins, and also when preparing stack
result areas for calls. In the latter case, there may be temporary
values on the stack, so the stack height before pushing stack results is
not the current block's stack height. Similarly adjustments are needed
when pushing stack results after a call.
Differential Revision: https://phabricator.services.mozilla.com/D71017
--HG--
extra : moz-landing-system : lando
On x86 and x64, the register dump has space for the full XMM FP
registers, but PushRegistersInMask will reduce the register set down
to quadword if JitSupportsSimd() is false. Thus register dump areas
must be created by another mechanism than PushRegistersInMask when
!JitSupportsSimd(). The platform code did this in the case of
bailouts but got it wrong for invalidations; this patch fixes that for
both platforms.
We never found this bug because JitSupportsSimd() currently always
returns true on x86 and x64, as it only checks HasSSE2(), and that is
always true.
Additionally, make JitSupportsSimd() guard its return value on the
js::jit::SupportsSimd flag, which it probably should have been doing
all along (it does this on other platforms). Since that flag is
always false, JitSupportsSimd() will now always return false, there
being no SIMD on x86 or x64 yet.
Differential Revision: https://phabricator.services.mozilla.com/D71149
--HG--
extra : moz-landing-system : lando
Some of the flags are mutable so reading this flag off-thread can cause TSan issues.
Differential Revision: https://phabricator.services.mozilla.com/D71172
--HG--
extra : moz-landing-system : lando
Outside of powering BytecodeSection's source notes generation, the line and
column numbers were almost entirely unused, except to power a single assertion
that lineno and column agreed between the stencil (BCE derived) and script.
However, by switching to using the SharedContext extents, we lose the ability
to always assert they're the same, because in the old system dynamically
allocated functions used externally provided column info that disagrees with
the parser result. In this patch the script still gets the same column
number as before, but we can't assert that the value is the same as what you
could get out of the BCE, because the BCE number is actually more accurate
than the script.
Fixing the script column should be followup.
Differential Revision: https://phabricator.services.mozilla.com/D70411
--HG--
extra : moz-landing-system : lando
This tracks the total memory used by the nursery's malloced buffers set and trigers a minor GC if it passes some limit. The limit is somewhat arbirarily defined as eight times the nursery capactity - this only fires rarely in normal use but is enough to prevent runaway memory growth in this case.
Depends on D71041
Differential Revision: https://phabricator.services.mozilla.com/D71042
--HG--
extra : moz-landing-system : lando
For now this generates just CACHE_IR_OPS and CACHE_IR_SHARED_OPS in CacheIROpsGenerated.h
but the plan is to use this to generate parts of the IR writer and compiler/transpiler
interface. The spewer could also potentially be improved now that each operand has a name
and more precise type.
Generating the IR writer will likely happen incrementally so that will give us
another chance to double check the precise types match what's in the YAML file.
Differential Revision: https://phabricator.services.mozilla.com/D70995
--HG--
extra : moz-landing-system : lando
Most other generated SpiderMonkey files have the 'Generated' suffix so let's
follow that convention.
Differential Revision: https://phabricator.services.mozilla.com/D70993
--HG--
extra : moz-landing-system : lando
Move the TI heuristic into BCE::emitFunction where the other special mutation
of inner-functions is happening.
Differential Revision: https://phabricator.services.mozilla.com/D70781
--HG--
extra : moz-landing-system : lando
Instead rely on consistent definitions of the TreatAsRunOnce flag on the
SharedContext. Also simplify the BCE::check{RunOnce,Singleton}Context
accessors. Note that the TreatAsRunOnce flag indicates the script is expected
to run-once, but the BCE also checks for isInLoop to decide if current
bytecode location within the script should still be considered run-once.
Differential Revision: https://phabricator.services.mozilla.com/D70780
--HG--
extra : moz-landing-system : lando
Use the same conditions for qualifying an inner function as a run-once-lambda
between the lazy and non-lazy code paths. Use the FunctionBox::immutableFlags
so that this works well with delazification too.
Differential Revision: https://phabricator.services.mozilla.com/D70779
--HG--
extra : moz-landing-system : lando
In the BytecodeEmitter constructor, initialize the TreatAsRunOnce flag for
top-level SharedContexts. In the future we should initialize this even
earlier. For the delazification case, we initialize already directly
initialize this flag from the lazy BaseScript.
Differential Revision: https://phabricator.services.mozilla.com/D70778
--HG--
extra : moz-landing-system : lando
The interpreter calls `TierUpTick` whenever we interpret a regexp. Once we hit the tick threshold, compileIfNecessary will compile native code for the regexp.
Currently the tick threshold is hard-coded to 10. V8's tick threshold is 1, which seems unreasonably low. We can tune this later.
Differential Revision: https://phabricator.services.mozilla.com/D70952
--HG--
extra : moz-landing-system : lando
The current ForceByteCodeEnum is a glorified boolean. This patch replaces it with a three-value bytecode/jitcode/either enum, which will make our tiering-up logic slightly nicer in the next patch.
Differential Revision: https://phabricator.services.mozilla.com/D70951
--HG--
extra : moz-landing-system : lando
Internally, irregexp uses -1 for errors, 0 for failure, and 1 for success. We have to use the same values in RegExpRunStatus.
Ideally we would replace RegExpRunStatus with an enum defined in RegExpTypes.h, but that will have to wait until we get rid of the old import.
Differential Revision: https://phabricator.services.mozilla.com/D70728
--HG--
extra : moz-landing-system : lando
The irregexp compiler takes the AST produced by the parser, compiles it down to a more efficient internal representation, then uses a 'macroassembler' to generate code. The generated code can either be bytecode (which is then fed into the interpreter) or jitcode (which can be executed directly).
This patch gets the infrastructure set up and handles the former case.
CompilePattern is based heavily on V8's `RegExpImpl::compile` (affc364620/src/regexp/regexp.cc (L745-L933)). I am upstreaming a patch to move the code in WrapBody into regexp-compiler.cc where it fits better.
V8 is about to land a patch to tweak the API for Interpret so that it allocates memory for its registers internally instead of requiring it to be passed in. When we import this change, we'll be able to pass `matches->pairsRaw()` directly into `MatchForCallFromRuntime`, and the interpreter will fill it in for us.
In the old engine, we could handle interrupts in the middle of the interpreter. If we hit an urgent interrupt in compiled code, we would generate bytecode and fall back to the interpreter (see https://searchfox.org/mozilla-central/rev/9120151ddb35f2d4c37bfe613a54a4f10a9a3dc5/js/src/vm/RegExpObject.cpp#1165-1175). (This is what all the `ForceByteCode` machinery in RegExpObject.cpp is about. It was added in bug 1077514.) That won't work in the new version. V8 does allow interrupts during regexp execution, but only by jumping through some scary hoops to "manually relocate unhandlified references" afterwards. Instead, we just retry the regexp. I have no idea what a reasonable number of retries is before giving up; I've arbitrarily picked 4 for now.
Differential Revision: https://phabricator.services.mozilla.com/D70695
--HG--
extra : moz-landing-system : lando
In preparation for actually compiling regexps in the next patch, hook up the V8 and irregexp representations of a compiled regexp.
Differential Revision: https://phabricator.services.mozilla.com/D70694
--HG--
extra : moz-landing-system : lando
A regexp with N sets of capturing parens will have N+1 capture groups, with the extra capture containing the entire matching string. Our old implementation stored `parenCount` in the RegExpShared and then added 1 to it whenever it was used. A much simpler answer is to just add 1 when initializing the regexp.
Differential Revision: https://phabricator.services.mozilla.com/D70693
--HG--
extra : moz-landing-system : lando
The interpreter calls `TierUpTick` whenever we interpret a regexp. Once we hit the tick threshold, compileIfNecessary will compile native code for the regexp.
Currently the tick threshold is hard-coded to 10. V8's tick threshold is 1, which seems unreasonably low. We can tune this later.
Differential Revision: https://phabricator.services.mozilla.com/D70952
--HG--
extra : moz-landing-system : lando
The current ForceByteCodeEnum is a glorified boolean. This patch replaces it with a three-value bytecode/jitcode/either enum, which will make our tiering-up logic slightly nicer in the next patch.
Differential Revision: https://phabricator.services.mozilla.com/D70951
--HG--
extra : moz-landing-system : lando
Internally, irregexp uses -1 for errors, 0 for failure, and 1 for success. We have to use the same values in RegExpRunStatus.
Ideally we would replace RegExpRunStatus with an enum defined in RegExpTypes.h, but that will have to wait until we get rid of the old import.
Differential Revision: https://phabricator.services.mozilla.com/D70728
--HG--
extra : moz-landing-system : lando
The irregexp compiler takes the AST produced by the parser, compiles it down to a more efficient internal representation, then uses a 'macroassembler' to generate code. The generated code can either be bytecode (which is then fed into the interpreter) or jitcode (which can be executed directly).
This patch gets the infrastructure set up and handles the former case.
CompilePattern is based heavily on V8's `RegExpImpl::compile` (affc364620/src/regexp/regexp.cc (L745-L933)). I am upstreaming a patch to move the code in WrapBody into regexp-compiler.cc where it fits better.
V8 is about to land a patch to tweak the API for Interpret so that it allocates memory for its registers internally instead of requiring it to be passed in. When we import this change, we'll be able to pass `matches->pairsRaw()` directly into `MatchForCallFromRuntime`, and the interpreter will fill it in for us.
In the old engine, we could handle interrupts in the middle of the interpreter. If we hit an urgent interrupt in compiled code, we would generate bytecode and fall back to the interpreter (see https://searchfox.org/mozilla-central/rev/9120151ddb35f2d4c37bfe613a54a4f10a9a3dc5/js/src/vm/RegExpObject.cpp#1165-1175). (This is what all the `ForceByteCode` machinery in RegExpObject.cpp is about. It was added in bug 1077514.) That won't work in the new version. V8 does allow interrupts during regexp execution, but only by jumping through some scary hoops to "manually relocate unhandlified references" afterwards. Instead, we just retry the regexp. I have no idea what a reasonable number of retries is before giving up; I've arbitrarily picked 4 for now.
Differential Revision: https://phabricator.services.mozilla.com/D70695
--HG--
extra : moz-landing-system : lando
In preparation for actually compiling regexps in the next patch, hook up the V8 and irregexp representations of a compiled regexp.
Differential Revision: https://phabricator.services.mozilla.com/D70694
--HG--
extra : moz-landing-system : lando
A regexp with N sets of capturing parens will have N+1 capture groups, with the extra capture containing the entire matching string. Our old implementation stored `parenCount` in the RegExpShared and then added 1 to it whenever it was used. A much simpler answer is to just add 1 when initializing the regexp.
Differential Revision: https://phabricator.services.mozilla.com/D70693
--HG--
extra : moz-landing-system : lando
It's probably more helpful to have the variable documentation near the
declaration. Also amends the description to cover normal name assignments.
Depends on D70863
Differential Revision: https://phabricator.services.mozilla.com/D70864
--HG--
extra : moz-landing-system : lando
`~Maybe()` will perform the clean-up anyway, so we don't really need to call
`reset()` manually here.
Depends on D70862
Differential Revision: https://phabricator.services.mozilla.com/D70863
--HG--
extra : moz-landing-system : lando
The comment about handling name assignments separately predates `NameOpEmitter`.
Using `NameOpEmitter` we don't have to worry choosing the correct bytecode
operations and when to emit `BindName`.
Depends on D70861
Differential Revision: https://phabricator.services.mozilla.com/D70862
--HG--
extra : moz-landing-system : lando
Restricted to Nightly because there's still an open issue about inferred
function names and because the proposal was only recently moved to stage 3.
Depends on D70821
Differential Revision: https://phabricator.services.mozilla.com/D70823
--HG--
extra : moz-landing-system : lando
Implements the changes from: https://github.com/tc39/ecma262/pull/1408
The spec PR requires to start the non-syntactic `try` block before retrieving
the "return" property and checking whether or not the "return" property is
callable. As part of this change we can also reorder the other byte code
instructions, which enables us to make the code more similar to normal JS code.
The equivalent JS code is documented in the added comments. Furthermore these
changes allow us to remove the manual stack depth fixups.
Depends on D70819
Differential Revision: https://phabricator.services.mozilla.com/D70820
--HG--
extra : moz-landing-system : lando
Updates the two callers to `JSOp::Pick` which can be optimised to `JSOp::Swap`.
Using `JSOp::Swap` saves one byte when compared to `JSOp::Pick`.
Depends on D70817
Differential Revision: https://phabricator.services.mozilla.com/D70819
--HG--
extra : moz-landing-system : lando
Omit the ellipsis characters when the call has zero arguments. This makes the
disassembly of iterator code a bit more readable, because we're now no longer
displaying additional "..." strings when the call has no arguments.
Depends on D70816
Differential Revision: https://phabricator.services.mozilla.com/D70817
--HG--
extra : moz-landing-system : lando