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

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

Issue 2484003002: [builtins] implement JSBuiltinReducer for ArrayIteratorNext() (Closed)
Patch Set: CheckIf() for ArrayBufferWasNeutered() rather than a branch, which hopefully can be eliminated, and… 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
Index: src/code-stub-assembler.cc
diff --git a/src/code-stub-assembler.cc b/src/code-stub-assembler.cc
index 85246894b778af2454ea0e7c95bdcaad1e29c1c1..179d84d8f996b9867d7269af651d46f6adaea0b4 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -8710,17 +8710,53 @@ compiler::Node* CodeStubAssembler::CreateArrayIterator(
Bind(&if_isfast);
{
- Node* map_index =
- IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset),
- LoadMapElementsKind(array_map));
- CSA_ASSERT(IntPtrGreaterThanOrEqual(
- map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset)));
- CSA_ASSERT(IntPtrLessThan(
- map_index, IntPtrConstant(kBaseMapIndex + kSlowIteratorOffset)));
-
- var_map_index.Bind(map_index);
- var_array_map.Bind(array_map);
- Goto(&allocate_iterator);
+ Label if_ispacked(this), if_isholey(this);
+ Node* elements_kind = LoadMapElementsKind(array_map);
+ Branch(Word32Equal(Word32And(elements_kind, Int32Constant(1)),
+ Int32Constant(0)),
+ &if_ispacked, &if_isholey);
Camillo Bruni 2016/11/09 12:03:49 Could you add a IsFastPackedElementsKind helper on
caitp 2016/11/09 17:40:16 Done, 2 new helpers (CSA::IsFastElementsKind() and
+ Bind(&if_isholey);
+ {
+ // Check the protector cell --- create a Generic iterator if invalid
+ 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);
+
+ // Otherwise, check that the prototype is a stable initial
Benedikt Meurer 2016/11/09 05:37:05 Maybe it'd be sufficient to check for current cont
caitp 2016/11/09 17:40:16 Updated to only check the current context, and add
+ // Array prototype
+ Node* prototype = LoadMapPrototype(array_map);
+ GotoUnless(IsAnyInitialArrayPrototype(prototype), &if_isslow);
+ GotoUnless(Word32Equal(DecodeWord32<Map::IsUnstable>(
+ LoadMapBitField3(array_map)),
+ Int32Constant(0)),
+ &if_isslow);
+
+ // Check that the Object prototype is stable as well.
+ prototype = LoadMapPrototype(LoadMap(prototype));
Camillo Bruni 2016/11/09 12:03:49 object_map = LoadMap(prototype); ...
+ GotoUnless(IsAnyInitialObjectPrototype(prototype), &if_isslow);
+ Branch(Word32Equal(
+ DecodeWord32<Map::IsUnstable>(LoadMapBitField3(array_map)),
Camillo Bruni 2016/11/09 12:03:49 You probably wanted to check the object_map here.
caitp 2016/11/09 17:40:16 good catch, but I guess we don't need stability ch
+ Int32Constant(0)),
+ &if_ispacked, &if_isslow);
+ }
+ Bind(&if_ispacked);
+ {
+ Node* map_index =
+ IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset),
+ LoadMapElementsKind(array_map));
+ CSA_ASSERT(IntPtrGreaterThanOrEqual(
+ map_index, IntPtrConstant(kBaseMapIndex + kFastIteratorOffset)));
+ CSA_ASSERT(IntPtrLessThan(
+ map_index, IntPtrConstant(kBaseMapIndex + kSlowIteratorOffset)));
+
+ var_map_index.Bind(map_index);
+ var_array_map.Bind(array_map);
+ Goto(&allocate_iterator);
+ }
}
Bind(&if_isslow);
@@ -8860,5 +8896,48 @@ void CodeStubArguments::PopAndReturn(compiler::Node* value) {
value);
}
+// Implement Isolate::IsInAnyContext() in CodeStubAssembler form.
+compiler::Node* CodeStubAssembler::IsInAnyNativeContext(compiler::Node* object,
+ uint32_t index) {
+ Variable var_context(this, MachineRepresentation::kTagged);
+ Variable var_found(this, MachineRepresentation::kWord32);
+ var_context.Bind(LoadFirstNativeContext());
+ var_found.Bind(Int32Constant(0));
+
+ Label loop(this, &var_context), done(this);
+ Branch(WordEqual(var_context.value(), UndefinedConstant()), &done, &loop);
Camillo Bruni 2016/11/09 12:03:49 nit: IsUndefined(var_context.value())
+
+ // Loop while {context} is not undefined:
+ Bind(&loop);
+ {
+ Label continue_loop(this), break_loop(this);
+ Node* context = var_context.value();
+ Node* value = LoadContextElement(context, index);
+
+ Branch(WordEqual(value, object), &break_loop, &continue_loop);
+ Bind(&break_loop);
+ var_found.Bind(Int32Constant(1));
+ Goto(&done);
+
+ Bind(&continue_loop);
+ var_context.Bind(LoadContextElement(context, Context::NEXT_CONTEXT_LINK));
+ Branch(WordEqual(var_context.value(), UndefinedConstant()), &done, &loop);
Camillo Bruni 2016/11/09 12:03:49 nit: IsUndefined(var_context.value())
+ }
+
+ Bind(&done);
+ Node* result = Word32NotEqual(var_found.value(), Int32Constant(0));
+ return result;
+}
+
+compiler::Node* CodeStubAssembler::IsAnyInitialArrayPrototype(
+ compiler::Node* object) {
+ return IsInAnyNativeContext(object, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
+}
+
+compiler::Node* CodeStubAssembler::IsAnyInitialObjectPrototype(
+ compiler::Node* object) {
+ return IsInAnyNativeContext(object, Context::INITIAL_OBJECT_PROTOTYPE_INDEX);
+}
+
} // namespace internal
} // namespace v8

Powered by Google App Engine
This is Rietveld 408576698