[TurboFan] Array.prototype.map inlining error

A Phi is necessary to carry the ElementsKind forward in case transitions
are taken.

Bug: chromium:747075
Change-Id: I9d9d66b0219fe3f67d08536f4d478ee300c76acb
Reviewed-on: https://chromium-review.googlesource.com/583090
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46852}
This commit is contained in:
Mike Stanton 2017-07-24 16:36:05 +02:00 committed by Commit Bot
parent 46d815e737
commit d9b98f3d05
2 changed files with 29 additions and 8 deletions

View File

@ -2814,7 +2814,7 @@ void EffectControlLinearizer::TransitionElementsTo(Node* node, Node* array,
Node* EffectControlLinearizer::IsElementsKindGreaterThan(
Node* kind, ElementsKind reference_kind) {
Node* ref_kind = __ Int32Constant(reference_kind);
Node* ret = __ Int32LessThanOrEqual(ref_kind, kind);
Node* ret = __ Int32LessThan(ref_kind, kind);
return ret;
}
@ -2831,17 +2831,21 @@ void EffectControlLinearizer::LowerTransitionAndStoreElement(Node* node) {
// if kind == HOLEY_SMI_ELEMENTS {
// if value is heap number {
// Transition array to HOLEY_DOUBLE_ELEMENTS
// kind = HOLEY_DOUBLE_ELEMENTS
// } else {
// Transition array to HOLEY_ELEMENTS
// kind = HOLEY_ELEMENTS
// }
// } else if kind == HOLEY_DOUBLE_ELEMENTS {
// if value is not heap number {
// Transition array to HOLEY_ELEMENTS
// kind = HOLEY_ELEMENTS
// }
// }
// }
//
// -- STORE PHASE ----------------------
// [make sure {kind} is up-to-date]
// if kind == HOLEY_DOUBLE_ELEMENTS {
// if value is smi {
// float_value = convert smi to float
@ -2865,9 +2869,9 @@ void EffectControlLinearizer::LowerTransitionAndStoreElement(Node* node) {
kind = __ Word32Shr(andit, shift);
}
auto do_store = __ MakeLabel<6>();
auto do_store = __ MakeLabel<6>(MachineRepresentation::kWord32);
Node* check1 = ObjectIsSmi(value);
__ GotoIf(check1, &do_store);
__ GotoIf(check1, &do_store, kind);
{
// {value} is a HeapObject.
Node* check2 = IsElementsKindGreaterThan(kind, HOLEY_SMI_ELEMENTS);
@ -2885,30 +2889,33 @@ void EffectControlLinearizer::LowerTransitionAndStoreElement(Node* node) {
// {value} is a HeapNumber.
TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS,
HOLEY_DOUBLE_ELEMENTS);
__ Goto(&do_store);
__ Goto(&do_store, __ Int32Constant(HOLEY_DOUBLE_ELEMENTS));
}
__ Bind(&if_value_not_heap_number);
{
TransitionElementsTo(node, array, HOLEY_SMI_ELEMENTS, HOLEY_ELEMENTS);
__ Goto(&do_store);
__ Goto(&do_store, __ Int32Constant(HOLEY_ELEMENTS));
}
}
__ Bind(&if_array_not_fast_smi);
{
Node* check3 = IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS);
__ GotoUnless(check3, &do_store);
__ GotoUnless(check3, &do_store, kind);
// We have double elements kind.
Node* value_map = __ LoadField(AccessBuilder::ForMap(), value);
Node* heap_number_map = __ HeapNumberMapConstant();
Node* check4 = __ WordEqual(value_map, heap_number_map);
__ GotoIf(check4, &do_store);
__ GotoIf(check4, &do_store, kind);
// But the value is not a heap number, so we must transition.
TransitionElementsTo(node, array, HOLEY_DOUBLE_ELEMENTS, HOLEY_ELEMENTS);
__ Goto(&do_store);
__ Goto(&do_store, __ Int32Constant(HOLEY_ELEMENTS));
}
}
// Make sure kind is up-to-date.
__ Bind(&do_store);
kind = do_store.PhiAt(0);
Node* elements = __ LoadField(AccessBuilder::ForJSObjectElements(), array);
Node* check2 = IsElementsKindGreaterThan(kind, HOLEY_ELEMENTS);
auto if_kind_is_double = __ MakeLabel<1>();

View File

@ -0,0 +1,14 @@
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
r = [
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14
];
for (i = -1; i < 100000; i++) {
r2 = r.map(function(y) {return y/64} );
assertTrue(r2[0] < 1);
}