Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2059)

Unified Diff: src/code-stub-assembler.cc

Issue 2484003002: [builtins] implement JSBuiltinReducer for ArrayIteratorNext() (Closed)
Patch Set: fix tests when ignition is used Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/access-builder.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 323c05d17e737cbbfdc0e5acfb1dc6625743b867..766d331333bd837b614f0a7429fadb990985d08e 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -681,16 +681,11 @@ void CodeStubAssembler::BranchIfFastJSArray(Node* object, Node* context,
Node* elements_kind = LoadMapElementsKind(map);
// Bailout if receiver has slow elements.
- GotoIf(
- Int32GreaterThan(elements_kind, Int32Constant(LAST_FAST_ELEMENTS_KIND)),
- if_false);
+ GotoUnless(IsFastElementsKind(elements_kind), if_false);
// Check prototype chain if receiver does not have packed elements.
- STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1));
- STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1));
- STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1));
- Node* holey_elements = Word32And(elements_kind, Int32Constant(1));
- GotoIf(Word32Equal(holey_elements, Int32Constant(0)), if_true);
+ GotoUnless(IsHoleyFastElementsKind(elements_kind), if_true);
+
BranchIfPrototypesHaveNoElements(map, if_true, if_false);
}
@@ -8898,19 +8893,59 @@ compiler::Node* CodeStubAssembler::CreateArrayIterator(
Bind(&if_isfast);
{
- Node* map_index =
- IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset),
- LoadMapElementsKind(array_map));
- CSA_ASSERT(this, IntPtrGreaterThanOrEqual(
- map_index, IntPtrConstant(kBaseMapIndex +
- kFastIteratorOffset)));
- CSA_ASSERT(this, IntPtrLessThan(map_index,
- IntPtrConstant(kBaseMapIndex +
- kSlowIteratorOffset)));
+ Label if_ispacked(this), if_isholey(this);
+ Node* elements_kind = LoadMapElementsKind(array_map);
+ Branch(IsHoleyFastElementsKind(elements_kind), &if_isholey,
+ &if_ispacked);
- var_map_index.Bind(map_index);
- var_array_map.Bind(array_map);
- Goto(&allocate_iterator);
+ Bind(&if_isholey);
+ {
+ // Fast holey JSArrays can treat the hole as undefined if the
+ // protector cell is valid, and the prototype chain is unchanged from
+ // its initial state (because the protector cell is only tracked for
+ // initial the Array and Object prototypes). Check these conditions
+ // here, and take the slow path if any fail.
+ Node* protector_cell = LoadRoot(Heap::kArrayProtectorRootIndex);
+ DCHECK(isolate()->heap()->array_protector()->IsPropertyCell());
+ GotoUnless(
+ WordEqual(
+ LoadObjectField(protector_cell, PropertyCell::kValueOffset),
+ SmiConstant(Smi::FromInt(Isolate::kArrayProtectorValid))),
+ &if_isslow);
+
+ Node* native_context = LoadNativeContext(context);
+
+ Node* prototype = LoadMapPrototype(array_map);
+ Node* array_prototype = LoadContextElement(
+ native_context, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
+ GotoUnless(WordEqual(prototype, array_prototype), &if_isslow);
+
+ Node* map = LoadMap(prototype);
+ prototype = LoadMapPrototype(map);
+ Node* object_prototype = LoadContextElement(
+ native_context, Context::INITIAL_OBJECT_PROTOTYPE_INDEX);
+ GotoUnless(WordEqual(prototype, object_prototype), &if_isslow);
+
+ map = LoadMap(prototype);
+ prototype = LoadMapPrototype(map);
+ Branch(IsNull(prototype), &if_ispacked, &if_isslow);
+ }
+ Bind(&if_ispacked);
+ {
+ Node* map_index =
+ IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset),
+ LoadMapElementsKind(array_map));
+ CSA_ASSERT(this, IntPtrGreaterThanOrEqual(
+ map_index, IntPtrConstant(kBaseMapIndex +
+ kFastIteratorOffset)));
+ CSA_ASSERT(this, IntPtrLessThan(map_index,
+ IntPtrConstant(kBaseMapIndex +
+ kSlowIteratorOffset)));
+
+ var_map_index.Bind(map_index);
+ var_array_map.Bind(array_map);
+ Goto(&allocate_iterator);
+ }
}
Bind(&if_isslow);
@@ -9051,5 +9086,24 @@ void CodeStubArguments::PopAndReturn(compiler::Node* value) {
value);
}
+compiler::Node* CodeStubAssembler::IsFastElementsKind(
+ compiler::Node* elements_kind) {
+ return Uint32LessThanOrEqual(elements_kind,
+ Int32Constant(LAST_FAST_ELEMENTS_KIND));
+}
+
+compiler::Node* CodeStubAssembler::IsHoleyFastElementsKind(
+ compiler::Node* elements_kind) {
+ CSA_ASSERT(this, IsFastElementsKind(elements_kind));
+
+ STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == (FAST_SMI_ELEMENTS | 1));
+ STATIC_ASSERT(FAST_HOLEY_ELEMENTS == (FAST_ELEMENTS | 1));
+ STATIC_ASSERT(FAST_HOLEY_DOUBLE_ELEMENTS == (FAST_DOUBLE_ELEMENTS | 1));
+
+ // Check prototype chain if receiver does not have packed elements.
+ Node* holey_elements = Word32And(elements_kind, Int32Constant(1));
+ return Word32Equal(holey_elements, Int32Constant(1));
+}
+
} // namespace internal
} // namespace v8
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/access-builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698