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:
parent
d6f859b389
commit
d65b3f4d3b
@ -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(
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) \
|
||||
|
Loading…
Reference in New Issue
Block a user