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

Unified Diff: src/interpreter/interpreter-assembler.cc

Issue 2155153002: [interpreter] Update ForInPrepare to conditionally use runtime. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase 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
« src/interpreter/interpreter.cc ('K') | « src/interpreter/interpreter-assembler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/interpreter-assembler.cc
diff --git a/src/interpreter/interpreter-assembler.cc b/src/interpreter/interpreter-assembler.cc
index 8f5d941e5a2e6632fd93c8a0965fc5999375e629..00cfd165001281e71f640969f7a7e0df963fbf71 100644
--- a/src/interpreter/interpreter-assembler.cc
+++ b/src/interpreter/interpreter-assembler.cc
@@ -630,6 +630,76 @@ Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context,
first_arg, function_entry, result_size);
}
+Node* InterpreterAssembler::EnumLength(Node* map) {
+ Node* bitfield_3 = LoadMapBitField3(map);
+ Node* enum_length = BitFieldDecode<Map::EnumLengthBits>(bitfield_3);
+ return SmiTag(enum_length);
+}
+
+void InterpreterAssembler::CheckEnumCache(Node* receiver, Label* use_cache,
rmcilroy 2016/07/19 11:08:54 Could we move these both to CodeStubAssembler - th
oth 2016/07/19 12:59:25 Done.
+ 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 start(this, 2, loop_vars);
rmcilroy 2016/07/19 11:08:54 nit - start->loop
oth 2016/07/19 12:59:25 Done.
+
+ // 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());
+
+ Node* condition = WordEqual(enum_length, invalid_enum_cache_sentinel);
+ BranchIf(condition, use_runtime, &start);
+ }
+
+ Label next(this);
rmcilroy 2016/07/19 11:08:54 nit - move definition next to start
oth 2016/07/19 12:59:25 Done.
+
+ // Check that there are no elements. prototype contains the current JS
rmcilroy 2016/07/19 11:08:54 /s/prototype/|current_js_object| ?
oth 2016/07/19 12:59:25 Done.
+ // object we've reached through the prototype chain.
+ Bind(&start);
+ {
+ 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.
+ BranchIf(WordEqual(elements, empty_fixed_array), &if_no_elements,
rmcilroy 2016/07/19 11:08:54 You can do BranchIfWordEqual if you like.
oth 2016/07/19 12:59:25 Done.
+ &if_elements);
+ Bind(&if_elements);
+ {
+ // Second chance, the object may be using the empty slow element
+ // dictionary.
+ Node* slow_empty_dictionary =
+ LoadRoot(Heap::kEmptySlowElementDictionaryRootIndex);
+ BranchIf(WordNotEqual(elements, slow_empty_dictionary), use_runtime,
+ &if_no_elements);
+ }
+
+ Bind(&if_no_elements);
+ {
+ // Update map prototype.
+ current_js_object.Bind(LoadMapPrototype(current_map.value()));
+ BranchIf(WordEqual(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), &start, use_runtime);
+ }
+}
+
void InterpreterAssembler::UpdateInterruptBudget(Node* weight) {
Label ok(this), interrupt_check(this, Label::kDeferred), end(this);
Node* budget_offset =
« src/interpreter/interpreter.cc ('K') | « src/interpreter/interpreter-assembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698