Optimize RegExp instance/prototype guards
Categories
(Core :: JavaScript Engine, task, P1)
Tracking
()
Tracking | Status | |
---|---|---|
firefox139 | --- | fixed |
People
(Reporter: jandem, Assigned: jandem)
References
(Blocks 1 open bug)
Details
Attachments
(9 files)
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review |
We can now replace the following self-hosted functions with faster intrinsics that rely on fuses:
IsRegExpMethodOptimizable
IsRegExpSplitOptimizable
IsRegExpMatchAllOptimizable
IsRegExpStringIteratorNextOptimizable
IsStringMatchOptimizable
IsStringSearchOptimizable
The .exec
property lookup in the RegExpExec
intrinsic could use a similar fast path (as well as the CacheIR we generate for this intrinsic).
This will also make it easier to potentially port some of these functions to C++ in the future.
Assignee | ||
Comment 1•1 month ago
|
||
I've implemented this + a few related optimizations.
For the string-replace micro-benchmark below (best of 5 runs, all with --spectre-mitigations=off
):
before: 371 ms
after: 346 ms
before --no-ion: 1596 ms
after --no-ion: 1334 ms
For a version with a string ("abc"
) instead of regular expression:
before: 223 ms
after: 210 ms
before --no-ion: 591 ms
after --no-ion: 470 ms
So we're faster especially without Ion (Baseline code being slower hurts us on Speedometer). The new fuse-based code is also simpler and will make it easier to rewrite builtins in C++ later if needed because it removes various property accesses.
function f() {
var s = "foo";
var re = /a|b/;
var t = Date.now();
for (var i = 0; i < 10_000_000; i++) {
s = s.replace(re, "");
}
print(Date.now() - t);
return s;
}
f();
Assignee | ||
Comment 2•29 days ago
|
||
This fuse is only checked from C++ code so it doesn't need to be an invalidating fuse.
Assignee | ||
Comment 3•29 days ago
|
||
This adds the fuse without using it yet.
The list of properties guarded by the fuse is based on js::RegExpPrototypeOptimizableRaw
.
That optimization will be replaced with a fuse check in a later patch.
Assignee | ||
Comment 4•29 days ago
|
||
This is very similar to the global's boundFunctionShapeWithDefaultProto
.
Later patches will use this shape to check for plain regular expression objects.
Assignee | ||
Comment 5•29 days ago
|
||
This replaces IsStringMatchOptimizable
and similar self-hosted functions with
calls to either IsRegExpPrototypeOptimizable()
or IsOptimizableRegExpObject(object)
.
On Speedometer 3 these intrinsics always return true
.
The fuse also guards against changes to data properties so we no longer need
to check the property values explicitly in self-hosted code.
Assignee | ||
Comment 6•29 days ago
|
||
This makes IsRegExpPrototypeOptimizable()
a no-op in Ion code as long as the
fuse isn't popped. The IsOptimizableRegExpObject(object)
intrinsic is a
shape check in Ion code.
Assignee | ||
Comment 7•29 days ago
|
||
Add a fast path based on IsOptimizableRegExpObject
to the C++ code, and also guard
on the fuse in the CacheIR code.
On Speedometer 3 this fast path is always used.
Assignee | ||
Comment 8•29 days ago
|
||
Self-hosted code used functions such as StringProtoHasNoMatch
to check Symbol.match
and other symbols aren't defined on String.prototype
or Object.prototype
.
We can replace these functions with a fuse check. The fuse is popped when any of the
four symbols is added to String.prototype
or Object.prototype
or when
String.prototype
's prototype is changed.
Assignee | ||
Comment 9•29 days ago
|
||
Assignee | ||
Comment 10•29 days ago
|
||
Updated•29 days ago
|
Assignee | ||
Updated•28 days ago
|
Comment 11•22 days ago
|
||
Comment 12•22 days ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/6443bb48f276
https://hg.mozilla.org/mozilla-central/rev/da7dd0b3756f
https://hg.mozilla.org/mozilla-central/rev/06cc9671f128
https://hg.mozilla.org/mozilla-central/rev/2da432e568c7
https://hg.mozilla.org/mozilla-central/rev/d687719a301c
https://hg.mozilla.org/mozilla-central/rev/d8e1c8893d80
https://hg.mozilla.org/mozilla-central/rev/6640a9f186a8
https://hg.mozilla.org/mozilla-central/rev/4d4e7e868ec9
https://hg.mozilla.org/mozilla-central/rev/e815df607713
Comment 13•21 days ago
•
|
||
Either this bug or bug 1956420 lead to improvements:
7.2% on six-speed-regex-u-es5
7.8% on six-speed-regex-u-es6
Some improvement on Octane-regexp
Some improvement on Jetstream2-regexp
Description
•