Commit e65c0b25 authored by Benedikt Meurer's avatar Benedikt Meurer Committed by Commit Bot

[turbofan] Don't go MEGAMORPHIC when storing oddballs to typed arrays.

The KEYED_STORE_IC was never able to deal with stores to typed arrays
where the value being stored is not already a Number (i.e. either a Smi
or a HeapNumber). By extending it to also handle Oddballs (i.e. true,
false, undefined and null) and teaching TurboFan to also perform the
appropriate check plus the truncation to Number, we can easily support
this use case as well.

On the micro-benchmark in the bug report, we go from

  typedArrayStoreBool: 2975 ms.
  typedArrayStoreInt: 44 ms.

to

  typedArrayStoreBool: 43 ms.
  typedArrayStoreInt: 44 ms.

so that's roughly a 70x performance boost.

Bug: chromium:287773
Change-Id: I227419aeabc3f5b6793aa280a95448d03ac2f2dd
Reviewed-on: https://chromium-review.googlesource.com/691731
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarMichael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48257}
parent 9debe441
......@@ -7003,10 +7003,15 @@ Node* CodeStubAssembler::PrepareValueForWriteToTypedArray(
}
VARIABLE(var_result, rep);
Label done(this, &var_result), if_smi(this);
Label done(this, &var_result), if_smi(this), if_heapnumber(this);
GotoIf(TaggedIsSmi(input), &if_smi);
// Try to convert a heap number to a Smi.
GotoIfNot(IsHeapNumber(input), bailout);
// We can handle both HeapNumber and Oddball here, since Oddball has the
// same layout as the HeapNumber for the HeapNumber::value field. This
// way we can also properly optimize stores of oddballs to typed arrays.
GotoIf(IsHeapNumber(input), &if_heapnumber);
Branch(HasInstanceType(input, ODDBALL_TYPE), &if_heapnumber, bailout);
BIND(&if_heapnumber);
{
Node* value = LoadHeapNumberValue(input);
if (rep == MachineRepresentation::kWord32) {
......
......@@ -2160,9 +2160,12 @@ JSNativeContextSpecialization::BuildElementAccess(
UNREACHABLE();
break;
case AccessMode::kStore: {
// Ensure that the {value} is actually a Number.
value = effect = graph()->NewNode(simplified()->CheckNumber(), value,
effect, control);
// Ensure that the {value} is actually a Number or an Oddball,
// and truncate it to a Number appropriately.
value = effect =
graph()->NewNode(simplified()->SpeculativeToNumber(
NumberOperationHint::kNumberOrOddball),
value, effect, control);
// Introduce the appropriate truncation for {value}. Currently we
// only need to do this for ClamedUint8Array {receiver}s, as the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment