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

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

Issue 2155153002: [interpreter] Update ForInPrepare to conditionally use runtime. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Trim interpreter assembler. Created 4 years, 5 months 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/interpreter/interpreter.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 3bf07277044e05fb093777627b32c100556629ad..3b628d868337292ecc72b58b2d740d22466a48ce 100644
--- a/src/code-stub-assembler.cc
+++ b/src/code-stub-assembler.cc
@@ -3137,5 +3137,72 @@ void CodeStubAssembler::LoadGlobalIC(const LoadICParameters* p) {
}
}
+Node* CodeStubAssembler::EnumLength(Node* map) {
+ Node* bitfield_3 = LoadMapBitField3(map);
+ Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3);
+ return SmiTag(enum_length);
+}
+
+void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache,
+ Label* use_runtime) {
+ Variable current_js_object(this, MachineRepresentation::kTagged);
+ current_js_object.Bind(receiver);
+
+ Variable current_map(this, MachineRepresentation::kTagged);
+ current_map.Bind(LoadMap(current_js_object.value()));
+
+ // These variables are updated in the loop below.
+ Variable* loop_vars[2] = {&current_js_object, &current_map};
+ Label loop(this, 2, loop_vars), next(this);
+
+ // Check if the enum length field is properly initialized, indicating that
+ // there is an enum cache.
+ {
+ Node* invalid_enum_cache_sentinel =
+ SmiConstant(Smi::FromInt(kInvalidEnumCacheSentinel));
+ Node* enum_length = EnumLength(current_map.value());
+ BranchIfWordEqual(enum_length, invalid_enum_cache_sentinel, use_runtime,
+ &loop);
+ }
+
+ // Check that there are no elements. |current_js_object| contains
+ // the current JS object we've reached through the prototype chain.
+ Bind(&loop);
+ {
+ Label if_elements(this), if_no_elements(this);
+ Node* elements = LoadElements(current_js_object.value());
+ Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
+ // Check that there are no elements.
+ BranchIfWordEqual(elements, empty_fixed_array, &if_no_elements,
+ &if_elements);
+ Bind(&if_elements);
+ {
+ // Second chance, the object may be using the empty slow element
+ // dictionary.
+ Node* slow_empty_dictionary =
+ LoadRoot(Heap::kEmptySlowElementDictionaryRootIndex);
+ BranchIfWordNotEqual(elements, slow_empty_dictionary, use_runtime,
+ &if_no_elements);
+ }
+
+ Bind(&if_no_elements);
+ {
+ // Update map prototype.
+ current_js_object.Bind(LoadMapPrototype(current_map.value()));
+ BranchIfWordEqual(current_js_object.value(), NullConstant(), use_cache,
+ &next);
+ }
+ }
+
+ Bind(&next);
+ {
+ // For all objects but the receiver, check that the cache is empty.
+ current_map.Bind(LoadMap(current_js_object.value()));
+ Node* enum_length = EnumLength(current_map.value());
+ Node* zero_constant = SmiConstant(Smi::FromInt(0));
+ BranchIf(WordEqual(enum_length, zero_constant), &loop, use_runtime);
+ }
+}
+
} // namespace internal
} // namespace v8
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/interpreter/interpreter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698