Change IterableToList's check to a CSA call instead of a runtime call.

The conditions checked by the CSA IsFastJSArrayWithNoCustomIteration is actually
stronger than that of the runtime IterableToListCanBeElided. In particular,
while IterableToListCanBeElided only checks that the prototype has no element
when the array is holey, IsFastJSArrayWithNoCustomIteration always requires
that the prototype has no element.

Bug: v8:7980
Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I28b086428d79682392413fb4182923184d7c1836
Reviewed-on: https://chromium-review.googlesource.com/1183671
Commit-Queue: Hai Dang <dhai@google.com>
Reviewed-by: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55312}
This commit is contained in:
Hai Dang 2018-08-22 13:57:38 +02:00 committed by Commit Bot
parent d6f859b389
commit d65b3f4d3b
6 changed files with 14 additions and 27 deletions

View File

@ -164,8 +164,7 @@ void BaseCollectionsAssembler::AddConstructorEntries(
Variant variant, TNode<Context> context, TNode<Context> native_context,
TNode<Object> collection, TNode<Object> initial_entries) {
TVARIABLE(BoolT, use_fast_loop,
IsFastJSArrayWithNoCustomIteration(initial_entries, context,
native_context));
IsFastJSArrayWithNoCustomIteration(initial_entries, context));
TNode<IntPtrT> at_least_space_for =
EstimatedInitialSize(initial_entries, use_fast_loop.value());
Label allocate_table(this, &use_fast_loop), exit(this), fast_loop(this),
@ -186,8 +185,8 @@ void BaseCollectionsAssembler::AddConstructorEntries(
TNode<JSArray> initial_entries_jsarray =
UncheckedCast<JSArray>(initial_entries);
#if DEBUG
CSA_ASSERT(this, IsFastJSArrayWithNoCustomIteration(
initial_entries_jsarray, context, native_context));
CSA_ASSERT(this, IsFastJSArrayWithNoCustomIteration(initial_entries_jsarray,
context));
TNode<Map> original_initial_entries_map = LoadMap(initial_entries_jsarray);
#endif
@ -228,8 +227,7 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromFastJSArray(
CSA_ASSERT(
this,
WordEqual(GetAddFunction(variant, native_context, collection), add_func));
CSA_ASSERT(this, IsFastJSArrayWithNoCustomIteration(fast_jsarray, context,
native_context));
CSA_ASSERT(this, IsFastJSArrayWithNoCustomIteration(fast_jsarray, context));
TNode<IntPtrT> length = SmiUntag(LoadFastJSArrayLength(fast_jsarray));
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(length, IntPtrConstant(0)));
CSA_ASSERT(

View File

@ -201,13 +201,14 @@ TNode<JSArray> IteratorBuiltinsAssembler::IterableToList(
TVARIABLE(JSArray, created_list);
// This is a fast-path for ignoring the iterator.
// TODO(petermarshall): Port IterableToListCanBeElided to CSA.
Node* elided =
CallRuntime(Runtime::kIterableToListCanBeElided, context, iterable);
CSA_ASSERT(this, IsBoolean(elided));
Branch(IsTrue(elided), &fast_path, &slow_path);
// TODO(dhai): IsFastJSArrayWithNoCustomIteration unnecessarily checks that
// the prototype has no element even when the array is packed.
// Then the fast path will not be taken in the case when the array is packed
// and the prototype has some elements.
Branch(IsFastJSArrayWithNoCustomIteration(iterable, context), &fast_path,
&slow_path);
// This is a fast-path for ignoring the iterator.
BIND(&fast_path);
{
TNode<JSArray> input_array = CAST(iterable);

View File

@ -1065,8 +1065,7 @@ TNode<BoolT> CodeStubAssembler::IsFastJSArray(SloppyTNode<Object> object,
}
TNode<BoolT> CodeStubAssembler::IsFastJSArrayWithNoCustomIteration(
TNode<Object> object, TNode<Context> context,
TNode<Context> native_context) {
TNode<Object> object, TNode<Context> context) {
Label if_false(this, Label::kDeferred), if_fast(this), exit(this);
TVARIABLE(BoolT, var_result);
GotoIfForceSlowPath(&if_false);

View File

@ -1732,9 +1732,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<BoolT> IsExternalStringInstanceType(SloppyTNode<Int32T> instance_type);
TNode<BoolT> IsFastJSArray(SloppyTNode<Object> object,
SloppyTNode<Context> context);
TNode<BoolT> IsFastJSArrayWithNoCustomIteration(
TNode<Object> object, TNode<Context> context,
TNode<Context> native_context);
TNode<BoolT> IsFastJSArrayWithNoCustomIteration(TNode<Object> object,
TNode<Context> context);
TNode<BoolT> IsFeedbackCell(SloppyTNode<HeapObject> object);
TNode<BoolT> IsFeedbackVector(SloppyTNode<HeapObject> object);
TNode<BoolT> IsContext(SloppyTNode<HeapObject> object);

View File

@ -1239,15 +1239,6 @@ RUNTIME_FUNCTION(Runtime_CreateDataProperty) {
return *value;
}
// Checks that 22.2.2.1.1 Runtime Semantics: IterableToList produces exactly the
// same result as doing nothing.
RUNTIME_FUNCTION(Runtime_IterableToListCanBeElided) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(!obj->IterationHasObservableEffects());
}
RUNTIME_FUNCTION(Runtime_GetOwnPropertyDescriptor) {
HandleScope scope(isolate);

View File

@ -334,7 +334,6 @@ namespace internal {
F(HasProperty, 2, 1) \
F(InternalSetPrototype, 2, 1) \
F(IsJSReceiver, 1, 1) \
F(IterableToListCanBeElided, 1, 1) \
F(KeyedGetProperty, 2, 1) \
F(NewObject, 2, 1) \
F(ObjectCreate, 2, 1) \