| Index: src/builtins/builtins-array-gen.cc
|
| diff --git a/src/builtins/builtins-array-gen.cc b/src/builtins/builtins-array-gen.cc
|
| index ca553b73ceb6b643831d5249eec1f6c647c985da..c5ac4add210d4adaaf79ecfb3efd91ff523cf068 100644
|
| --- a/src/builtins/builtins-array-gen.cc
|
| +++ b/src/builtins/builtins-array-gen.cc
|
| @@ -1679,96 +1679,60 @@ TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) {
|
| Node* array = args.GetReceiver();
|
| Node* search_element =
|
| args.GetOptionalArgumentValue(kSearchElementArg, UndefinedConstant());
|
| - Node* start_from =
|
| - args.GetOptionalArgumentValue(kFromIndexArg, UndefinedConstant());
|
| Node* context = Parameter(BuiltinDescriptor::kContext);
|
|
|
| Node* intptr_zero = IntPtrConstant(0);
|
| Node* intptr_one = IntPtrConstant(1);
|
|
|
| - VARIABLE(len_var, MachineType::PointerRepresentation());
|
| - VARIABLE(index_var, MachineType::PointerRepresentation());
|
| - VARIABLE(start_from_var, MachineType::PointerRepresentation());
|
| -
|
| - Label init_k(this), return_found(this), return_not_found(this),
|
| + Label init_index(this), return_found(this), return_not_found(this),
|
| call_runtime(this);
|
|
|
| - Label init_len(this);
|
| -
|
| - index_var.Bind(intptr_zero);
|
| - len_var.Bind(intptr_zero);
|
| -
|
| // Take slow path if not a JSArray, if retrieving elements requires
|
| // traversing prototype, or if access checks are required.
|
| BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ,
|
| - &init_len, &call_runtime);
|
| + &init_index, &call_runtime);
|
|
|
| - BIND(&init_len);
|
| - {
|
| - // JSArray length is always an Smi for fast arrays.
|
| - CSA_ASSERT(this,
|
| - TaggedIsSmi(LoadObjectField(array, JSArray::kLengthOffset)));
|
| - Node* len = LoadAndUntagObjectField(array, JSArray::kLengthOffset);
|
| + BIND(&init_index);
|
| + VARIABLE(index_var, MachineType::PointerRepresentation(), intptr_zero);
|
|
|
| - len_var.Bind(len);
|
| - Branch(WordEqual(len_var.value(), intptr_zero), &return_not_found, &init_k);
|
| - }
|
| + // JSArray length is always a positive Smi for fast arrays.
|
| + CSA_ASSERT(this, TaggedIsPositiveSmi(LoadJSArrayLength(array)));
|
| + Node* array_length = SmiUntag(LoadJSArrayLength(array));
|
|
|
| - BIND(&init_k);
|
| {
|
| // For now only deal with undefined and Smis here; we must be really careful
|
| // with side-effects from the ToInteger conversion as the side-effects might
|
| // render our assumptions about the receiver being a fast JSArray and the
|
| // length invalid.
|
| - Label done(this), init_k_smi(this), init_k_other(this), init_k_zero(this),
|
| - init_k_n(this);
|
| - Branch(TaggedIsSmi(start_from), &init_k_smi, &init_k_other);
|
| + Label done(this);
|
|
|
| - BIND(&init_k_smi);
|
| - {
|
| - // The fromIndex is a Smi.
|
| - start_from_var.Bind(SmiUntag(start_from));
|
| - Goto(&init_k_n);
|
| - }
|
| + // If no fromIndex was passed, default to 0.
|
| + GotoIf(IntPtrLessThanOrEqual(argc, IntPtrConstant(kFromIndexArg)), &done);
|
|
|
| - BIND(&init_k_other);
|
| - {
|
| - // The fromIndex must be undefined then, otherwise bailout and let the
|
| - // runtime deal with the full ToInteger conversion.
|
| - GotoIfNot(IsUndefined(start_from), &call_runtime);
|
| - start_from_var.Bind(intptr_zero);
|
| - Goto(&init_k_n);
|
| - }
|
| + // Handle Smis here and everything else in runtime.
|
| + Node* start_from = args.AtIndex(kFromIndexArg);
|
| + GotoIfNot(TaggedIsSmi(start_from), &call_runtime);
|
|
|
| - BIND(&init_k_n);
|
| - {
|
| - Label if_positive(this), if_negative(this), done(this);
|
| - Branch(IntPtrLessThan(start_from_var.value(), intptr_zero), &if_negative,
|
| - &if_positive);
|
| + Node* intptr_start_from = SmiUntag(start_from);
|
| + index_var.Bind(intptr_start_from);
|
|
|
| - BIND(&if_positive);
|
| - {
|
| - index_var.Bind(start_from_var.value());
|
| - Goto(&done);
|
| - }
|
| + Label if_negative(this);
|
| + Branch(IntPtrLessThan(intptr_start_from, intptr_zero), &if_negative, &done);
|
|
|
| - BIND(&if_negative);
|
| - {
|
| - index_var.Bind(IntPtrAdd(len_var.value(), start_from_var.value()));
|
| - Branch(IntPtrLessThan(index_var.value(), intptr_zero), &init_k_zero,
|
| - &done);
|
| - }
|
| -
|
| - BIND(&init_k_zero);
|
| - {
|
| - index_var.Bind(intptr_zero);
|
| - Goto(&done);
|
| - }
|
| -
|
| - BIND(&done);
|
| + BIND(&if_negative);
|
| + {
|
| + Node* len_minus_start_from = IntPtrAdd(array_length, intptr_start_from);
|
| + index_var.Bind(IntPtrMax(len_minus_start_from, intptr_zero));
|
| + Goto(&done);
|
| }
|
| +
|
| + BIND(&done);
|
| }
|
|
|
| + // Fail early if startIndex >= array.length.
|
| + GotoIf(IntPtrGreaterThanOrEqual(index_var.value(), array_length),
|
| + &return_not_found);
|
| +
|
| static int32_t kElementsKind[] = {
|
| FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
|
| FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS,
|
| @@ -1808,7 +1772,7 @@ TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) {
|
|
|
| BIND(&ident_loop);
|
| {
|
| - GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
|
| + GotoIfNot(UintPtrLessThan(index_var.value(), array_length),
|
| &return_not_found);
|
| Node* element_k = LoadFixedArrayElement(elements, index_var.value());
|
| GotoIf(WordEqual(element_k, search_element), &return_found);
|
| @@ -1826,7 +1790,7 @@ TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) {
|
| BIND(¬_nan_loop);
|
| {
|
| Label continue_loop(this), not_smi(this);
|
| - GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
|
| + GotoIfNot(UintPtrLessThan(index_var.value(), array_length),
|
| &return_not_found);
|
| Node* element_k = LoadFixedArrayElement(elements, index_var.value());
|
| GotoIfNot(TaggedIsSmi(element_k), ¬_smi);
|
| @@ -1846,8 +1810,9 @@ TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) {
|
|
|
| BIND(&string_loop);
|
| {
|
| + CSA_ASSERT(this, IsString(search_element));
|
| Label continue_loop(this);
|
| - GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
|
| + GotoIfNot(UintPtrLessThan(index_var.value(), array_length),
|
| &return_not_found);
|
| Node* element_k = LoadFixedArrayElement(elements, index_var.value());
|
| GotoIf(TaggedIsSmi(element_k), &continue_loop);
|
| @@ -1860,7 +1825,7 @@ TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) {
|
| &continue_loop);
|
|
|
| BIND(&continue_loop);
|
| - index_var.Bind(IntPtrAdd(index_var.value(), intptr_one));
|
| + Increment(index_var);
|
| Goto(&string_loop);
|
| }
|
| }
|
| @@ -1884,7 +1849,7 @@ TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) {
|
| // Search for HeapNumber
|
| BIND(¬_nan_loop);
|
| {
|
| - GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
|
| + GotoIfNot(UintPtrLessThan(index_var.value(), array_length),
|
| &return_not_found);
|
| Node* element_k = LoadFixedDoubleArrayElement(elements, index_var.value(),
|
| MachineType::Float64());
|
| @@ -1915,7 +1880,7 @@ TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) {
|
| BIND(¬_nan_loop);
|
| {
|
| Label continue_loop(this);
|
| - GotoIfNot(UintPtrLessThan(index_var.value(), len_var.value()),
|
| + GotoIfNot(UintPtrLessThan(index_var.value(), array_length),
|
| &return_not_found);
|
|
|
| // Load double value or continue if it contains a double hole.
|
| @@ -1938,8 +1903,12 @@ TF_BUILTIN(ArrayIndexOf, CodeStubAssembler) {
|
| args.PopAndReturn(NumberConstant(-1));
|
|
|
| BIND(&call_runtime);
|
| - args.PopAndReturn(CallRuntime(Runtime::kArrayIndexOf, context, array,
|
| - search_element, start_from));
|
| + {
|
| + Node* start_from =
|
| + args.GetOptionalArgumentValue(kFromIndexArg, UndefinedConstant());
|
| + args.PopAndReturn(CallRuntime(Runtime::kArrayIndexOf, context, array,
|
| + search_element, start_from));
|
| + }
|
| }
|
|
|
| class ArrayPrototypeIterationAssembler : public CodeStubAssembler {
|
|
|