Process feedback and hints for Lda/StaNamed bytecodes w.r.t. access on
the global proxy. This stores the property cells (or their absence) on
the JSGlobalProxyData.
Bug: v8:7790
Change-Id: Iadedea5494611c1b2ed38b6ce75687e084cc27f9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1499499
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60411}
ReduceArrayIndexOfIncludes didn't account for kUnreliableReceiverMaps.
Will think about a more robust mechanism for this.
Bug: chromium:944062
Change-Id: Ib2bdaf4399225de4413e12c5684f58dfe524a2cd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1532331
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60400}
There were four places where we did essentially the same steps in
order to extract the initial map for inlining a JSCreate operation.
This CL creates a function on NodeProperties for this task.
As a side effect, this fixes a bug in ReduceJSCreateArray, where
has_initial_map could get called when it wasn't permissible to do so.
Notes: For simplicity, in one or two places where we used to get the
target/newtarget constants from the types we now get them from
HeapConstant nodes.
Cosmetic change: rename "receiver_map" to the more accurate
"root_map" in JSNativeContextSpecialization::ExtractReceiverMaps.
Bug: chromium:939316
Change-Id: I8fd9eb50993be3d839ab9b18eeea28184c53eabf
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1528435
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60301}
If the branch associated with the condition is kDead, the current
node will be killed anyway, so let us just survive the lowering.
Bug: chromium:935092
Change-Id: If7b39e3b5452d6c9bc5199080eb38725e6c4eab5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1488769
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60143}
Causes flakyness in TSAN runs when flag is written by EnforceFlagImplications
and read by ConcurrentMarking.
BUG=v8:8924
Change-Id: I2b0bf0fbb678e03492d7ed13e48657de9316b700
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1505796
Auto-Submit: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Mythri Alle <mythria@chromium.org>
Reviewed-by: Mythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60062}
This piggy-backs off similar support for lite mode, which silently skips
tests that require optimization in lite (and now jitless) modes.
Bug: v8:7777,v8:8778, v8:8885
Change-Id: I666d92685ca71682224028743f02d0cce3723135
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1503758
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60057}
Bytecode flushing can make tests using assertOptimized flaky if the bytecode is
flushed between marking and optimization. It can also be flaky if the feedback vector
is collected before optimization. To prevent this, a new %PrepareForOptimization
runtime-test function is added that hold onto the bytecode strongly until it is
optimized after being explicitly marked for optimization by %OptimizeFunctionOnNextCall.
BUG=v8:8801,v8:8395
Change-Id: Idbd962a3a2044b915903f9c5e92d1789942b5b41
Reviewed-on: https://chromium-review.googlesource.com/c/1463525
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59914}
When calling a known function from optimized code, where the number of
actual arguments does not match the number of expected arguments,
TurboFan has to call indirectly via the arguments adaptor trampoline,
which creates an argument adaptor frame underneath the activation record
for the callee. This is done so that the callee can still get to the
actual arguments, using either
1. the arguments object, or
2. rest parameters (to get to superfluous arguments), or
3. the non-standard Function.arguments accessor (for sloppy mode
functions), or
4. direct eval(), where we don't know whether there's a use of the
arguments object hiding somewhere in the string.
However going through the arguments adaptor trampoline is quite
expensive usually, it seems to be responsible for over 60% of the
call overhead in those cases.
So this adds a fast path for the case of calling strict mode functions
where we have an arguments mismatch, but where we are sure that the
callee cannot observe the actual arguments. We use a bit on the
SharedFunctionInfo to indicate that this is safe, which is controlled
by hints from the Parser which knows whether the callee uses either
arguments object or rest parameters.
In those cases we use a direct call from optimized code, passing the
expected arguments instead of the actual arguments. This improves the
benchmark on the document below by around 60-65%, which is exactly
the overhead of the arguments adaptor trampoline that we save in this
case.
This also adds a runtime flag --fast_calls_with_arguments_mismatches,
which can be used to turn off the new behavior. This might be handy
for checking the performance impact via Finch.
Bug: v8:8895
Change-Id: Idea51dba7ee6cb989e86e0742eaf3516e5afe3c4
Cq-Include-Trybots: luci.chromium.try:linux-blink-rel
Doc: http://bit.ly/v8-faster-calls-with-arguments-mismatch
Reviewed-on: https://chromium-review.googlesource.com/c/1482735
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59825}
This lets me run tests with --no-turbo-inlining without having to
worry about false positives.
Change-Id: Icf906e631ef5821136f397af141ba8b18334da7e
Reviewed-on: https://chromium-review.googlesource.com/c/1477730
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59707}
... more precisely, do not mess up the exceptional edges.
Bug: chromium:924151
Change-Id: I3541a1c339c07f509519d4ece6d677dd499f181e
Reviewed-on: https://chromium-review.googlesource.com/c/1429860
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59063}
If feedback for call site frequency is 0, then the combined frequency
is still 0, even if the current function invocation count is infinity.
Bug: chromium:919754
Change-Id: I97be096b6b38f934fb13f01b2b22e148c539e1c0
Reviewed-on: https://chromium-review.googlesource.com/c/1404445
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58714}
Also disables --stress-flush-bytecode on some mjsunit tests which fail
when bytecode flushing is stressed due to test invariants.
Bug=v8:8395
Change-Id: If627910214b3c266e7776340ba182829148e8289
Reviewed-on: https://chromium-review.googlesource.com/c/1372071
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58230}
We assert that loops always have effect phis because there must be
a stack check in every loop. However, with generators, the stack check
may end up outside of loop because the dispatch switch is built first
(while the dispatch switch will also keep the loop backedge alive).
The logic for creating effect phis is already in the code, so
removing the dcheck should be fine.
Bug: chromium:913232
Change-Id: Icf4df831e8b47350543c2b82a34bd3af98782a16
Reviewed-on: https://chromium-review.googlesource.com/c/1372065
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58160}
This is purely a renaming change. The ES spec uses the term 'detach'
for the process of removing the backing store of a typed array, while
V8 uses the historical term 'neuter'. Update our internal implementation,
including method names and flag names, to match the spec.
Note that some error messages still use the term 'neuter' since error
messages are asserted by some embedder tests, like layout tests.
R=bmeurer@chromium.org, yangguo@chromium.org, mstarzinger@chromium.org, mlippautz@chromium.org
BUG=chromium:913887
Change-Id: I62f1c3ac9ae67ba01d612a5221afa3d92deae272
Reviewed-on: https://chromium-review.googlesource.com/c/1370036
Commit-Queue: Ben Titzer <titzer@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58149}
Currently, if we lower to a pure computation that is unreachable because
of some runtime check, we just rename it with DeadValue. This is
problematic if the pure computation gets later eliminated - that allows
the DeadValue node float above the check that makes it dead. As we
conservatively lower DeadValues to debug-break (i.e., crash), we
might induce crash where we should not.
With this CL, whenever we lower an impossible effectful node (i.e., with
Type::None) to a pure node in simplified lowering, we insert an
Unreachable node there (pinned to the effect chain) and mark the
impossible node dead (and make it depend on the Unreachable node).
Bug: chromium:910838
Change-Id: I218991c79b9e283a9dd5beb4d3f0c4664be76cb2
Reviewed-on: https://chromium-review.googlesource.com/c/1365274
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58066}
This CL moves optimization capabilities from typed lowering to typed
optimization. In particular, this allows retyping of Speculative to
number optimizations depending on their input types. This can save type
checks if we know that inputs are already in SafeIntegerRange and uses
are truncating to 32bit integers.
This change recovers the performance lost to 31bit Smis on
Octane/crypto on x64:
32bit nosmis avg 30,984.84 stddev 180.52
31bit smis (w/o patch) avg 29,438.52 stddev 120.30 -4.99%
31bit smis avg 31,274.52 stddev 176.26 +0.93% +6.24%
Change-Id: I86d6e37305262336f4f7bd46aac0d2cbca11e8c1
Bug: v8:8344
Reviewed-on: https://chromium-review.googlesource.com/c/1323729
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57717}
This is a reland of 585b4eef6a without
any changes.
Original change's description:
> [turbofan] Improve NumberMultiply typing rule.
>
> The NumberMultiply typing rule gave up in the presence of NaN inputs,
> but we can still infer useful ranges here and just union the result
> of that with the NaN propagation (similar for MinusZero propagation).
> This way we can still makes sense of these ranges at the uses.
>
> Bug: v8:8015
> Change-Id: Ic4c5e8edc6c68776ff3baca9628ad7de0f8e2a92
> Reviewed-on: https://chromium-review.googlesource.com/c/1261143
> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
> Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#56539}
Tbr: bmeurer@chromium.org
Bug: v8:8015
Change-Id: I32e5c2f439a1186891ca3393ee53a2a766585839
Reviewed-on: https://chromium-review.googlesource.com/c/1345993
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57664}
This reverts commit 585b4eef6a.
Reason for revert: Speculative, crbug 906567.
Original change's description:
> [turbofan] Improve NumberMultiply typing rule.
>
> The NumberMultiply typing rule gave up in the presence of NaN inputs,
> but we can still infer useful ranges here and just union the result
> of that with the NaN propagation (similar for MinusZero propagation).
> This way we can still makes sense of these ranges at the uses.
>
> Bug: v8:8015
> Change-Id: Ic4c5e8edc6c68776ff3baca9628ad7de0f8e2a92
> Reviewed-on: https://chromium-review.googlesource.com/c/1261143
> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
> Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#56539}
TBR=sigurds@chromium.org,bmeurer@chromium.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: v8:8015
Change-Id: I3c652bafbbc0e5d1ad4ff288264fd4f4cbf71330
Reviewed-on: https://chromium-review.googlesource.com/c/1340253
Reviewed-by: Georg Neis <neis@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57602}
Fail IsInvalid check if the property cell has been invalidated.
Bug: chromium:905555
Change-Id: Ia0712b97bd6ba628936b74b3893ddb1c229ee686
Reviewed-on: https://chromium-review.googlesource.com/c/1339863
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57597}
This fixes several problems with instanceof and constant field tracking
in the compiler:
- properly bailout on numbers and non-functions at @@hasInstance.
- deopt on changes of @@hasInstance property.
Bug: v8:8361
Change-Id: I4a1cf9e29d72076f2d37a7c703f18cb2fb8f4040
Reviewed-on: https://chromium-review.googlesource.com/c/1322449
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57532}
As opposed to the register.
For subtle reasons, this fixes a deoptimizer bug with handling return
values in lazy deopt. Since the return values can now only overwrite
the accumulator, there is no danger of overwriting a captured object
that might be later used (since there is no "later").
Bug: chromium:902608
Change-Id: I3a7a10bb1c7a6f4303a01d60f80680afcb7bc942
Reviewed-on: https://chromium-review.googlesource.com/c/1325901
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57349}
This test currently takes nearly 10 minutes on the arm64 debug builder.
Bug: v8:7783
Change-Id: I500fc026b01873e666f32062d790eca3f34455b9
Reviewed-on: https://chromium-review.googlesource.com/c/1318495
Commit-Queue: Adam Klein <adamk@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57298}
BinaryNumberOpTyper was not monotonic: if one input changes
from Number to Numeric, while the other input stays BigInt,
the result would change from Number to BigInt.
We have some fuzzing tests for monotonicity but unfortunately
they never generated the inputs required for triggering this bug.
We'll look into improving our tests.
Bug: v8:8380
Change-Id: I7320d9ae4b89ad8798bf9e97cc272edba2162a77
Reviewed-on: https://chromium-review.googlesource.com/c/1307418
Commit-Queue: Hai Dang <dhai@google.com>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57125}
This adds appropriate LoopExit nodes for the JSCallReducer lowerings of
the following higher order Array builtins:
- Array.prototype.every()
- Array.prototype.find()
- Array.prototype.findIndex()
- Array.prototype.some()
Loop peeling allows TurboFan to make loop invariant operations in the
callback passed to the higher order builtin fully redundant, and thus
completely eliminate the loop invariant code from the subsequent loop
iterations. This can have a huge performance impact, depending on what
kind of code runs inside of the callback. For example, on the micro-
benchmarks outlined in http://crbug.com/v8/8273 we go from
forLoop: 364 ms.
every: 443 ms.
some: 432 ms.
find: 522 ms.
findIndex: 437 ms.
to
forLoop: 369 ms.
every: 354 ms.
some: 348 ms.
find: 419 ms.
findIndex: 360 ms.
which is 20% improvement, and essentially brings the Array builtins (the
appropriate ones Array#some() and Array#every() in this case) on par
with the hand-written `for`-loop.
Bug: v8:1956, v8:8273
Change-Id: I9d32736e5402807b4ac79cd5ad15ceacd1945681
Reviewed-on: https://chromium-review.googlesource.com/c/1305935
Reviewed-by: Daniel Clifford <danno@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57110}
This introduces Word64 support for the CheckBounds operator, which now
lowers to either CheckedUint32Bounds or CheckedUint64Bounds after the
representation selection. The right hand side of CheckBounds can now
be any positive safe integer on 64-bit architectures, whereas it remains
Unsigned31 for 32-bit architectures. We only use the extended Word64
support when the right hand side is outside the Unsigned31 range, so
for everything except DataViews this means that the performance should
remain the same. The typing rule for the CheckBounds operator was
updated to reflect this new behavior.
The CheckBounds with a right hand side outside the Unsigned31 range will
pass a new Signed64 feedback kind, which is handled with newly introduced
CheckedFloat64ToInt64 and CheckedTaggedToInt64 operators in representation
selection.
The JSCallReducer lowering for DataView getType()/setType() methods was
updated to not smi-check the [[ByteLength]] and [[ByteOffset]] anymore,
but instead just use the raw uintptr_t values and operate on any value
(for 64-bit architectures these fields can hold any positive safe
integer, for 32-bit architectures it's limited to Unsigned31 range as
before). This means that V8 can now handle huge DataViews fully, without
falling off a performance cliff.
This refactoring even gave us some performance improvements, on a simple
micro-benchmark just exercising different DataView accesses we go from
testDataViewGetUint8: 796 ms.
testDataViewGetUint16: 997 ms.
testDataViewGetInt32: 994 ms.
testDataViewGetFloat64: 997 ms.
to
testDataViewGetUint8: 895 ms.
testDataViewGetUint16: 889 ms.
testDataViewGetInt32: 888 ms.
testDataViewGetFloat64: 890 ms.
meaning we lost around 10% on the single byte case, but gained 10% across
the board for all the other element sizes.
Design-Document: http://bit.ly/turbofan-word64
Bug: chromium:225811, v8:4153, v8:7881, v8:8171, v8:8383
Change-Id: Ic9d1bf152e47802c04dcfd679372e5c85e4abc83
Reviewed-on: https://chromium-review.googlesource.com/c/1303732
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57095}
For NumberMin and NumberMax we don't need to go to Float64 when the
inputs are known to be in SafeInteger range, instead we can go to
Word64 on 64-bit architectures. This is preliminary work for the
huge DataView support, since we'll utilize NumberMax in that case
to clamp the limit for the bounds check.
Bug: v8:8178, v8:8383
Change-Id: I414114229c5c86b92749d30d645cedc641541ae4
Reviewed-on: https://chromium-review.googlesource.com/c/1304535
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57090}
This changes the ReceiverOrOddball feedback on JSStrictEqual to
ReceiverOrNullOrUndefined feedback, which can also safely be
consumed by JSEqual (we cannot generally accept any oddball here
since booleans trigger implicit conversions, unfortunately).
Thus we replace the previously introduced CheckReceiverOrOddball
with CheckReceiverOrNullOrUndefined, and drop CheckOddball, since
we will no longer collect Oddball feedback separately.
TurboFan will then turn a JSEqual[ReceiverOrNullOrUndefined] into
a sequence like this:
```
left = CheckReceiverOrNullOrUndefined(left);
right = CheckReceiverOrNullOrUndefined(right);
result = if ObjectIsUndetectable(left) then
ObjectIsUndetectable(right)
else
ReferenceEqual(left, right);
```
This significantly improves the peak performance of abstract equality
with Receiver, Null or Undefined inputs. On the test case outlined in
http://crbug.com/v8/8356 we go from
naive: 2946 ms.
tenary: 2134 ms.
to
naive: 2230 ms.
tenary: 2250 ms.
which corresponds to a 25% improvement on the abstract equality case.
For regular code this will probably yield more performance, since we
get rid of the JSEqual operator, which might have arbitrary side
effects and thus blocks all kinds of TurboFan optimizations. The
JSStrictEqual case is slightly slower now, since it has to rule out
booleans as well (even though that's not strictly necessary, but
consistency is key here).
This way developers can safely use `a == b` instead of doing a dance
like `a == null ? b == null : a === b` (which is what dart2js does
right now) when both `a` and `b` are known to be Receiver, Null or
Undefined. The abstract equality is not only faster to parse than
the tenary, but also generates a shorter bytecode sequence. In the
test case referenced in http://crbug.com/v8/8356 the bytecode for
`naive` is
```
StackCheck
Ldar a1
TestEqual a0, [0]
JumpIfFalse [5]
LdaSmi [1]
Return
LdaSmi [2]
Return
```
which is 14 bytes, whereas the `tenary` function generates
```
StackCheck
Ldar a0
TestUndetectable
JumpIfFalse [7]
Ldar a1
TestUndetectable
Jump [7]
Ldar a1
TestEqualStrict a0, [0]
JumpIfToBooleanFalse [5]
LdaSmi [1]
Return
LdaSmi [2]
Return
```
which is 24 bytes. So the `naive` version is 40% smaller and requires
fewer bytecode dispatches.
Bug: chromium:898455, v8:8356
Change-Id: If3961b2518b4438700706b3bd6071d546305e233
Reviewed-on: https://chromium-review.googlesource.com/c/1297315
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56948}
This CL introduces proper Oddball and ReceiverOrOddball states for the
CompareOperationFeedback, and updates the StrictEqual IC to collect this
feedback as well. Previously it would not collect Oddball feedback, not
even in the sense of NumberOrOddball, since that's not usable for the
SpeculativeNumberEqual.
The new feedback is handled via newly introduced CheckReceiverOrOddball
and CheckOddball operators in TurboFan, introduced by JSTypedLowering.
Just like with the Receiver feedback, it's enough to check one side and
do a ReferenceEqual afterwards, since strict equal can only yield true
if both sides refer to the same instance.
This improves the benchmark mentioned in http://crbug.com/v8/8356 from
naive: 2950 ms.
tenary: 2456 ms.
to around
naive: 2996 ms.
tenary: 2192 ms.
which corresponds to a roughly 10% improvement in the case for the
tenary pattern, which is currently used by dart2js. In real world
scenarios this will probably help even more, since TurboFan is able
to optimize across the strict equality, i.e. there's no longer a stub
call forcibly spilling all registers that are live across the call.
This new feedback will be used as a basis for the JSEqual support for
ReceiverOrOddball, which will allow dart2js switching to the shorter
a==b form, at the same peak performance.
Bug: v8:8356
Change-Id: Iafbf5d64fcc9312f9e575b54c32c631ce9b572b2
Reviewed-on: https://chromium-review.googlesource.com/c/1297309
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56925}
When InferReceiverMaps doesn't provide us with reliable maps for the
resolution, we can still utilize the information if all the maps that
are found are stable - aka leaf - maps. But in that case we need to
make sure that we add proper dependencies on the stability of these
maps.
Bug: v8:7253
Change-Id: I6f5825583acc3f2575e83a244d55609ac64d04d3
Reviewed-on: https://chromium-review.googlesource.com/c/1288633
Reviewed-by: Georg Neis <neis@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56789}
The NumberMultiply typing rule gave up in the presence of NaN inputs,
but we can still infer useful ranges here and just union the result
of that with the NaN propagation (similar for MinusZero propagation).
This way we can still makes sense of these ranges at the uses.
Bug: v8:8015
Change-Id: Ic4c5e8edc6c68776ff3baca9628ad7de0f8e2a92
Reviewed-on: https://chromium-review.googlesource.com/c/1261143
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56539}
This change introduces new intrinsics used to desugar async functions
in the Parser and the BytecodeGenerator, namely we introduce a new
%_AsyncFunctionEnter intrinsic that constructs the generator object
for the async function (and in the future will also create the outer
promise for the async function). This generator object is internal
and never escapes to user code, plus since async functions don't have
a "prototype" property, we can just a single map here instead of tracking
the prototype/initial_map on every async function. This saves one word
per async function plus one initial_map per async function that was
invoked at least once.
We also introduce two new intrinsics %_AsyncFunctionReject, which
rejects the outer promise with the caught exception, and another
%_AsyncFunctionResolve, which resolves the outer promise with the
right hand side of the `return` statement. These functions also perform
the DevTools part of the job (aka popping from the promise stack and
sending the debug event). This allows us to get rid of the implicit
try-finally from async functions completely; because the finally
block only called to the %AsyncFunctionPromiseRelease builtin, which
was used to inform DevTools.
In essence we now turn an async function like
```js
async function f(x) { return await bar(x); }
```
into something like this (in Parser and BytecodeGenerator respectively):
```
function f(x) {
.generator_object = %_AsyncFunctionEnter(.closure, this);
.promise = %AsyncFunctionCreatePromise();
try {
.tmp = await bar(x);
return %_AsyncFunctionResolve(.promise, .tmp);
} catch (e) {
return %_AsyncFunctionReject(.promise, e);
}
}
```
Overall the bytecode for async functions gets significantly shorter
already (and will get even shorter once we put the outer promise into
the async function generator object). For example the bytecode for a
simple async function
```js
async function f(x) { return await x; }
```
goes from 175 bytes to 110 bytes (a ~38% reduction in size), which
is in particular due to the simplification around the try-finally
removal.
Overall this seems to improve the doxbee-async-es2017-native test by
around 2-3%. On the test case mentioned in v8:8276 we go from
1124ms to 441ms, which corresponds to a 60% reduction in total
execution time!
Tbr: marja@chromium.org
Bug: v8:7253, v8:7522, v8:8276
Cq-Include-Trybots: luci.chromium.try:linux_chromium_headless_rel;luci.chromium.try:linux_chromium_rel_ng;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: Id29dc92de7490b387ff697860c900cee44c9a7a4
Reviewed-on: https://chromium-review.googlesource.com/c/1269041
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Maya Lekova <mslekova@chromium.org>
Reviewed-by: Yang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56502}
This adds support to the escape analysis to allow scalar replacement
of (small) FixedArrays with element accesses where the index is not a
compile time constant. This happens quite often when inlining functions
that operate on variable number of arguments. For example consider this
little piece of code:
```js
function sum(...args) {
let s = 0;
for (let i = 0; i < args.length; ++i) s += args[i];
return s;
}
function sum2(x, y) {
return sum(x, y);
}
```
This example is made up, of course, but it shows the problem. Let's
assume that TurboFan inlines the function `sum` into it's call site
at `sum2`. Now it has to materialize the `args` array with the two
values `x` and `y`, and iterate through these `args` to sum them up.
The escape analysis pass figures out that `args` doesn't escape (aka
doesn't outlive) the optimized code for `sum2` now, but TurboFan still
needs to materialize the elements backing store for `args` since there's
a `LoadElement(args.elements,i)` in the graph now, and `i` is not a
compile time constant.
However the escape analysis has more information than just that. In
particular the escape analysis knows exactly how many elements a non
escaping object has, based on the fact that the allocation must be
local to the function and that we only track objects with known size.
So in the case above when we get to `args[i]` in the escape analysis
the relevant part of the graph looks something like this:
```
elements = LoadField[elements](args)
length = LoadField[length](args)
index = CheckBounds(i, length)
value = LoadElement(elements, index)
```
In particular the contract here is that `LoadElement(elements,index)`
is guaranteed to have an `index` that is within the valid bounds for
the `elements` (there must be a preceeding `CheckBounds` or some other
guard in optimized code before it). And since `elements` is allocated
inside of the optimized code object, the escape analysis also knows
that `elements` has exactly two elements inside (namely the values of
`x` and `y`). So we can use that information and replace the access
with a `Select(index===0,x,y)` operation instead, which allows us to
scalar replace the `elements`, since there's no escaping use anymore
in the graph.
We do this for the case that the number of elements is 2, as described
above, but also for the case where elements length is one. In case
of 0, we know that the `LoadElement` must be in dead code, but we can't
just mark it for deletion from the graph (to make sure it doesn't block
scalar replacement of non-dead code), so we don't handle this for now.
And for one element it's even easier, since the `LoadElement` has to
yield exactly said element.
We could generalize this to handle arbitrary lengths, but since there's
a cost to arbitrary decision trees here, it's unclear when this is still
beneficial. Another possible solution for length > 2 would be to have
special stack allocation for these backing stores and do variable index
accesses to these stack areas. But that's way beyond the scope of this
isolated change.
This change shows a ~2% improvement on the EarleyBoyer benchmark in
JetStream, since it benefits a lot from not having to materialize these
small arguments backing stores.
Drive-by-fix: Fix JSCreateLowering to properly initialize "elements"
with StoreElement instead of StoreField (which violates the invariant
in TurboFan that fields and elements never alias).
Bug: v8:5267, v8:6200
Change-Id: Idd464a15a81e7c9653c48c814b406eb859841428
Reviewed-on: https://chromium-review.googlesource.com/c/1267935
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56442}
This change adds predicates to check whether a given JavaScript operator
needs the "current context" or if any surrounding context (including the
"native context") does it. For example JSAdd doesn't ever need the
current context, but actually only the native context. In the
BytecodeGraphBuilder we use this predicate to check whether a given
operator needs the current context, and if not, we just pass in the
native context.
Doing so we improve the performance on the benchmarks given in the
tracking bug significantly, and go from something around
arrayMap: 476 ms.
arrayFilter: 312 ms.
arrayEvery: 241 ms.
arraySome: 152 ms.
to
arrayMap: 377 ms.
arrayFilter: 296 ms.
arrayEvery: 191 ms.
arraySome: 91 ms.
which is an up to 40% improvement. So for idiomatic modern JavaScript
which uses higher order functions quite a lot, not just the builtins
provided by the JSVM, this is going to improve peak performance
noticably.
This also makes it possible to completely eliminate all the allocations
in the aliased sloppy arguments example
```js
function foo(a) { return arguments.length; }
```
concretely we don't allocate the function context anymore and we also
don't allocate the arguments object anymore (the JSStackCheck was the
reason why we did this in the past, because it was holding on to the
current context, which also kept the allocation for the arguments
alive).
Bug: v8:6200, v8:8060
Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef
Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators
Reviewed-on: https://chromium-review.googlesource.com/c/1267176
Reviewed-by: Georg Neis <neis@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56441}
As identified in the web-tooling-benchmark, there are specific code
patterns involving array indexed property accesses and subsequent
comparisons of those indices that lead to repeated Smi checks in the
optimized code, which in turn leads to high register pressure and
generally bad register allocation. An example of this pattern is
code like this:
```js
function f(a, n) {
const i = a[n];
if (n >= 1) return i;
}
```
The `a[n]` property access introduces a CheckBounds on `n`, which
later lowers to a `CheckedTaggedToInt32[dont-check-minus-zero]`,
however the `n >= 1` comparison has collected `SignedSmall` feedback
and so it introduces a `CheckedTaggedToTaggedSigned` operation. This
second Smi check is redundant and cannot easily be combined with the
earlier tagged->int32 conversion, since that also deals with heap
numbers and even truncates -0 to 0.
So we teach the RedundancyElimination to look at the inputs of these
speculative number comparisons and if there's a leading bounds check
on either of these inputs, we change the input to the result of the
bounds check. This avoids the redundant Smi checks later and generally
allows the SimplifiedLowering to do a significantly better job on the
number comparisons. We only do this in case of SignedSmall feedback
and only for inputs that are not already known to be in UnsignedSmall
range, to avoid doing too many (unnecessary) expensive lookups during
RedundancyElimination.
All of this is safe despite the fact that CheckBounds truncates -0
to 0, since the regular number comparisons in JavaScript identify
0 and -0 (unlike Object.is()). This also adds appropriate tests,
especially for the interesting cases where -0 is used only after
the code was optimized.
Bug: v8:6936, v8:7094
Change-Id: Ie37114fb6192e941ae1a4f0bfe00e9c0a8305c07
Reviewed-on: https://chromium-review.googlesource.com/c/1246181
Reviewed-by: Sigurd Schneider <sigurds@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56428}
This reverts commit 4fd92b252b.
Reason for revert: Significant tankage on the no-mitigations bots (bad timing on the regular bots)
Original change's description:
> [turbofan] Do not consume SignedSmall feedback in TurboFan anymore.
>
> This changes TurboFan to treat SignedSmall feedback similar to Signed32
> feedback for binary and compare operations, in order to simplify and
> unify the machinery.
>
> This is an experiment. If this turns out to tank performance, we will
> need to revisit and ideally revert this change.
>
> Bug: v8:7094
> Change-Id: I885769c2fe93d8413e59838fbe844650c848c3f1
> Reviewed-on: https://chromium-review.googlesource.com/c/1261442
> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#56411}
TBR=jarin@chromium.org,bmeurer@chromium.org
# Not skipping CQ checks because original CL landed > 1 day ago.
Bug: v8:7094
Change-Id: I9fff3b40e6dc0ceb7611b55e1ca9940089470404
Reviewed-on: https://chromium-review.googlesource.com/c/1267175
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56427}
This changes TurboFan to treat SignedSmall feedback similar to Signed32
feedback for binary and compare operations, in order to simplify and
unify the machinery.
This is an experiment. If this turns out to tank performance, we will
need to revisit and ideally revert this change.
Bug: v8:7094
Change-Id: I885769c2fe93d8413e59838fbe844650c848c3f1
Reviewed-on: https://chromium-review.googlesource.com/c/1261442
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56411}
The CheckSmi in String.fromCodePoint() is unnecessary and even leads to
unnecessary deoptimizations, since the CheckBounds already does the
right thing, plus it also handles HeapNumbers (in Signed32 range) and
properly identifies zeros.
Bug: v8:8238
Change-Id: I73bf7a70c3cd718c987f112ceb928188c0534cd5
Reviewed-on: https://chromium-review.googlesource.com/c/1262675
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56395}