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

Side by Side Diff: src/compiler/js-native-context-specialization.cc

Issue 2115513002: [turbofan] Introduce CheckIf simplified operator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 unified diff | Download patch
« no previous file with comments | « src/compiler/js-global-object-specialization.cc ('k') | src/compiler/node-matchers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/js-native-context-specialization.h" 5 #include "src/compiler/js-native-context-specialization.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/compilation-dependencies.h" 9 #include "src/compilation-dependencies.h"
10 #include "src/compiler/access-builder.h" 10 #include "src/compiler/access-builder.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 Node* node, Node* value, MapHandleList const& receiver_maps, 73 Node* node, Node* value, MapHandleList const& receiver_maps,
74 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, 74 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode,
75 Node* index) { 75 Node* index) {
76 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || 76 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
77 node->opcode() == IrOpcode::kJSStoreNamed || 77 node->opcode() == IrOpcode::kJSStoreNamed ||
78 node->opcode() == IrOpcode::kJSLoadProperty || 78 node->opcode() == IrOpcode::kJSLoadProperty ||
79 node->opcode() == IrOpcode::kJSStoreProperty); 79 node->opcode() == IrOpcode::kJSStoreProperty);
80 Node* receiver = NodeProperties::GetValueInput(node, 0); 80 Node* receiver = NodeProperties::GetValueInput(node, 0);
81 Node* effect = NodeProperties::GetEffectInput(node); 81 Node* effect = NodeProperties::GetEffectInput(node);
82 Node* control = NodeProperties::GetControlInput(node); 82 Node* control = NodeProperties::GetControlInput(node);
83 Node* frame_state = NodeProperties::FindFrameStateBefore(node);
84 83
85 // Not much we can do if deoptimization support is disabled. 84 // Not much we can do if deoptimization support is disabled.
86 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); 85 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
87 86
88 // Retrieve the native context from the given {node}. 87 // Retrieve the native context from the given {node}.
89 Handle<Context> native_context; 88 Handle<Context> native_context;
90 if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange(); 89 if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange();
91 90
92 // Compute property access infos for the receiver maps. 91 // Compute property access infos for the receiver maps.
93 AccessInfoFactory access_info_factory(dependencies(), native_context, 92 AccessInfoFactory access_info_factory(dependencies(), native_context,
(...skipping 10 matching lines...) Expand all
104 // The final states for every polymorphic branch. We join them with 103 // The final states for every polymorphic branch. We join them with
105 // Merge++Phi+EffectPhi at the bottom. 104 // Merge++Phi+EffectPhi at the bottom.
106 ZoneVector<Node*> values(zone()); 105 ZoneVector<Node*> values(zone());
107 ZoneVector<Node*> effects(zone()); 106 ZoneVector<Node*> effects(zone());
108 ZoneVector<Node*> controls(zone()); 107 ZoneVector<Node*> controls(zone());
109 108
110 // Ensure that {index} matches the specified {name} (if {index} is given). 109 // Ensure that {index} matches the specified {name} (if {index} is given).
111 if (index != nullptr) { 110 if (index != nullptr) {
112 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Name()), 111 Node* check = graph()->NewNode(simplified()->ReferenceEqual(Type::Name()),
113 index, jsgraph()->HeapConstant(name)); 112 index, jsgraph()->HeapConstant(name));
114 control = effect = graph()->NewNode(common()->DeoptimizeUnless(), check, 113 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control);
115 frame_state, effect, control);
116 } 114 }
117 115
118 // Check if {receiver} may be a number. 116 // Check if {receiver} may be a number.
119 bool receiverissmi_possible = false; 117 bool receiverissmi_possible = false;
120 for (PropertyAccessInfo const& access_info : access_infos) { 118 for (PropertyAccessInfo const& access_info : access_infos) {
121 if (access_info.receiver_type()->Is(Type::Number())) { 119 if (access_info.receiver_type()->Is(Type::Number())) {
122 receiverissmi_possible = true; 120 receiverissmi_possible = true;
123 break; 121 break;
124 } 122 }
125 } 123 }
(...skipping 25 matching lines...) Expand all
151 Node* this_value = value; 149 Node* this_value = value;
152 Node* this_receiver = receiver; 150 Node* this_receiver = receiver;
153 Node* this_effect = effect; 151 Node* this_effect = effect;
154 Node* this_control; 152 Node* this_control;
155 153
156 // Perform map check on {receiver}. 154 // Perform map check on {receiver}.
157 Type* receiver_type = access_info.receiver_type(); 155 Type* receiver_type = access_info.receiver_type();
158 if (receiver_type->Is(Type::String())) { 156 if (receiver_type->Is(Type::String())) {
159 Node* check = graph()->NewNode(simplified()->ObjectIsString(), receiver); 157 Node* check = graph()->NewNode(simplified()->ObjectIsString(), receiver);
160 if (j == access_infos.size() - 1) { 158 if (j == access_infos.size() - 1) {
161 this_control = this_effect = 159 this_effect = graph()->NewNode(simplified()->CheckIf(), check,
162 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, 160 this_effect, fallthrough_control);
163 this_effect, fallthrough_control); 161 this_control = fallthrough_control;
164 fallthrough_control = nullptr; 162 fallthrough_control = nullptr;
165 } else { 163 } else {
166 Node* branch = 164 Node* branch =
167 graph()->NewNode(common()->Branch(), check, fallthrough_control); 165 graph()->NewNode(common()->Branch(), check, fallthrough_control);
168 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); 166 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
169 this_control = graph()->NewNode(common()->IfTrue(), branch); 167 this_control = graph()->NewNode(common()->IfTrue(), branch);
170 } 168 }
171 } else { 169 } else {
172 // Emit a (sequence of) map checks for other {receiver}s. 170 // Emit a (sequence of) map checks for other {receiver}s.
173 ZoneVector<Node*> this_controls(zone()); 171 ZoneVector<Node*> this_controls(zone());
174 ZoneVector<Node*> this_effects(zone()); 172 ZoneVector<Node*> this_effects(zone());
175 int num_classes = access_info.receiver_type()->NumClasses(); 173 int num_classes = access_info.receiver_type()->NumClasses();
176 for (auto i = access_info.receiver_type()->Classes(); !i.Done(); 174 for (auto i = access_info.receiver_type()->Classes(); !i.Done();
177 i.Advance()) { 175 i.Advance()) {
178 DCHECK_LT(0, num_classes); 176 DCHECK_LT(0, num_classes);
179 Handle<Map> map = i.Current(); 177 Handle<Map> map = i.Current();
180 Node* check = 178 Node* check =
181 graph()->NewNode(simplified()->ReferenceEqual(Type::Internal()), 179 graph()->NewNode(simplified()->ReferenceEqual(Type::Internal()),
182 receiver_map, jsgraph()->Constant(map)); 180 receiver_map, jsgraph()->Constant(map));
183 if (--num_classes == 0 && j == access_infos.size() - 1) { 181 if (--num_classes == 0 && j == access_infos.size() - 1) {
184 Node* deoptimize = 182 check = graph()->NewNode(simplified()->CheckIf(), check, this_effect,
185 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, 183 fallthrough_control);
186 this_effect, fallthrough_control); 184 this_controls.push_back(fallthrough_control);
187 this_controls.push_back(deoptimize); 185 this_effects.push_back(check);
188 this_effects.push_back(deoptimize);
189 fallthrough_control = nullptr; 186 fallthrough_control = nullptr;
190 } else { 187 } else {
191 Node* branch = 188 Node* branch =
192 graph()->NewNode(common()->Branch(), check, fallthrough_control); 189 graph()->NewNode(common()->Branch(), check, fallthrough_control);
193 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); 190 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
194 this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch)); 191 this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
195 this_effects.push_back(this_effect); 192 this_effects.push_back(this_effect);
196 } 193 }
197 } 194 }
198 195
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 227
231 // Generate the actual property access. 228 // Generate the actual property access.
232 if (access_info.IsNotFound()) { 229 if (access_info.IsNotFound()) {
233 DCHECK_EQ(AccessMode::kLoad, access_mode); 230 DCHECK_EQ(AccessMode::kLoad, access_mode);
234 this_value = jsgraph()->UndefinedConstant(); 231 this_value = jsgraph()->UndefinedConstant();
235 } else if (access_info.IsDataConstant()) { 232 } else if (access_info.IsDataConstant()) {
236 this_value = jsgraph()->Constant(access_info.constant()); 233 this_value = jsgraph()->Constant(access_info.constant());
237 if (access_mode == AccessMode::kStore) { 234 if (access_mode == AccessMode::kStore) {
238 Node* check = graph()->NewNode( 235 Node* check = graph()->NewNode(
239 simplified()->ReferenceEqual(Type::Tagged()), value, this_value); 236 simplified()->ReferenceEqual(Type::Tagged()), value, this_value);
240 this_control = this_effect = 237 this_effect = graph()->NewNode(simplified()->CheckIf(), check,
241 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, 238 this_effect, this_control);
242 this_effect, this_control);
243 } 239 }
244 } else { 240 } else {
245 DCHECK(access_info.IsDataField()); 241 DCHECK(access_info.IsDataField());
246 FieldIndex const field_index = access_info.field_index(); 242 FieldIndex const field_index = access_info.field_index();
247 Type* const field_type = access_info.field_type(); 243 Type* const field_type = access_info.field_type();
248 if (access_mode == AccessMode::kLoad && 244 if (access_mode == AccessMode::kLoad &&
249 access_info.holder().ToHandle(&holder)) { 245 access_info.holder().ToHandle(&holder)) {
250 this_receiver = jsgraph()->Constant(holder); 246 this_receiver = jsgraph()->Constant(holder);
251 } 247 }
252 Node* this_storage = this_receiver; 248 Node* this_storage = this_receiver;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 graph()->NewNode(simplified()->CheckTaggedPointer(), this_value, 320 graph()->NewNode(simplified()->CheckTaggedPointer(), this_value,
325 this_effect, this_control); 321 this_effect, this_control);
326 if (field_type->NumClasses() == 1) { 322 if (field_type->NumClasses() == 1) {
327 // Emit a map check for the value. 323 // Emit a map check for the value.
328 Node* this_value_map = this_effect = graph()->NewNode( 324 Node* this_value_map = this_effect = graph()->NewNode(
329 simplified()->LoadField(AccessBuilder::ForMap()), this_value, 325 simplified()->LoadField(AccessBuilder::ForMap()), this_value,
330 this_effect, this_control); 326 this_effect, this_control);
331 Node* check = graph()->NewNode( 327 Node* check = graph()->NewNode(
332 simplified()->ReferenceEqual(Type::Internal()), this_value_map, 328 simplified()->ReferenceEqual(Type::Internal()), this_value_map,
333 jsgraph()->Constant(field_type->Classes().Current())); 329 jsgraph()->Constant(field_type->Classes().Current()));
334 this_control = this_effect = 330 this_effect = graph()->NewNode(simplified()->CheckIf(), check,
335 graph()->NewNode(common()->DeoptimizeUnless(), check, 331 this_effect, this_control);
336 frame_state, this_effect, this_control);
337 } else { 332 } else {
338 DCHECK_EQ(0, field_type->NumClasses()); 333 DCHECK_EQ(0, field_type->NumClasses());
339 } 334 }
340 } else { 335 } else {
341 DCHECK(field_type->Is(Type::Tagged())); 336 DCHECK(field_type->Is(Type::Tagged()));
342 } 337 }
343 Handle<Map> transition_map; 338 Handle<Map> transition_map;
344 if (access_info.transition_map().ToHandle(&transition_map)) { 339 if (access_info.transition_map().ToHandle(&transition_map)) {
345 this_effect = graph()->NewNode( 340 this_effect = graph()->NewNode(
346 common()->BeginRegion(RegionObservability::kObservable), 341 common()->BeginRegion(RegionObservability::kObservable),
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
557 Node* check = 552 Node* check =
558 graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), 553 graph()->NewNode(simplified()->ReferenceEqual(Type::Any()),
559 receiver_map, jsgraph()->Constant(map)); 554 receiver_map, jsgraph()->Constant(map));
560 if (--num_classes == 0 && num_transitions == 0 && 555 if (--num_classes == 0 && num_transitions == 0 &&
561 j == access_infos.size() - 1) { 556 j == access_infos.size() - 1) {
562 // Last map check on the fallthrough control path, do a conditional 557 // Last map check on the fallthrough control path, do a conditional
563 // eager deoptimization exit here. 558 // eager deoptimization exit here.
564 // TODO(turbofan): This is ugly as hell! We should probably introduce 559 // TODO(turbofan): This is ugly as hell! We should probably introduce
565 // macro-ish operators for property access that encapsulate this whole 560 // macro-ish operators for property access that encapsulate this whole
566 // mess. 561 // mess.
567 Node* deoptimize = 562 check = graph()->NewNode(simplified()->CheckIf(), check, effect,
568 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, 563 fallthrough_control);
569 effect, fallthrough_control); 564 this_controls.push_back(fallthrough_control);
570 this_controls.push_back(deoptimize); 565 this_effects.push_back(check);
571 this_effects.push_back(deoptimize);
572 fallthrough_control = nullptr; 566 fallthrough_control = nullptr;
573 } else { 567 } else {
574 Node* branch = 568 Node* branch =
575 graph()->NewNode(common()->Branch(), check, fallthrough_control); 569 graph()->NewNode(common()->Branch(), check, fallthrough_control);
576 this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch)); 570 this_controls.push_back(graph()->NewNode(common()->IfTrue(), branch));
577 this_effects.push_back(effect); 571 this_effects.push_back(effect);
578 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); 572 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
579 } 573 }
580 if (!map->IsJSArrayMap()) receiver_is_jsarray = false; 574 if (!map->IsJSArrayMap()) receiver_is_jsarray = false;
581 } 575 }
582 576
583 // Generate possible elements kind transitions. 577 // Generate possible elements kind transitions.
584 for (auto transition : access_info.transitions()) { 578 for (auto transition : access_info.transitions()) {
585 DCHECK_LT(0u, num_transitions); 579 DCHECK_LT(0u, num_transitions);
586 Handle<Map> transition_source = transition.first; 580 Handle<Map> transition_source = transition.first;
587 Handle<Map> transition_target = transition.second; 581 Handle<Map> transition_target = transition.second;
588 Node* transition_control; 582 Node* transition_control;
589 Node* transition_effect = effect; 583 Node* transition_effect = effect;
590 584
591 // Check if {receiver} has the specified {transition_source} map. 585 // Check if {receiver} has the specified {transition_source} map.
592 Node* check = graph()->NewNode( 586 Node* check = graph()->NewNode(
593 simplified()->ReferenceEqual(Type::Any()), receiver_map, 587 simplified()->ReferenceEqual(Type::Any()), receiver_map,
594 jsgraph()->HeapConstant(transition_source)); 588 jsgraph()->HeapConstant(transition_source));
595 if (--num_transitions == 0 && j == access_infos.size() - 1) { 589 if (--num_transitions == 0 && j == access_infos.size() - 1) {
596 transition_control = transition_effect = 590 transition_effect =
597 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, 591 graph()->NewNode(simplified()->CheckIf(), check,
598 transition_effect, fallthrough_control); 592 transition_effect, fallthrough_control);
593 transition_control = fallthrough_control;
599 fallthrough_control = nullptr; 594 fallthrough_control = nullptr;
600 } else { 595 } else {
601 Node* branch = 596 Node* branch =
602 graph()->NewNode(common()->Branch(), check, fallthrough_control); 597 graph()->NewNode(common()->Branch(), check, fallthrough_control);
603 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch); 598 fallthrough_control = graph()->NewNode(common()->IfFalse(), branch);
604 transition_control = graph()->NewNode(common()->IfTrue(), branch); 599 transition_control = graph()->NewNode(common()->IfTrue(), branch);
605 } 600 }
606 601
607 // Migrate {receiver} from {transition_source} to {transition_target}. 602 // Migrate {receiver} from {transition_source} to {transition_target}.
608 if (IsSimpleMapChangeTransition(transition_source->elements_kind(), 603 if (IsSimpleMapChangeTransition(transition_source->elements_kind(),
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 668
674 // Don't try to store to a copy-on-write backing store. 669 // Don't try to store to a copy-on-write backing store.
675 if (access_mode == AccessMode::kStore && 670 if (access_mode == AccessMode::kStore &&
676 IsFastSmiOrObjectElementsKind(elements_kind)) { 671 IsFastSmiOrObjectElementsKind(elements_kind)) {
677 Node* this_elements_map = this_effect = 672 Node* this_elements_map = this_effect =
678 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 673 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
679 this_elements, this_effect, this_control); 674 this_elements, this_effect, this_control);
680 Node* check = graph()->NewNode( 675 Node* check = graph()->NewNode(
681 simplified()->ReferenceEqual(Type::Any()), this_elements_map, 676 simplified()->ReferenceEqual(Type::Any()), this_elements_map,
682 jsgraph()->HeapConstant(factory()->fixed_array_map())); 677 jsgraph()->HeapConstant(factory()->fixed_array_map()));
683 this_control = this_effect = 678 this_effect = graph()->NewNode(simplified()->CheckIf(), check,
684 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, 679 this_effect, this_control);
685 this_effect, this_control);
686 } 680 }
687 681
688 // Load the length of the {receiver}. 682 // Load the length of the {receiver}.
689 Node* this_length = this_effect = 683 Node* this_length = this_effect =
690 receiver_is_jsarray 684 receiver_is_jsarray
691 ? graph()->NewNode( 685 ? graph()->NewNode(
692 simplified()->LoadField( 686 simplified()->LoadField(
693 AccessBuilder::ForJSArrayLength(elements_kind)), 687 AccessBuilder::ForJSArrayLength(elements_kind)),
694 this_receiver, this_effect, this_control) 688 this_receiver, this_effect, this_control)
695 : graph()->NewNode( 689 : graph()->NewNode(
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 } 1068 }
1075 1069
1076 1070
1077 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 1071 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
1078 return jsgraph()->simplified(); 1072 return jsgraph()->simplified();
1079 } 1073 }
1080 1074
1081 } // namespace compiler 1075 } // namespace compiler
1082 } // namespace internal 1076 } // namespace internal
1083 } // namespace v8 1077 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-global-object-specialization.cc ('k') | src/compiler/node-matchers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698