This adds support to the KeyedLoadIC to ignore out of bounds accesses
for Strings and return undefined instead. We add a dedicated bit to the
Smi handler to encode the OOB state and have TurboFan generate appropriate
code for that case as well. This is mostly useful when programs
accidentially access past the length of a string, which was observed and
fixed for example in Babel recently, see
https://github.com/babel/babel/pull/6589
for details. The idea is to also extend this mechanism to Arrays and
maybe other receivers, as reading beyond the length is also often used
in jQuery and other popular libraries.
Note that this is considered a mitigation for a performance cliff and
not a general optimization of OOB accesses. These should still be
avoided and handled properly instead.
This seems to further improve the babel test on the web-tooling-benchmark
by around 1%, because the OOB access no longer turns the otherwise
MONOMORPHIC access into MEGAMORPHIC state.
Bug: v8:6936, v8:7014
Change-Id: I9df03304e056d7001a65da8e9621119f8e9bb55b
Reviewed-on: https://chromium-review.googlesource.com/744022
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49049}
Following up on adding n-ary nodes, this extends the parser and
interpreter to support n-ary logical operations.
Bug: v8:6964
Bug: chromium:731861
Change-Id: Ife2141c389b9abccd917ab2aaddf399c436ef777
Reviewed-on: https://chromium-review.googlesource.com/735497
Reviewed-by: Adam Klein <adamk@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49029}
We now represent the SameValue operation explicitly in TurboFan and the
operation can thus participate in all kinds of optimizations. Especially
we get rid of the JSCall node in the general case, which blocks several
optimizations across the call. The general, baseline performance is now
always on par with StrictEqual.
Once the StrictEqual operator is also a simplified operator, we should
start unifying the type based optimizations in SimplifiedLowering.
In the micro-benchmark we go from
testStrictEqual: 1422 ms.
testObjectIs: 1520 ms.
testManualSameValue: 1759 ms.
to
testStrictEqual: 1426 ms.
testObjectIs: 1357 ms.
testManualSameValue: 1766 ms.
which gives the expected result.
Bug: v8:7007
Change-Id: I0de3ff6ff6209ab4c3edb69de6a16e387295a9c8
Reviewed-on: https://chromium-review.googlesource.com/741228
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48994}
Expressions of the form
a_0 + a_1 + a_2 + a_3 + ... + a_n
seem to be reasonably common for cases such as building templates.
However, parsing these expressions results in a n-deep expression tree:
...
/
+
/ \
+ a_2
/ \
a_0 a_1
Traversing this tree during compilation can cause a stack overflow when n is
large.
Instead, for left-associate operations such as add, we now build up an
n-ary node in the parse tree, of the form
n-ary +
/ | \
/ | ... \
a_0 a_1 a_n
The bytecode compiler can now iterate through the child expressions
rather than recursing.
This patch only supports arithmetic operations -- subsequent patches
will enable the same optimization for logical tests and comma
expressions.
Bug: v8:6964
Bug: chromium:724961
Bug: chromium:731861
Bug: chromium:752081
Bug: chromium:771653
Bug: chromium:777302
Change-Id: Ie97e4ce42506fe62a7bc4ffbdaa90a9f698352cb
Reviewed-on: https://chromium-review.googlesource.com/733120
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48920}
When TurboFan sees a call to Reflect.get with exactly two parameters,
we can lower that to a direct call to the GetPropertyStub, which is
certainly faster than the general C++ builtin. This gives a nice
7-8% improvement on the chai test in the web-tooling-benchmark.
The micro-benchmark on the issue goes from
reflectGetPresent: 461 ms.
reflectGetAbsent: 470 ms.
to
reflectGetPresent: 141 ms.
reflectGetAbsent: 245 ms.
which is an up to 3.2x improvement.
Bug: v8:5996, v8:6936, v8:6937
Change-Id: Ic439fccb13f1a2f84386bf9fc31b4283d101afc4
Reviewed-on: https://chromium-review.googlesource.com/732988
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48841}
This adds a new InstanceOfIC where the TestInstanceOf bytecode collects
constant feedback about the right-hand side of instanceof operators,
including both JSFunction and JSBoundFunction instances. TurboFan then
uses the feedback to optimize instanceof in places where the right-hand
side is not a known constant (known to TurboFan).
This addresses the odd performance cliff that we see with instanceof in
functions with multiple closures. It was discovered as one of the main
bottlenecks on the uglify-es test in the web-tooling-benchmark. The
uglify-es test (run in separation) is ~18% faster with this change.
On the micro-benchmark in the tracking bug we go from
instanceofSingleClosure_Const: 69 ms.
instanceofSingleClosure_Class: 246 ms.
instanceofMultiClosure: 246 ms.
instanceofParameter: 246 ms.
to
instanceofSingleClosure_Const: 70 ms.
instanceofSingleClosure_Class: 75 ms.
instanceofMultiClosure: 76 ms.
instanceofParameter: 73 ms.
boosting performance by roughly 3.6x and thus effectively removing the
performance cliff around instanceof.
Bug: v8:6936, v8:6971
Change-Id: Ib88dbb9eaef9cafa4a0e260fbbde73427a54046e
Reviewed-on: https://chromium-review.googlesource.com/730686
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48820}
This revert is manual, but almost completely automatic.
It was just blocked by a single-line irrelevant refactoring change.
This reverts commit 1cee0e012e.
Reason for revert: chromium:776256
Original change's description:
> Reland^4 "[turbofan] eagerly prune None types and deadness from the graph"
>
> This fixes https://bugs.chromium.org/p/chromium/issues/detail?id=773954.
> The issue was that in the EffectControlLinearizer, the effect input of an
> {Unreachable} node was not updated, leaving a {Checkpoint} behind.
>
> This is a reland of 4cf476458f
> Original change's description:
> > Reland^3 "[turbofan] eagerly prune None types and deadness from the graph"
> >
> > This fixes the issues
> > https://bugs.chromium.org/p/chromium/issues/detail?id=772873
> > and https://bugs.chromium.org/p/chromium/issues/detail?id=772872.
> >
> > One problem was that mutating an effect node into Unreachable confused
> > the LoadElimination sidetables, so I just always create a new node now.
> >
> > The other problem was that UpdateBlockControl() was executed after
> > UpdateEffectPhi() in the lazy case. This reverted the update to the Merge input.
> > So now I make sure that UpdateEffectPhi() is always executed last.
> >
> > This is a reland of 6ddb5e7da7
> > Original change's description:
> > > Reland^2 "[turbofan] eagerly prune None types and deadness from the graph"
> > >
> > > Now, the EffectControlLinearizer connects all occurrences of Unreachable to the
> > > graph end. This fixes issues with later phases running DeadCodeElimination and
> > > introducing new DeadValue nodes when processing uses of Unreachable.
> > >
> > > This is a reland of 3c4bc27f13
> > > Original change's description:
> > > > Reland "[turbofan] eagerly prune None types and deadness from the graph"
> > > >
> > > > This is a reland of e1cdda2512
> > > > Original change's description:
> > > > > [turbofan] eagerly prune None types and deadness from the graph
> > > > >
> > > > > In addition to using the {Dead} node to prune dead control nodes and nodes that
> > > > > depend on them, we introduce a {DeadValue} node representing an impossible value
> > > > > that can occur at any position in the graph. The extended {DeadCodeElimination}
> > > > > prunes {DeadValue} and its uses, inserting a crashing {Unreachable} node into
> > > > > the effect chain when possible. The remaining uses of {DeadValue} are handled
> > > > > in {EffectControlLinearizer}, where we always have access to the effect chain.
> > > > > In addition to explicitly introduced {DeadValue} nodes, we consider any value use
> > > > > of a node with type {None} as dead.
> > > > >
> > > > > Bug: chromium:741225
> > > > > Change-Id: Icc4b636d1d018c452ba1a2fa7cd3e00e522f1655
> > > > > Reviewed-on: https://chromium-review.googlesource.com/641250
> > > > > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > > > > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > > > > Cr-Commit-Position: refs/heads/master@{#48208}
> > > >
> > > > Bug: chromium:741225
> > > > Change-Id: I21316913dae02864f7a6d7c9269405a79f054138
> > > > Reviewed-on: https://chromium-review.googlesource.com/692034
> > > > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > > > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > > > Cr-Commit-Position: refs/heads/master@{#48232}
> > >
> > > Bug: chromium:741225
> > > Change-Id: I5702ec34856c075717162153adc765774453c45f
> > > Reviewed-on: https://chromium-review.googlesource.com/702264
> > > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > > Cr-Commit-Position: refs/heads/master@{#48366}
> >
> > Bug: chromium:741225
> > Change-Id: I4054a694d2521c2e1f0c4a3ad0f3cf100b5c536f
> > Reviewed-on: https://chromium-review.googlesource.com/709214
> > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#48469}
>
> Bug: chromium:741225
> Change-Id: Id9d4f3a3ae36cb3e38f80edcdba88efa7922ca24
> Reviewed-on: https://chromium-review.googlesource.com/715716
> Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#48660}
TBR=jarin@chromium.org,tebbi@chromium.org,bmeurer@chromium.org
Bug: chromium:741225 chromium:776256
Change-Id: Iaf2af3cb6dea5fdece43297cb9d987e7decc726d
Reviewed-on: https://chromium-review.googlesource.com/727804
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48749}
This addresses the odd performance cliff, where the CallIC tracks known
JSFunction targets, but goes MEGAMORPHIC when it sees a JSBoundFunction
target. With this fix in place the micro-benchmark on the bug goes from
arrowCall: 82 ms.
boundCall: 234 ms.
to
arrowCall: 81 ms.
boundCall: 80 ms.
so Function#bind doesn't cause any additional overhead anymore.
Bug: v8:5267, v8:6962
Change-Id: Iaceaf89fd3e99e2afe2ae45e96a6813a3ef8b1d2
Reviewed-on: https://chromium-review.googlesource.com/727879
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48722}
So far the JSCallReducer was only able to unfold constant
JSBoundFunction targets for JSCall nodes, which is not the
common case. With the introduction of JSCreateBoundFunction
operator earlier, we can now also recognize calls to bound
functions where the bind happens earlier in the function,
i.e. as the example of
a.map(f.bind(self))
in https://twitter.com/BenLesh/status/920700003974123520, which
is a handy way to use Function#bind. So this transformation
takes a node like
JSCall(JSCreateBoundFunction(bound_target_function,
bound_this,
a1,...,aN),
receiver, p1,...,pM)
and turns that into
JSCall(bound_target_function, bound_this, a1,...,aN,p1,...,pM)
allowing TurboFan to further inline the bound_target_function
at this call site if that's also inlinable (i.e. it's a known
constant JSFunction or the result of a JSCreateClosure call).
This improves the micro-benchmark from
arrowCall: 55 ms.
boundCall: 221 ms.
arrowMap: 181 ms.
boundMap: 806 ms.
to
arrowCall: 71 ms.
boundCall: 76 ms.
arrowMap: 188 ms.
boundMap: 186 ms.
so that Function#bind in this case is as fast as using closures,
which is an up to 4.3x improvement in the Array#map example.
Bug: v8:5257, v8:6961
Change-Id: Ibca650faad912bf9db1db6fbc48772e7551289a6
Reviewed-on: https://chromium-review.googlesource.com/727799
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48713}
This fixes https://bugs.chromium.org/p/chromium/issues/detail?id=773954.
The issue was that in the EffectControlLinearizer, the effect input of an
{Unreachable} node was not updated, leaving a {Checkpoint} behind.
This is a reland of 4cf476458f
Original change's description:
> Reland^3 "[turbofan] eagerly prune None types and deadness from the graph"
>
> This fixes the issues
> https://bugs.chromium.org/p/chromium/issues/detail?id=772873
> and https://bugs.chromium.org/p/chromium/issues/detail?id=772872.
>
> One problem was that mutating an effect node into Unreachable confused
> the LoadElimination sidetables, so I just always create a new node now.
>
> The other problem was that UpdateBlockControl() was executed after
> UpdateEffectPhi() in the lazy case. This reverted the update to the Merge input.
> So now I make sure that UpdateEffectPhi() is always executed last.
>
> This is a reland of 6ddb5e7da7
> Original change's description:
> > Reland^2 "[turbofan] eagerly prune None types and deadness from the graph"
> >
> > Now, the EffectControlLinearizer connects all occurrences of Unreachable to the
> > graph end. This fixes issues with later phases running DeadCodeElimination and
> > introducing new DeadValue nodes when processing uses of Unreachable.
> >
> > This is a reland of 3c4bc27f13
> > Original change's description:
> > > Reland "[turbofan] eagerly prune None types and deadness from the graph"
> > >
> > > This is a reland of e1cdda2512
> > > Original change's description:
> > > > [turbofan] eagerly prune None types and deadness from the graph
> > > >
> > > > In addition to using the {Dead} node to prune dead control nodes and nodes that
> > > > depend on them, we introduce a {DeadValue} node representing an impossible value
> > > > that can occur at any position in the graph. The extended {DeadCodeElimination}
> > > > prunes {DeadValue} and its uses, inserting a crashing {Unreachable} node into
> > > > the effect chain when possible. The remaining uses of {DeadValue} are handled
> > > > in {EffectControlLinearizer}, where we always have access to the effect chain.
> > > > In addition to explicitly introduced {DeadValue} nodes, we consider any value use
> > > > of a node with type {None} as dead.
> > > >
> > > > Bug: chromium:741225
> > > > Change-Id: Icc4b636d1d018c452ba1a2fa7cd3e00e522f1655
> > > > Reviewed-on: https://chromium-review.googlesource.com/641250
> > > > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > > > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > > > Cr-Commit-Position: refs/heads/master@{#48208}
> > >
> > > Bug: chromium:741225
> > > Change-Id: I21316913dae02864f7a6d7c9269405a79f054138
> > > Reviewed-on: https://chromium-review.googlesource.com/692034
> > > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > > Cr-Commit-Position: refs/heads/master@{#48232}
> >
> > Bug: chromium:741225
> > Change-Id: I5702ec34856c075717162153adc765774453c45f
> > Reviewed-on: https://chromium-review.googlesource.com/702264
> > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#48366}
>
> Bug: chromium:741225
> Change-Id: I4054a694d2521c2e1f0c4a3ad0f3cf100b5c536f
> Reviewed-on: https://chromium-review.googlesource.com/709214
> Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#48469}
Bug: chromium:741225
Change-Id: Id9d4f3a3ae36cb3e38f80edcdba88efa7922ca24
Reviewed-on: https://chromium-review.googlesource.com/715716
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48660}
Ensure we only lower SpeculativeNumberBinops to a pure operator for
non-string plain primitives. Previously we could lower if a value might be
the-hole, however this would fail a CHECK in ConvertInputsToNumber which
expects a plain primitive.
BUG=chromium:772420
Change-Id: I0c755d10db7afd9cabfb638eca5662d70dfc8d51
Reviewed-on: https://chromium-review.googlesource.com/715717
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48649}
OSR for functions which use arguments no longer needs to be disabled, since
TurboFan handles the case.
Bug:
Change-Id: I121f1190a142c18f113bd5f875e258812645c43f
Reviewed-on: https://chromium-review.googlesource.com/721661
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48631}
Port the baseline version of Reflect.has to the CodeStubAssembler and
reuse the existing logic for HasProperty (i.e. the HasProperty builtin).
Also inline the Reflect.has builtin into TurboFan, by adding a check
on the target in front of a use of the JSHasProperty operator.
Technically this additional check is not necessary, because the
JSHasProperty operator already throws if the target is not a JSReceiver,
but the exception message is confusing then.
This improves the performance of the micro-benchmark from
reflectHasPresent: 337 ms.
reflectHasAbsent: 472 ms.
to
reflectHasPresent: 121 ms.
reflectHasAbsent: 216 ms.
which is a nice 2.8x improvement in the best case. It also improves the
chai test on the web-tooling-benchmark by around 1-2%, which is roughly
the expected win (since Reflect.has overall accounts for around 3-4%).
Bug: v8:5996, v8:6936, v8:6937
Change-Id: I856183229677a71c19936f06f2a4fc7a794a9a4a
Reviewed-on: https://chromium-review.googlesource.com/720959
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48608}
This reverts commit 4cf476458f.
Reason for revert: Broken effect chains detected by Clusterfuzz. Playing it safe for the 63 branch.
Original change's description:
> Reland^3 "[turbofan] eagerly prune None types and deadness from the graph"
>
> This fixes the issues
> https://bugs.chromium.org/p/chromium/issues/detail?id=772873
> and https://bugs.chromium.org/p/chromium/issues/detail?id=772872.
>
> One problem was that mutating an effect node into Unreachable confused
> the LoadElimination sidetables, so I just always create a new node now.
>
> The other problem was that UpdateBlockControl() was executed after
> UpdateEffectPhi() in the lazy case. This reverted the update to the Merge input.
> So now I make sure that UpdateEffectPhi() is always executed last.
>
> This is a reland of 6ddb5e7da7
> Original change's description:
> > Reland^2 "[turbofan] eagerly prune None types and deadness from the graph"
> >
> > Now, the EffectControlLinearizer connects all occurrences of Unreachable to the
> > graph end. This fixes issues with later phases running DeadCodeElimination and
> > introducing new DeadValue nodes when processing uses of Unreachable.
> >
> > This is a reland of 3c4bc27f13
> > Original change's description:
> > > Reland "[turbofan] eagerly prune None types and deadness from the graph"
> > >
> > > This is a reland of e1cdda2512
> > > Original change's description:
> > > > [turbofan] eagerly prune None types and deadness from the graph
> > > >
> > > > In addition to using the {Dead} node to prune dead control nodes and nodes that
> > > > depend on them, we introduce a {DeadValue} node representing an impossible value
> > > > that can occur at any position in the graph. The extended {DeadCodeElimination}
> > > > prunes {DeadValue} and its uses, inserting a crashing {Unreachable} node into
> > > > the effect chain when possible. The remaining uses of {DeadValue} are handled
> > > > in {EffectControlLinearizer}, where we always have access to the effect chain.
> > > > In addition to explicitly introduced {DeadValue} nodes, we consider any value use
> > > > of a node with type {None} as dead.
> > > >
> > > > Bug: chromium:741225
> > > > Change-Id: Icc4b636d1d018c452ba1a2fa7cd3e00e522f1655
> > > > Reviewed-on: https://chromium-review.googlesource.com/641250
> > > > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > > > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > > > Cr-Commit-Position: refs/heads/master@{#48208}
> > >
> > > Bug: chromium:741225
> > > Change-Id: I21316913dae02864f7a6d7c9269405a79f054138
> > > Reviewed-on: https://chromium-review.googlesource.com/692034
> > > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > > Cr-Commit-Position: refs/heads/master@{#48232}
> >
> > Bug: chromium:741225
> > Change-Id: I5702ec34856c075717162153adc765774453c45f
> > Reviewed-on: https://chromium-review.googlesource.com/702264
> > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#48366}
>
> Bug: chromium:741225
> Change-Id: I4054a694d2521c2e1f0c4a3ad0f3cf100b5c536f
> Reviewed-on: https://chromium-review.googlesource.com/709214
> Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#48469}
TBR=jarin@chromium.org,tebbi@chromium.org
Change-Id: Icf6a6af4feaafd4bde28cb7b996735ff91bb3810
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:741225
Reviewed-on: https://chromium-review.googlesource.com/715096
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48482}
This fixes the issues
https://bugs.chromium.org/p/chromium/issues/detail?id=772873
and https://bugs.chromium.org/p/chromium/issues/detail?id=772872.
One problem was that mutating an effect node into Unreachable confused
the LoadElimination sidetables, so I just always create a new node now.
The other problem was that UpdateBlockControl() was executed after
UpdateEffectPhi() in the lazy case. This reverted the update to the Merge input.
So now I make sure that UpdateEffectPhi() is always executed last.
This is a reland of 6ddb5e7da7
Original change's description:
> Reland^2 "[turbofan] eagerly prune None types and deadness from the graph"
>
> Now, the EffectControlLinearizer connects all occurrences of Unreachable to the
> graph end. This fixes issues with later phases running DeadCodeElimination and
> introducing new DeadValue nodes when processing uses of Unreachable.
>
> This is a reland of 3c4bc27f13
> Original change's description:
> > Reland "[turbofan] eagerly prune None types and deadness from the graph"
> >
> > This is a reland of e1cdda2512
> > Original change's description:
> > > [turbofan] eagerly prune None types and deadness from the graph
> > >
> > > In addition to using the {Dead} node to prune dead control nodes and nodes that
> > > depend on them, we introduce a {DeadValue} node representing an impossible value
> > > that can occur at any position in the graph. The extended {DeadCodeElimination}
> > > prunes {DeadValue} and its uses, inserting a crashing {Unreachable} node into
> > > the effect chain when possible. The remaining uses of {DeadValue} are handled
> > > in {EffectControlLinearizer}, where we always have access to the effect chain.
> > > In addition to explicitly introduced {DeadValue} nodes, we consider any value use
> > > of a node with type {None} as dead.
> > >
> > > Bug: chromium:741225
> > > Change-Id: Icc4b636d1d018c452ba1a2fa7cd3e00e522f1655
> > > Reviewed-on: https://chromium-review.googlesource.com/641250
> > > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > > Cr-Commit-Position: refs/heads/master@{#48208}
> >
> > Bug: chromium:741225
> > Change-Id: I21316913dae02864f7a6d7c9269405a79f054138
> > Reviewed-on: https://chromium-review.googlesource.com/692034
> > Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> > Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#48232}
>
> Bug: chromium:741225
> Change-Id: I5702ec34856c075717162153adc765774453c45f
> Reviewed-on: https://chromium-review.googlesource.com/702264
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#48366}
Bug: chromium:741225
Change-Id: I4054a694d2521c2e1f0c4a3ad0f3cf100b5c536f
Reviewed-on: https://chromium-review.googlesource.com/709214
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48469}
The Object.is builtin provides an entry point to the abstract operation
SameValue, which properly distinguishes -0 and 0, and also identifies
NaNs. Most of the time you don't need these, but rather just regular
strict equality, but when you do, Object.is(o, -0) is the most readable
way to check for minus zero.
This is for example used in Node.js by formatNumber to properly print -0
for negative zero. However since the builtin thus far implemented as C++
builtin and TurboFan didn't know anything about it, Node.js considering
to go with a more performant, less readable version (which also makes
assumptions about the input value) in
https://github.com/nodejs/node/pull/15726
until the performance of Object.is will be on par (so hopefully we can
go back to Object.is in Node 9).
This CL ports the baseline implementation of Object.is to CSA, which
is pretty straight-forward since SameValue is already available in
CodeStubAssembler, and inlines a few interesting cases into TurboFan,
i.e. comparing same SSA node, and checking for -0 and NaN explicitly.
On the micro-benchmarks we go from
testNumberIsMinusZero: 1000 ms.
testObjectIsMinusZero: 929 ms.
testObjectIsNaN: 954 ms.
testObjectIsSame: 793 ms.
testStrictEqualSame: 104 ms.
to
testNumberIsMinusZero: 89 ms.
testObjectIsMinusZero: 88 ms.
testObjectIsNaN: 88 ms.
testObjectIsSame: 86 ms.
testStrictEqualSame: 105 ms.
which is a nice 10x to 11x improvement and brings Object.is on par with
strict equality for most cases.
Drive-by-fix: Also refactor and optimize the SameValue check in the
CodeStubAssembler to avoid code bloat (by not inlining StrictEqual
into every user of SameValue, and also avoiding useless checks).
Bug: v8:6882
Change-Id: Ibffd8c36511f219fcce0d89ed4e1073f5d6c6344
Reviewed-on: https://chromium-review.googlesource.com/700254
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48275}
Until now keyed accesses to properties with string or symbol keys were
only optimized properly while the IC was monomorphic and would go
megamorphic as soon as there's another receiver map, even if the name
was still the same (i.e. the same symbol or internalized string). This
was a weird performance-cliff, that'll hurt modern code especially
because for symbols you can only access them via keyed loads and stores.
This CL fixes the state machine inside the ICs to properly transition to
POLYMORPHIC state (and stay there) as long as the new name matches the
previously recorded name. The FeedbackVector and TurboFan were already
able to deal with this and didn't need any updates.
On the micro-benchmark from the tracking bug we go from
testStringMonomorphic: 429 ms.
testSymbolMonomorphic: 431 ms.
testStringPolymorphic: 429 ms.
testSymbolPolymorphic: 5621 ms.
to
testStringMonomorphic: 429 ms.
testSymbolMonomorphic: 429 ms.
testStringPolymorphic: 429 ms.
testSymbolPolymorphic: 430 ms.
effectively eliminating the overhead for symbols completely, and
yielding a 13.5x performance boost.
This also seems to yield a 1% improvement on the ARES6 ML benchmark,
because it eliminates the KEYED_LOAD_ICs for the Symbol.species lookups.
Bug: v8:6367, v8:6278, v8:6344
Change-Id: I879fe56387b4c56203c1ad8ef8cafb6cc4c32897
Reviewed-on: https://chromium-review.googlesource.com/695108
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48261}
The TypedArray.prototype[Symbol.toStringTag] getter is currently the best (and
as far as I can tell only definitely side-effect free) way to check whether an
arbitrary object is a TypedArray - either generally TypedArray or a specific
one like Uint8Array. Using the getter is thus emerging as the general pattern
to detect TypedArrays, even Node.js now adapted it starting with
https://github.com/nodejs/node/pull/15663
for the isTypedArray and isUint8Array type checks in lib/internal/util/types.js
now.
The getter returns either the string with the TypedArray subclass name
(i.e. "Uint8Array") or undefined if the receiver is not a TypedArray.
This can be implemented with a simple elements kind dispatch, instead of
checking the instance type and then loading the class name from the
constructor, which requires a loop walking up the transition tree. This
CL ports the builtin to CSA and TurboFan, and changes the logic to a
simple elements kind check. On the micro-benchmark mentioned in the
referenced bug, the time goes from
testIsArrayBufferView: 565 ms.
testIsTypedArray: 2403 ms.
testIsUint8Array: 3847 ms.
to
testIsArrayBufferView: 566 ms.
testIsTypedArray: 965 ms.
testIsUint8Array: 965 ms.
which presents an up to 4x improvement.
Bug: v8:6874
Change-Id: I9c330b4529d9631df2f052acf023c6a4fae69611
Reviewed-on: https://chromium-review.googlesource.com/695021
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48254}
This is a reland of 9d3c4b4b91
Original change's description:
> [turbofan] Implement lowering of {JSCreateClosure}.
>
> This adds support for inline allocation of {JSFunction} objects as part
> of closures instantiation for {JSCreateClosure} nodes. The lowering is
> limited to instantiation sites which have already seen more than one
> previous instantiation, this avoids the need to increment the respective
> counter.
>
> R=jarin@chromium.org
>
> Change-Id: I462c557453fe58bc5f09020a3d5ebdf11c2ea68b
> Reviewed-on: https://chromium-review.googlesource.com/594287
> Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#48176}
Change-Id: I3ec3880bea89798a34a3878e6122b95db1014151
Reviewed-on: https://chromium-review.googlesource.com/686834
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48198}
This reverts commit 9d3c4b4b91.
Reason for revert: Breaks cctest/test-debug/NoBreakWhenBootstrapping in no-snap mode.
Original change's description:
> [turbofan] Implement lowering of {JSCreateClosure}.
>
> This adds support for inline allocation of {JSFunction} objects as part
> of closures instantiation for {JSCreateClosure} nodes. The lowering is
> limited to instantiation sites which have already seen more than one
> previous instantiation, this avoids the need to increment the respective
> counter.
>
> R=jarin@chromium.org
>
> Change-Id: I462c557453fe58bc5f09020a3d5ebdf11c2ea68b
> Reviewed-on: https://chromium-review.googlesource.com/594287
> Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#48176}
TBR=mstarzinger@chromium.org,jarin@chromium.org
Change-Id: Id52281f6a3c0b7c2603053ecf002777d5b0d6f1f
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/686534
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48178}
This adds support for inline allocation of {JSFunction} objects as part
of closures instantiation for {JSCreateClosure} nodes. The lowering is
limited to instantiation sites which have already seen more than one
previous instantiation, this avoids the need to increment the respective
counter.
R=jarin@chromium.org
Change-Id: I462c557453fe58bc5f09020a3d5ebdf11c2ea68b
Reviewed-on: https://chromium-review.googlesource.com/594287
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48176}
SetForceInlineFlag is now only used in tests. Earlier, it was also used
in js builtins, because unless this flag was specified the js builtins
were not inlined. All the performance critical js builtins are moved
to turbofan builtins and SetForceInlineFlag is no longer used. We would
like to remove this flag completely to simplify inlining heuristics.
Also, this uses a bit on the SharedFuntionInfo.
Bug: v8:6682
Change-Id: I19afd27381afc212f29179f2c5477095c8174f39
Reviewed-on: https://chromium-review.googlesource.com/660739
Commit-Queue: Mythri Alle <mythria@chromium.org>
Reviewed-by: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47997}
So far we didn't properly constant-fold JSToString operators in
JSTypedLowering where the input was a known number constant.
Bug: v8:6815
Change-Id: Iac87346b7d38f0f75461f285ea7daa2d5a5e1524
Reviewed-on: https://chromium-review.googlesource.com/663358
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47972}
When accessing elements of a global (constant) JSArray, whose backing
store is copy-on-write, we can just constant-fold the value and insert
a check that the backing store stays the same.
Bug: v8:6816, v8:6815
Change-Id: I090bcec7b1ce72a1f9ed8625680ed91e8c67f27f
Reviewed-on: https://chromium-review.googlesource.com/662757
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47963}
TurboFan wasn't able to inline calls to Array.prototype.push which
didn't have exactly one parameter. This was a rather artifical
limitation and was mostly due to the way the MaybeGrowFastElements
operator was implemented (which was not ideal by itself). Refactoring
this a bit, allows us to inline the operation in general, independent
of the number of values to push.
Array#push with multiple parameters is used quite a lot inside Ember (as
discovered by Apple, i.e. https://bugs.webkit.org/show_bug.cgi?id=175823)
and is also dominating the Six-Speed/SpreadLiterals/ES5 benchmark (see
https://twitter.com/SpiderMonkeyJS/status/906528938452832257 from the
SpiderMonkey folks). The micro-benchmark mentioned in the tracking bug
(v8:6808) improves from
arrayPush0: 2422 ms.
arrayPush1: 2567 ms.
arrayPush2: 4092 ms.
arrayPush3: 4308 ms.
to
arrayPush0: 798 ms.
arrayPush1: 2563 ms.
arrayPush2: 2623 ms.
arrayPush3: 2773 ms.
with this change, effectively removing the odd 50-60% performance
cliff that was associated with going from one parameter to two or
more.
Bug: v8:2229, v8:6808
Change-Id: Iffe4c1233903c04c3dc2062aad39d99769c8ab57
Reviewed-on: https://chromium-review.googlesource.com/657582
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47940}
The previous %StringCharCodeAt runtime entry (and the inlined intrinsic)
are obsolete and not used anymore (except in dedicated tests for this
runtime function), so remove it. And rename the %StringCharCodeAtRT
function, which is actually used to %StringCharCodeAt instead to have
a consistent naming scheme for runtime fallbacks.
Bug: v8:5049
Change-Id: I619429ef54f6efea61fc51ab9ed1d5cfe4417f99
Reviewed-on: https://chromium-review.googlesource.com/657719
Commit-Queue: Yang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47928}
The advantage of an explicit Abort that the interpreter and the compiler know
that aborting cannot continue or throw or deopt. As a result we generate less
code and we do not confuse the compiler if the environment is not set up for
throwing (as in the generator dispatch that fails validation in
crbug.com/762057).
Bug: chromium:762057
Change-Id: I3e88f78be32f31ac49b1845595255f802c405ed7
Reviewed-on: https://chromium-review.googlesource.com/657025
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47922}
Add support to the JSCallReducer to recognize JSConstruct nodes where
the target is the Object constructor, and reduce them to JSCreate
nodes if either
(a) no value is passed to the Object constructor, or
(b) the target and new.target are definitely not identical, by checking
whether both target and new.target are different HeapConstants
(if they are not, then the JSCreateLowering will not be able to
do a lot with the JSCreate anyways).
This should cover the relevant cases for subclassing appropriately. It
fixes the 3-4x slowdown on the micro-benchmark mentioned in the linked
bug,
baseNoExtends: 752 ms.
baseExtendsObject: 752 ms.
baseExtendsViaFactory: 751 ms.
and thus removes the performance cliff.
R=jarin@chromium.org
Bug: v8:6801
Change-Id: Id265fd1399302a67b5790a6d0156679920c58bdd
Reviewed-on: https://chromium-review.googlesource.com/657019
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47913}
We emitted rotation by 24 bits with bitwise and, but that is wrong
because the low 8 bits can wrap around and "leak" into the result.
Bug: chromium:739902
Change-Id: Id49251e89405afb1581b8c60cde808c2d8bf693d
Reviewed-on: https://chromium-review.googlesource.com/645848
Reviewed-by: Martyn Capewell <martyn.capewell@arm.com>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47746}
When calling
Object(value)
where the value is known to be a JSReceiver, we can just replace it with
value, as the Object constructor call is a no-op in that case. Otherwise
when value is known to be not null or undefined then we can replace the
Object constructor call with an invocation of ToObject.
This covers the common pattern found in bundles generated by Webpack,
where the Object constructor is used to call imported functions, i.e.
Object(module.foo)(1, 2, 3)
There's a lot of detail in https://github.com/webpack/webpack/issues/5600
on this matter and why this pattern was chosen.
Bug: v8:6772
Change-Id: I2b4f0b4542b68b97b337ce571d6d79946c73d8bb
Reviewed-on: https://chromium-review.googlesource.com/643868
Reviewed-by: Yang Guo <yangguo@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47728}
This change prevents constant folding of uninhabited RefenceEqual node
because that could widen a type (from None type to the type of the
boolean constant).
Hopefully, this is a temporary workaround that will be replaced
by a better dead code elimination.
Bug: v8:6631
Change-Id: Ie25e7d710aaf1d37c9adba60f92438570843dd5d
Reviewed-on: https://chromium-review.googlesource.com/627916
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47545}
This is in preparation to the removal of the FullCodeGenerator, we no
longer need the ability to stress the underlying implementation.
R=rmcilroy@chromium.org
BUG=v8:6409
Cq-Include-Trybots: master.tryserver.v8:v8_linux_noi18n_rel_ng
Change-Id: Iad3177d6de4a68b57c12a770b6e85ed7a9710254
Reviewed-on: https://chromium-review.googlesource.com/584747
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47276}
With TurboFan, there should no longer be any deopt loops (aside from
bugs). So, the "too many deopts" bailout is no longer needed, at least
in its current form.
This fixes an issue where deopt counts are leaked between native
contexts, resulting in optimization being disabled unnecessarily.
Bug: v8:6402
Change-Id: Ia06374ae6b5c2d473bcdd8eef1284bf02766c2fb
Reviewed-on: https://chromium-review.googlesource.com/588894
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46961}