Commit f88a1d87 authored by Adam Klein's avatar Adam Klein Committed by Commit Bot

Revert "Add fast paths to Array.from."

This reverts commit 7bd9eb7e.

Reason for revert: crashes on canary, see https://crbug.com/901010

Original change's description:
> Add fast paths to Array.from.
>
> This reuses the fast path from IterableToList for Array.from. The fast
> paths are taken when .from is called with the receiver Array and the only
> argument is the iterable (no mapping function or thisArg).
>
> Bug: v8:7980
> Change-Id: I975b0c5e3f838262d7b71ad4dec5111fb031d746
> Reviewed-on: https://chromium-review.googlesource.com/c/1297322
> Commit-Queue: Hai Dang <dhai@google.com>
> Reviewed-by: Georg Neis <neis@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#56993}

TBR=neis@chromium.org,dhai@google.com
Bug: v8:7980, chromium:901010, v8:8410

Change-Id: I5e73267f0b3a905582c57a6fad1459c031600a73
Reviewed-on: https://chromium-review.googlesource.com/c/1315935
Commit-Queue: Adam Klein <adamk@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57221}
parent f5cf90cc
......@@ -1915,29 +1915,7 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) {
UncheckedCast<Int32T>(Parameter(Descriptor::kJSActualArgumentsCount));
CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
TNode<Object> items = args.GetOptionalArgumentValue(0);
TNode<Object> receiver = args.GetReceiver();
Label fast_iterate(this), normal_iterate(this);
// Use fast path if:
// * |items| is the only argument, and
// * the receiver is the Array function.
GotoIfNot(Word32Equal(argc, Int32Constant(1)), &normal_iterate);
TNode<Object> array_function = LoadContextElement(
LoadNativeContext(context), Context::ARRAY_FUNCTION_INDEX);
Branch(WordEqual(array_function, receiver), &fast_iterate, &normal_iterate);
BIND(&fast_iterate);
{
IteratorBuiltinsAssembler iterator_assembler(state());
TVARIABLE(Object, var_fast_result);
iterator_assembler.FastIterableToList(context, items, &var_fast_result,
&normal_iterate);
args.PopAndReturn(var_fast_result.value());
}
BIND(&normal_iterate);
TNode<Object> map_function = args.GetOptionalArgumentValue(1);
// If map_function is not undefined, then ensure it's callable else throw.
......@@ -1956,6 +1934,7 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) {
Label iterable(this), not_iterable(this), finished(this), if_exception(this);
TNode<Object> this_arg = args.GetOptionalArgumentValue(2);
TNode<Object> items = args.GetOptionalArgumentValue(0);
// The spec doesn't require ToObject to be called directly on the iterable
// branch, but it's part of GetMethod that is in the spec.
TNode<JSReceiver> array_like = ToObject_Inline(context, items);
......@@ -1992,7 +1971,7 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) {
}
// Construct the output array with empty length.
array = ConstructArrayLike(context, receiver);
array = ConstructArrayLike(context, args.GetReceiver());
// Actually get the iterator and throw if the iterator method does not yield
// one.
......@@ -2076,7 +2055,7 @@ TF_BUILTIN(ArrayFrom, ArrayPopulatorAssembler) {
// Construct an array using the receiver as constructor with the same length
// as the input array.
array = ConstructArrayLike(context, receiver, length.value());
array = ConstructArrayLike(context, args.GetReceiver(), length.value());
TVARIABLE(Number, index, SmiConstant(0));
......
......@@ -265,18 +265,30 @@ TF_BUILTIN(IterableToListMayPreserveHoles, IteratorBuiltinsAssembler) {
TailCallBuiltin(Builtins::kIterableToList, context, iterable, iterator_fn);
}
void IteratorBuiltinsAssembler::FastIterableToList(
TNode<Context> context, TNode<Object> iterable,
TVariable<Object>* var_result, Label* slow) {
Label done(this), check_string(this), check_map(this), check_set(this);
// This builtin loads the property Symbol.iterator as the iterator, and has fast
// paths for fast arrays, for primitive strings, for sets and set iterators, and
// for map iterators. These fast paths will only be taken if Symbol.iterator and
// the Iterator prototype are not modified in a way that changes the original
// iteration behavior.
// * In case of fast holey arrays, holes will be converted to undefined to
// reflect iteration semantics. Note that replacement by undefined is only
// correct when the NoElements protector is valid.
// * In case of map/set iterators, there is an additional requirement that the
// iterator is not partially consumed. To be spec-compliant, after spreading
// the iterator is set to be exhausted.
TF_BUILTIN(IterableToListWithSymbolLookup, IteratorBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
Label slow_path(this), check_string(this), check_map(this), check_set(this);
GotoIfForceSlowPath(&slow_path);
GotoIfNot(IsFastJSArrayWithNoCustomIteration(iterable, context),
&check_string);
// Fast path for fast JSArray.
*var_result =
CallBuiltin(Builtins::kCloneFastJSArrayFillingHoles, context, iterable);
Goto(&done);
TailCallBuiltin(Builtins::kCloneFastJSArrayFillingHoles, context, iterable);
BIND(&check_string);
{
......@@ -286,8 +298,7 @@ void IteratorBuiltinsAssembler::FastIterableToList(
iterable, context, &string_fast_call, &check_map);
BIND(&string_fast_call);
*var_result = CallBuiltin(Builtins::kStringToList, context, iterable);
Goto(&done);
TailCallBuiltin(Builtins::kStringToList, context, iterable);
}
BIND(&check_map);
......@@ -297,48 +308,19 @@ void IteratorBuiltinsAssembler::FastIterableToList(
state(), iterable, context, &map_fast_call, &check_set);
BIND(&map_fast_call);
*var_result = CallBuiltin(Builtins::kMapIteratorToList, context, iterable);
Goto(&done);
TailCallBuiltin(Builtins::kMapIteratorToList, context, iterable);
}
BIND(&check_set);
{
Label set_fast_call(this);
BranchIfIterableWithOriginalValueSetIterator(state(), iterable, context,
&set_fast_call, slow);
&set_fast_call, &slow_path);
BIND(&set_fast_call);
*var_result =
CallBuiltin(Builtins::kSetOrSetIteratorToList, context, iterable);
Goto(&done);
TailCallBuiltin(Builtins::kSetOrSetIteratorToList, context, iterable);
}
BIND(&done);
}
// This builtin loads the property Symbol.iterator as the iterator, and has fast
// paths for fast arrays, for primitive strings, for sets and set iterators, and
// for map iterators. These fast paths will only be taken if Symbol.iterator and
// the Iterator prototype are not modified in a way that changes the original
// iteration behavior.
// * In case of fast holey arrays, holes will be converted to undefined to
// reflect iteration semantics. Note that replacement by undefined is only
// correct when the NoElements protector is valid.
// * In case of map/set iterators, there is an additional requirement that the
// iterator is not partially consumed. To be spec-compliant, after spreading
// the iterator is set to be exhausted.
TF_BUILTIN(IterableToListWithSymbolLookup, IteratorBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
Label slow_path(this);
GotoIfForceSlowPath(&slow_path);
TVARIABLE(Object, var_result);
FastIterableToList(context, iterable, &var_result, &slow_path);
Return(var_result.value());
BIND(&slow_path);
{
TNode<Object> iterator_fn = GetIteratorMethod(context, iterable);
......
......@@ -66,9 +66,6 @@ class IteratorBuiltinsAssembler : public BaseBuiltinsFromDSLAssembler {
// following the ECMAscript operation with the same name.
TNode<JSArray> IterableToList(TNode<Context> context, TNode<Object> iterable,
TNode<Object> iterator_fn);
void FastIterableToList(TNode<Context> context, TNode<Object> iterable,
TVariable<Object>* var_result, Label* slow);
};
} // namespace internal
......
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