diff --git a/src/compiler/js-call-reducer.cc b/src/compiler/js-call-reducer.cc index 18ac8143e7..e281560320 100644 --- a/src/compiler/js-call-reducer.cc +++ b/src/compiler/js-call-reducer.cc @@ -1029,8 +1029,7 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle function, if (!CanInlineArrayIteratingBuiltin(receiver_map)) { return NoChange(); } - if (!IsFastElementsKind(next_kind) || - (IsDoubleElementsKind(next_kind) && IsHoleyElementsKind(next_kind))) { + if (!IsFastElementsKind(next_kind) || IsHoleyElementsKind(next_kind)) { return NoChange(); } if (IsDoubleElementsKind(kind) != IsDoubleElementsKind(next_kind)) { @@ -1068,15 +1067,15 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle function, &control, &check_fail, &check_throw); // Set initial accumulator value - Node* cur = nullptr; + Node* cur = jsgraph()->TheHoleConstant(); Node* initial_element_check_fail = nullptr; Node* initial_element_check_throw = nullptr; if (node->op()->ValueInputCount() > 3) { cur = NodeProperties::GetValueInput(node, 3); } else { - Node* check = graph()->NewNode(simplified()->NumberEqual(), original_length, - jsgraph()->SmiConstant(0)); + Node* check = + graph()->NewNode(simplified()->NumberEqual(), original_length, k); Node* check_branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); initial_element_check_fail = @@ -1088,7 +1087,8 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle function, control = graph()->NewNode(common()->IfFalse(), check_branch); cur = SafeLoadElement(kind, receiver, control, &effect, &k, p.feedback()); - k = jsgraph()->OneConstant(); + k = graph()->NewNode(simplified()->NumberAdd(), k, + jsgraph()->OneConstant()); } // Start the loop. @@ -1184,6 +1184,9 @@ Reduction JSCallReducer::ReduceArrayReduce(Handle function, control = graph()->NewNode(common()->Merge(2), control, after_call_control); effect = graph()->NewNode(common()->EffectPhi(2), effect, after_call_effect, control); + next_cur = + graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), cur, + next_cur, control); } k = next_k; @@ -1256,8 +1259,7 @@ Reduction JSCallReducer::ReduceArrayReduceRight(Handle function, if (!CanInlineArrayIteratingBuiltin(receiver_map)) { return NoChange(); } - if (!IsFastElementsKind(next_kind) || - (IsDoubleElementsKind(next_kind) && IsHoleyElementsKind(next_kind))) { + if (!IsFastElementsKind(next_kind) || IsHoleyElementsKind(next_kind)) { return NoChange(); } if (IsDoubleElementsKind(kind) != IsDoubleElementsKind(next_kind)) { @@ -1414,6 +1416,9 @@ Reduction JSCallReducer::ReduceArrayReduceRight(Handle function, control = graph()->NewNode(common()->Merge(2), control, after_call_control); effect = graph()->NewNode(common()->EffectPhi(2), effect, after_call_effect, control); + next_cur = + graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), cur, + next_cur, control); } k = next_k; @@ -3104,6 +3109,10 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) { return ReduceArrayMap(function, node); case Builtins::kArrayFilter: return ReduceArrayFilter(function, node); + case Builtins::kArrayReduce: + return ReduceArrayReduce(function, node); + case Builtins::kArrayReduceRight: + return ReduceArrayReduceRight(function, node); case Builtins::kArrayPrototypeFind: return ReduceArrayFind(ArrayFindVariant::kFind, function, node); case Builtins::kArrayPrototypeFindIndex: diff --git a/test/mjsunit/array-reduce.js b/test/mjsunit/array-reduce.js index 88da491d1c..171a40f092 100644 --- a/test/mjsunit/array-reduce.js +++ b/test/mjsunit/array-reduce.js @@ -1179,3 +1179,65 @@ assertEquals(undefined, arr.reduceRight(function(val) { return val })); done = true; assertEquals(null, g()); })(); + +(function ReduceHoleyArrayWithDefaultAccumulator() { + var __v_12258 = new Array(10); + function __f_3253(a) { + let __f_3252 = function(accumulator, currentValue) { + return currentValue; + } + return a.reduce(__f_3252, 13); + } + assertEquals(13, __f_3253(__v_12258)); + assertEquals(13, __f_3253(__v_12258)); + assertEquals(13, __f_3253(__v_12258)); + %OptimizeFunctionOnNextCall(__f_3253); + assertEquals(13, __f_3253(__v_12258)); +})(); + +(function ReduceRightHoleyArrayWithDefaultAccumulator() { + var __v_12258 = new Array(10); + function __f_3253(a) { + let __f_3252 = function(accumulator, currentValue) { + return currentValue; + } + return a.reduceRight(__f_3252, 13); + } + assertEquals(13, __f_3253(__v_12258)); + assertEquals(13, __f_3253(__v_12258)); + assertEquals(13, __f_3253(__v_12258)); + %OptimizeFunctionOnNextCall(__f_3253); + assertEquals(13, __f_3253(__v_12258)); +})(); + +(function ReduceHoleyArrayOneElementWithDefaultAccumulator() { + var __v_12258 = new Array(10); + __v_12258[1] = 5; + function __f_3253(a) { + let __f_3252 = function(accumulator, currentValue) { + return currentValue + accumulator; + } + return a.reduce(__f_3252, 13); + } + assertEquals(18, __f_3253(__v_12258)); + assertEquals(18, __f_3253(__v_12258)); + assertEquals(18, __f_3253(__v_12258)); + %OptimizeFunctionOnNextCall(__f_3253); + assertEquals(18, __f_3253(__v_12258)); +})(); + +(function ReduceRightHoleyArrayOneElementWithDefaultAccumulator() { + var __v_12258 = new Array(10); + __v_12258[1] = 5; + function __f_3253(a) { + let __f_3252 = function(accumulator, currentValue) { + return currentValue + accumulator; + } + return a.reduceRight(__f_3252, 13); + } + assertEquals(18, __f_3253(__v_12258)); + assertEquals(18, __f_3253(__v_12258)); + assertEquals(18, __f_3253(__v_12258)); + %OptimizeFunctionOnNextCall(__f_3253); + assertEquals(18, __f_3253(__v_12258)); +})();