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

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

Issue 2082523002: [turbofan] Introduce CheckTaggedSigned and CheckTaggedPointer operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix compile Created 4 years, 6 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-create-lowering.cc ('k') | src/compiler/machine-operator.cc » ('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 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
118 // Check if {receiver} may be a number. 118 // Check if {receiver} may be a number.
119 bool receiverissmi_possible = false; 119 bool receiverissmi_possible = false;
120 for (PropertyAccessInfo const& access_info : access_infos) { 120 for (PropertyAccessInfo const& access_info : access_infos) {
121 if (access_info.receiver_type()->Is(Type::Number())) { 121 if (access_info.receiver_type()->Is(Type::Number())) {
122 receiverissmi_possible = true; 122 receiverissmi_possible = true;
123 break; 123 break;
124 } 124 }
125 } 125 }
126 126
127 // Ensure that {receiver} is a heap object. 127 // Ensure that {receiver} is a heap object.
128 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
129 Node* receiverissmi_control = nullptr; 128 Node* receiverissmi_control = nullptr;
130 Node* receiverissmi_effect = effect; 129 Node* receiverissmi_effect = effect;
131 if (receiverissmi_possible) { 130 if (receiverissmi_possible) {
131 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver);
132 Node* branch = graph()->NewNode(common()->Branch(), check, control); 132 Node* branch = graph()->NewNode(common()->Branch(), check, control);
133 control = graph()->NewNode(common()->IfFalse(), branch); 133 control = graph()->NewNode(common()->IfFalse(), branch);
134 receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch); 134 receiverissmi_control = graph()->NewNode(common()->IfTrue(), branch);
135 receiverissmi_effect = effect; 135 receiverissmi_effect = effect;
136 } else { 136 } else {
137 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check, 137 receiver = effect = graph()->NewNode(simplified()->CheckTaggedPointer(),
138 frame_state, effect, control); 138 receiver, effect, control);
139 } 139 }
140 140
141 // Load the {receiver} map. The resulting effect is the dominating effect for 141 // Load the {receiver} map. The resulting effect is the dominating effect for
142 // all (polymorphic) branches. 142 // all (polymorphic) branches.
143 Node* receiver_map = effect = 143 Node* receiver_map = effect =
144 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 144 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
145 receiver, effect, control); 145 receiver, effect, control);
146 146
147 // Generate code for the various different property access patterns. 147 // Generate code for the various different property access patterns.
148 Node* fallthrough_control = control; 148 Node* fallthrough_control = control;
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 this_control = this_effect = 281 this_control = this_effect =
282 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, 282 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
283 this_effect, this_control); 283 this_effect, this_control);
284 this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()), 284 this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()),
285 this_value, this_control); 285 this_value, this_control);
286 286
287 if (!field_index.is_inobject() || field_index.is_hidden_field() || 287 if (!field_index.is_inobject() || field_index.is_hidden_field() ||
288 !FLAG_unbox_double_fields) { 288 !FLAG_unbox_double_fields) {
289 if (access_info.HasTransitionMap()) { 289 if (access_info.HasTransitionMap()) {
290 // Allocate a MutableHeapNumber for the new property. 290 // Allocate a MutableHeapNumber for the new property.
291 this_effect = 291 this_effect = graph()->NewNode(
292 graph()->NewNode(common()->BeginRegion(), this_effect); 292 common()->BeginRegion(RegionObservability::kNotObservable),
293 this_effect);
293 Node* this_box = this_effect = 294 Node* this_box = this_effect =
294 graph()->NewNode(simplified()->Allocate(NOT_TENURED), 295 graph()->NewNode(simplified()->Allocate(NOT_TENURED),
295 jsgraph()->Constant(HeapNumber::kSize), 296 jsgraph()->Constant(HeapNumber::kSize),
296 this_effect, this_control); 297 this_effect, this_control);
297 this_effect = graph()->NewNode( 298 this_effect = graph()->NewNode(
298 simplified()->StoreField(AccessBuilder::ForMap()), this_box, 299 simplified()->StoreField(AccessBuilder::ForMap()), this_box,
299 jsgraph()->HeapConstant(factory()->mutable_heap_number_map()), 300 jsgraph()->HeapConstant(factory()->mutable_heap_number_map()),
300 this_effect, this_control); 301 this_effect, this_control);
301 this_effect = graph()->NewNode( 302 this_effect = graph()->NewNode(
302 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()), 303 simplified()->StoreField(AccessBuilder::ForHeapNumberValue()),
303 this_box, this_value, this_effect, this_control); 304 this_box, this_value, this_effect, this_control);
304 this_value = this_effect = graph()->NewNode( 305 this_value = this_effect = graph()->NewNode(
305 common()->FinishRegion(), this_box, this_effect); 306 common()->FinishRegion(), this_box, this_effect);
306 307
307 field_access.type = Type::TaggedPointer(); 308 field_access.type = Type::TaggedPointer();
308 } else { 309 } else {
309 // We just store directly to the MutableHeapNumber. 310 // We just store directly to the MutableHeapNumber.
310 this_storage = this_effect = 311 this_storage = this_effect =
311 graph()->NewNode(simplified()->LoadField(field_access), 312 graph()->NewNode(simplified()->LoadField(field_access),
312 this_storage, this_effect, this_control); 313 this_storage, this_effect, this_control);
313 field_access.offset = HeapNumber::kValueOffset; 314 field_access.offset = HeapNumber::kValueOffset;
314 field_access.name = MaybeHandle<Name>(); 315 field_access.name = MaybeHandle<Name>();
315 field_access.machine_type = MachineType::Float64(); 316 field_access.machine_type = MachineType::Float64();
316 } 317 }
317 } else { 318 } else {
318 // Unboxed double field, we store directly to the field. 319 // Unboxed double field, we store directly to the field.
319 field_access.machine_type = MachineType::Float64(); 320 field_access.machine_type = MachineType::Float64();
320 } 321 }
321 } else if (field_type->Is(Type::TaggedSigned())) { 322 } else if (field_type->Is(Type::TaggedSigned())) {
322 Node* check = 323 this_value = this_effect =
323 graph()->NewNode(simplified()->ObjectIsSmi(), this_value); 324 graph()->NewNode(simplified()->CheckTaggedSigned(), this_value,
324 this_control = this_effect =
325 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
326 this_effect, this_control); 325 this_effect, this_control);
327 this_value =
328 graph()->NewNode(simplified()->TypeGuard(type_cache_.kSmi),
329 this_value, this_control);
330 } else if (field_type->Is(Type::TaggedPointer())) { 326 } else if (field_type->Is(Type::TaggedPointer())) {
331 Node* check = 327 this_value = this_effect =
332 graph()->NewNode(simplified()->ObjectIsSmi(), this_value); 328 graph()->NewNode(simplified()->CheckTaggedPointer(), this_value,
333 this_control = this_effect =
334 graph()->NewNode(common()->DeoptimizeIf(), check, frame_state,
335 this_effect, this_control); 329 this_effect, this_control);
336 if (field_type->NumClasses() == 1) { 330 if (field_type->NumClasses() == 1) {
337 // Emit a map check for the value. 331 // Emit a map check for the value.
338 Node* this_value_map = this_effect = graph()->NewNode( 332 Node* this_value_map = this_effect = graph()->NewNode(
339 simplified()->LoadField(AccessBuilder::ForMap()), this_value, 333 simplified()->LoadField(AccessBuilder::ForMap()), this_value,
340 this_effect, this_control); 334 this_effect, this_control);
341 Node* check = graph()->NewNode( 335 Node* check = graph()->NewNode(
342 simplified()->ReferenceEqual(Type::Internal()), this_value_map, 336 simplified()->ReferenceEqual(Type::Internal()), this_value_map,
343 jsgraph()->Constant(field_type->Classes().Current())); 337 jsgraph()->Constant(field_type->Classes().Current()));
344 this_control = this_effect = 338 this_control = this_effect =
345 graph()->NewNode(common()->DeoptimizeUnless(), check, 339 graph()->NewNode(common()->DeoptimizeUnless(), check,
346 frame_state, this_effect, this_control); 340 frame_state, this_effect, this_control);
347 } else { 341 } else {
348 DCHECK_EQ(0, field_type->NumClasses()); 342 DCHECK_EQ(0, field_type->NumClasses());
349 } 343 }
350 } else { 344 } else {
351 DCHECK(field_type->Is(Type::Tagged())); 345 DCHECK(field_type->Is(Type::Tagged()));
352 } 346 }
353 Handle<Map> transition_map; 347 Handle<Map> transition_map;
354 if (access_info.transition_map().ToHandle(&transition_map)) { 348 if (access_info.transition_map().ToHandle(&transition_map)) {
355 this_effect = graph()->NewNode(common()->BeginRegion(), this_effect); 349 this_effect = graph()->NewNode(
350 common()->BeginRegion(RegionObservability::kObservable),
351 this_effect);
356 this_effect = graph()->NewNode( 352 this_effect = graph()->NewNode(
357 simplified()->StoreField(AccessBuilder::ForMap()), this_receiver, 353 simplified()->StoreField(AccessBuilder::ForMap()), this_receiver,
358 jsgraph()->Constant(transition_map), this_effect, this_control); 354 jsgraph()->Constant(transition_map), this_effect, this_control);
359 } 355 }
360 this_effect = graph()->NewNode(simplified()->StoreField(field_access), 356 this_effect = graph()->NewNode(simplified()->StoreField(field_access),
361 this_storage, this_value, this_effect, 357 this_storage, this_value, this_effect,
362 this_control); 358 this_control);
363 if (access_info.HasTransitionMap()) { 359 if (access_info.HasTransitionMap()) {
364 this_effect = 360 this_effect =
365 graph()->NewNode(common()->FinishRegion(), 361 graph()->NewNode(common()->FinishRegion(),
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 // Nothing to do if we have no non-deprecated maps. 520 // Nothing to do if we have no non-deprecated maps.
525 if (access_infos.empty()) return NoChange(); 521 if (access_infos.empty()) return NoChange();
526 522
527 // The final states for every polymorphic branch. We join them with 523 // The final states for every polymorphic branch. We join them with
528 // Merge+Phi+EffectPhi at the bottom. 524 // Merge+Phi+EffectPhi at the bottom.
529 ZoneVector<Node*> values(zone()); 525 ZoneVector<Node*> values(zone());
530 ZoneVector<Node*> effects(zone()); 526 ZoneVector<Node*> effects(zone());
531 ZoneVector<Node*> controls(zone()); 527 ZoneVector<Node*> controls(zone());
532 528
533 // Ensure that {receiver} is a heap object. 529 // Ensure that {receiver} is a heap object.
534 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), receiver); 530 receiver = effect = graph()->NewNode(simplified()->CheckTaggedPointer(),
535 control = effect = graph()->NewNode(common()->DeoptimizeIf(), check, 531 receiver, effect, control);
536 frame_state, effect, control);
537 532
538 // Load the {receiver} map. The resulting effect is the dominating effect for 533 // Load the {receiver} map. The resulting effect is the dominating effect for
539 // all (polymorphic) branches. 534 // all (polymorphic) branches.
540 Node* receiver_map = effect = 535 Node* receiver_map = effect =
541 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()), 536 graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
542 receiver, effect, control); 537 receiver, effect, control);
543 538
544 // Generate code for the various different element access patterns. 539 // Generate code for the various different element access patterns.
545 Node* fallthrough_control = control; 540 Node* fallthrough_control = control;
546 for (size_t j = 0; j < access_infos.size(); ++j) { 541 for (size_t j = 0; j < access_infos.size(); ++j) {
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 // Return the signaling NaN hole directly if all uses are truncating. 773 // Return the signaling NaN hole directly if all uses are truncating.
779 mode = CheckFloat64HoleMode::kAllowReturnHole; 774 mode = CheckFloat64HoleMode::kAllowReturnHole;
780 } 775 }
781 this_value = this_effect = 776 this_value = this_effect =
782 graph()->NewNode(simplified()->CheckFloat64Hole(mode), this_value, 777 graph()->NewNode(simplified()->CheckFloat64Hole(mode), this_value,
783 this_effect, this_control); 778 this_effect, this_control);
784 } 779 }
785 } else { 780 } else {
786 DCHECK_EQ(AccessMode::kStore, access_mode); 781 DCHECK_EQ(AccessMode::kStore, access_mode);
787 if (IsFastSmiElementsKind(elements_kind)) { 782 if (IsFastSmiElementsKind(elements_kind)) {
788 Node* check = graph()->NewNode(simplified()->ObjectIsSmi(), this_value); 783 this_value = this_effect =
789 this_control = this_effect = 784 graph()->NewNode(simplified()->CheckTaggedSigned(), this_value,
790 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
791 this_effect, this_control); 785 this_effect, this_control);
792 this_value = graph()->NewNode(simplified()->TypeGuard(type_cache_.kSmi),
793 this_value, this_control);
794 } else if (IsFastDoubleElementsKind(elements_kind)) { 786 } else if (IsFastDoubleElementsKind(elements_kind)) {
795 Node* check = 787 Node* check =
796 graph()->NewNode(simplified()->ObjectIsNumber(), this_value); 788 graph()->NewNode(simplified()->ObjectIsNumber(), this_value);
797 this_control = this_effect = 789 this_control = this_effect =
798 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state, 790 graph()->NewNode(common()->DeoptimizeUnless(), check, frame_state,
799 this_effect, this_control); 791 this_effect, this_control);
800 this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()), 792 this_value = graph()->NewNode(simplified()->TypeGuard(Type::Number()),
801 this_value, this_control); 793 this_value, this_control);
802 // Make sure we do not store signalling NaNs into holey double arrays. 794 // Make sure we do not store signalling NaNs into holey double arrays.
803 if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { 795 if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 } 1083 }
1092 1084
1093 1085
1094 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 1086 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
1095 return jsgraph()->simplified(); 1087 return jsgraph()->simplified();
1096 } 1088 }
1097 1089
1098 } // namespace compiler 1090 } // namespace compiler
1099 } // namespace internal 1091 } // namespace internal
1100 } // namespace v8 1092 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-create-lowering.cc ('k') | src/compiler/machine-operator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698