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

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

Issue 2406803002: [turbofan] Enforce native context specialization. (Closed)
Patch Set: Remove unused variables Created 4 years, 2 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-native-context-specialization.h ('k') | src/compiler/node-properties.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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 for (auto map : maps) { 50 for (auto map : maps) {
51 if (!map->IsStringMap()) return false; 51 if (!map->IsStringMap()) return false;
52 } 52 }
53 return true; 53 return true;
54 } 54 }
55 55
56 } // namespace 56 } // namespace
57 57
58 JSNativeContextSpecialization::JSNativeContextSpecialization( 58 JSNativeContextSpecialization::JSNativeContextSpecialization(
59 Editor* editor, JSGraph* jsgraph, Flags flags, 59 Editor* editor, JSGraph* jsgraph, Flags flags,
60 MaybeHandle<Context> native_context, CompilationDependencies* dependencies, 60 Handle<Context> native_context, CompilationDependencies* dependencies,
61 Zone* zone) 61 Zone* zone)
62 : AdvancedReducer(editor), 62 : AdvancedReducer(editor),
63 jsgraph_(jsgraph), 63 jsgraph_(jsgraph),
64 flags_(flags), 64 flags_(flags),
65 native_context_(native_context), 65 native_context_(native_context),
66 dependencies_(dependencies), 66 dependencies_(dependencies),
67 zone_(zone), 67 zone_(zone),
68 type_cache_(TypeCache::Get()) {} 68 type_cache_(TypeCache::Get()) {}
69 69
70
71 Reduction JSNativeContextSpecialization::Reduce(Node* node) { 70 Reduction JSNativeContextSpecialization::Reduce(Node* node) {
72 switch (node->opcode()) { 71 switch (node->opcode()) {
73 case IrOpcode::kJSLoadContext: 72 case IrOpcode::kJSLoadContext:
74 return ReduceJSLoadContext(node); 73 return ReduceJSLoadContext(node);
75 case IrOpcode::kJSLoadNamed: 74 case IrOpcode::kJSLoadNamed:
76 return ReduceJSLoadNamed(node); 75 return ReduceJSLoadNamed(node);
77 case IrOpcode::kJSStoreNamed: 76 case IrOpcode::kJSStoreNamed:
78 return ReduceJSStoreNamed(node); 77 return ReduceJSStoreNamed(node);
79 case IrOpcode::kJSLoadProperty: 78 case IrOpcode::kJSLoadProperty:
80 return ReduceJSLoadProperty(node); 79 return ReduceJSLoadProperty(node);
81 case IrOpcode::kJSStoreProperty: 80 case IrOpcode::kJSStoreProperty:
82 return ReduceJSStoreProperty(node); 81 return ReduceJSStoreProperty(node);
83 default: 82 default:
84 break; 83 break;
85 } 84 }
86 return NoChange(); 85 return NoChange();
87 } 86 }
88 87
89 Reduction JSNativeContextSpecialization::ReduceJSLoadContext(Node* node) { 88 Reduction JSNativeContextSpecialization::ReduceJSLoadContext(Node* node) {
90 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode()); 89 DCHECK_EQ(IrOpcode::kJSLoadContext, node->opcode());
91 ContextAccess const& access = ContextAccessOf(node->op()); 90 ContextAccess const& access = ContextAccessOf(node->op());
92 Handle<Context> native_context;
93 // Specialize JSLoadContext(NATIVE_CONTEXT_INDEX) to the known native 91 // Specialize JSLoadContext(NATIVE_CONTEXT_INDEX) to the known native
94 // context (if any), so we can constant-fold those fields, which is 92 // context (if any), so we can constant-fold those fields, which is
95 // safe, since the NATIVE_CONTEXT_INDEX slot is always immutable. 93 // safe, since the NATIVE_CONTEXT_INDEX slot is always immutable.
96 if (access.index() == Context::NATIVE_CONTEXT_INDEX && 94 if (access.index() == Context::NATIVE_CONTEXT_INDEX) {
97 GetNativeContext(node).ToHandle(&native_context)) { 95 Node* value = jsgraph()->HeapConstant(native_context());
98 Node* value = jsgraph()->HeapConstant(native_context);
99 ReplaceWithValue(node, value); 96 ReplaceWithValue(node, value);
100 return Replace(value); 97 return Replace(value);
101 } 98 }
102 return NoChange(); 99 return NoChange();
103 } 100 }
104 101
105 Reduction JSNativeContextSpecialization::ReduceNamedAccess( 102 Reduction JSNativeContextSpecialization::ReduceNamedAccess(
106 Node* node, Node* value, MapHandleList const& receiver_maps, 103 Node* node, Node* value, MapHandleList const& receiver_maps,
107 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, 104 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode,
108 Node* index) { 105 Node* index) {
109 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || 106 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed ||
110 node->opcode() == IrOpcode::kJSStoreNamed || 107 node->opcode() == IrOpcode::kJSStoreNamed ||
111 node->opcode() == IrOpcode::kJSLoadProperty || 108 node->opcode() == IrOpcode::kJSLoadProperty ||
112 node->opcode() == IrOpcode::kJSStoreProperty); 109 node->opcode() == IrOpcode::kJSStoreProperty);
113 Node* receiver = NodeProperties::GetValueInput(node, 0); 110 Node* receiver = NodeProperties::GetValueInput(node, 0);
114 Node* context = NodeProperties::GetContextInput(node); 111 Node* context = NodeProperties::GetContextInput(node);
115 Node* frame_state_eager = NodeProperties::FindFrameStateBefore(node); 112 Node* frame_state_eager = NodeProperties::FindFrameStateBefore(node);
116 Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node); 113 Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node);
117 Node* effect = NodeProperties::GetEffectInput(node); 114 Node* effect = NodeProperties::GetEffectInput(node);
118 Node* control = NodeProperties::GetControlInput(node); 115 Node* control = NodeProperties::GetControlInput(node);
119 116
120 // Not much we can do if deoptimization support is disabled. 117 // Not much we can do if deoptimization support is disabled.
121 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); 118 if (!(flags() & kDeoptimizationEnabled)) return NoChange();
122 119
123 // Retrieve the native context from the given {node}.
124 Handle<Context> native_context;
125 if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange();
126
127 // Compute property access infos for the receiver maps. 120 // Compute property access infos for the receiver maps.
128 AccessInfoFactory access_info_factory(dependencies(), native_context, 121 AccessInfoFactory access_info_factory(dependencies(), native_context(),
129 graph()->zone()); 122 graph()->zone());
130 ZoneVector<PropertyAccessInfo> access_infos(zone()); 123 ZoneVector<PropertyAccessInfo> access_infos(zone());
131 if (!access_info_factory.ComputePropertyAccessInfos( 124 if (!access_info_factory.ComputePropertyAccessInfos(
132 receiver_maps, name, access_mode, &access_infos)) { 125 receiver_maps, name, access_mode, &access_infos)) {
133 return NoChange(); 126 return NoChange();
134 } 127 }
135 128
136 // TODO(turbofan): Add support for inlining into try blocks. 129 // TODO(turbofan): Add support for inlining into try blocks.
137 if (NodeProperties::IsExceptionalCall(node) || 130 if (NodeProperties::IsExceptionalCall(node) ||
138 !(flags() & kAccessorInliningEnabled)) { 131 !(flags() & kAccessorInliningEnabled)) {
(...skipping 28 matching lines...) Expand all
167 receiver = effect = graph()->NewNode(simplified()->CheckNumber(), 160 receiver = effect = graph()->NewNode(simplified()->CheckNumber(),
168 receiver, effect, control); 161 receiver, effect, control);
169 } else { 162 } else {
170 // Monomorphic property access. 163 // Monomorphic property access.
171 effect = BuildCheckHeapObject(receiver, effect, control); 164 effect = BuildCheckHeapObject(receiver, effect, control);
172 effect = BuildCheckMaps(receiver, effect, control, 165 effect = BuildCheckMaps(receiver, effect, control,
173 access_info.receiver_maps()); 166 access_info.receiver_maps());
174 } 167 }
175 168
176 // Generate the actual property access. 169 // Generate the actual property access.
177 ValueEffectControl continuation = BuildPropertyAccess( 170 ValueEffectControl continuation =
178 receiver, value, context, frame_state_lazy, effect, control, name, 171 BuildPropertyAccess(receiver, value, context, frame_state_lazy, effect,
179 native_context, access_info, access_mode); 172 control, name, access_info, access_mode);
180 value = continuation.value(); 173 value = continuation.value();
181 effect = continuation.effect(); 174 effect = continuation.effect();
182 control = continuation.control(); 175 control = continuation.control();
183 } else { 176 } else {
184 // The final states for every polymorphic branch. We join them with 177 // The final states for every polymorphic branch. We join them with
185 // Merge+Phi+EffectPhi at the bottom. 178 // Merge+Phi+EffectPhi at the bottom.
186 ZoneVector<Node*> values(zone()); 179 ZoneVector<Node*> values(zone());
187 ZoneVector<Node*> effects(zone()); 180 ZoneVector<Node*> effects(zone());
188 ZoneVector<Node*> controls(zone()); 181 ZoneVector<Node*> controls(zone());
189 182
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 // FrameState after the EffectPhi that is generated above. 273 // FrameState after the EffectPhi that is generated above.
281 this_effect = 274 this_effect =
282 graph()->NewNode(common()->Checkpoint(), frame_state_eager, 275 graph()->NewNode(common()->Checkpoint(), frame_state_eager,
283 this_effect, this_control); 276 this_effect, this_control);
284 } 277 }
285 } 278 }
286 279
287 // Generate the actual property access. 280 // Generate the actual property access.
288 ValueEffectControl continuation = BuildPropertyAccess( 281 ValueEffectControl continuation = BuildPropertyAccess(
289 this_receiver, this_value, context, frame_state_lazy, this_effect, 282 this_receiver, this_value, context, frame_state_lazy, this_effect,
290 this_control, name, native_context, access_info, access_mode); 283 this_control, name, access_info, access_mode);
291 values.push_back(continuation.value()); 284 values.push_back(continuation.value());
292 effects.push_back(continuation.effect()); 285 effects.push_back(continuation.effect());
293 controls.push_back(continuation.control()); 286 controls.push_back(continuation.control());
294 } 287 }
295 288
296 DCHECK_NULL(fallthrough_control); 289 DCHECK_NULL(fallthrough_control);
297 290
298 // Generate the final merge point for all (polymorphic) branches. 291 // Generate the final merge point for all (polymorphic) branches.
299 int const control_count = static_cast<int>(controls.size()); 292 int const control_count = static_cast<int>(controls.size());
300 if (control_count == 0) { 293 if (control_count == 0) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
446 length, effect, control); 439 length, effect, control);
447 440
448 // Load the character from the {receiver}. 441 // Load the character from the {receiver}.
449 value = graph()->NewNode(simplified()->StringCharCodeAt(), receiver, index, 442 value = graph()->NewNode(simplified()->StringCharCodeAt(), receiver, index,
450 control); 443 control);
451 444
452 // Return it as a single character string. 445 // Return it as a single character string.
453 value = graph()->NewNode(simplified()->StringFromCharCode(), value); 446 value = graph()->NewNode(simplified()->StringFromCharCode(), value);
454 } else { 447 } else {
455 // Retrieve the native context from the given {node}. 448 // Retrieve the native context from the given {node}.
456 Handle<Context> native_context;
457 if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange();
458
459 // Compute element access infos for the receiver maps. 449 // Compute element access infos for the receiver maps.
460 AccessInfoFactory access_info_factory(dependencies(), native_context, 450 AccessInfoFactory access_info_factory(dependencies(), native_context(),
461 graph()->zone()); 451 graph()->zone());
462 ZoneVector<ElementAccessInfo> access_infos(zone()); 452 ZoneVector<ElementAccessInfo> access_infos(zone());
463 if (!access_info_factory.ComputeElementAccessInfos( 453 if (!access_info_factory.ComputeElementAccessInfos(
464 receiver_maps, access_mode, &access_infos)) { 454 receiver_maps, access_mode, &access_infos)) {
465 return NoChange(); 455 return NoChange();
466 } 456 }
467 457
468 // Nothing to do if we have no non-deprecated maps. 458 // Nothing to do if we have no non-deprecated maps.
469 if (access_infos.empty()) { 459 if (access_infos.empty()) {
470 return ReduceSoftDeoptimize( 460 return ReduceSoftDeoptimize(
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 // don't have the kNoWrite flag on it, even though they are not 526 // don't have the kNoWrite flag on it, even though they are not
537 // observable by JavaScript. 527 // observable by JavaScript.
538 effect = graph()->NewNode(common()->Checkpoint(), frame_state, effect, 528 effect = graph()->NewNode(common()->Checkpoint(), frame_state, effect,
539 control); 529 control);
540 530
541 // Perform map check on the {receiver}. 531 // Perform map check on the {receiver}.
542 effect = BuildCheckMaps(receiver, effect, control, 532 effect = BuildCheckMaps(receiver, effect, control,
543 access_info.receiver_maps()); 533 access_info.receiver_maps());
544 534
545 // Access the actual element. 535 // Access the actual element.
546 ValueEffectControl continuation = BuildElementAccess( 536 ValueEffectControl continuation =
547 receiver, index, value, effect, control, native_context, access_info, 537 BuildElementAccess(receiver, index, value, effect, control,
548 access_mode, store_mode); 538 access_info, access_mode, store_mode);
549 value = continuation.value(); 539 value = continuation.value();
550 effect = continuation.effect(); 540 effect = continuation.effect();
551 control = continuation.control(); 541 control = continuation.control();
552 } else { 542 } else {
553 // The final states for every polymorphic branch. We join them with 543 // The final states for every polymorphic branch. We join them with
554 // Merge+Phi+EffectPhi at the bottom. 544 // Merge+Phi+EffectPhi at the bottom.
555 ZoneVector<Node*> values(zone()); 545 ZoneVector<Node*> values(zone());
556 ZoneVector<Node*> effects(zone()); 546 ZoneVector<Node*> effects(zone());
557 ZoneVector<Node*> controls(zone()); 547 ZoneVector<Node*> controls(zone());
558 548
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 // TODO(turbofan): The effect/control linearization will not find a 627 // TODO(turbofan): The effect/control linearization will not find a
638 // FrameState after the EffectPhi that is generated above. 628 // FrameState after the EffectPhi that is generated above.
639 this_effect = graph()->NewNode(common()->Checkpoint(), frame_state, 629 this_effect = graph()->NewNode(common()->Checkpoint(), frame_state,
640 this_effect, this_control); 630 this_effect, this_control);
641 } 631 }
642 } 632 }
643 633
644 // Access the actual element. 634 // Access the actual element.
645 ValueEffectControl continuation = BuildElementAccess( 635 ValueEffectControl continuation = BuildElementAccess(
646 this_receiver, this_index, this_value, this_effect, this_control, 636 this_receiver, this_index, this_value, this_effect, this_control,
647 native_context, access_info, access_mode, store_mode); 637 access_info, access_mode, store_mode);
648 values.push_back(continuation.value()); 638 values.push_back(continuation.value());
649 effects.push_back(continuation.effect()); 639 effects.push_back(continuation.effect());
650 controls.push_back(continuation.control()); 640 controls.push_back(continuation.control());
651 } 641 }
652 642
653 DCHECK_NULL(fallthrough_control); 643 DCHECK_NULL(fallthrough_control);
654 644
655 // Generate the final merge point for all (polymorphic) branches. 645 // Generate the final merge point for all (polymorphic) branches.
656 int const control_count = static_cast<int>(controls.size()); 646 int const control_count = static_cast<int>(controls.size());
657 if (control_count == 0) { 647 if (control_count == 0) {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 KeyedAccessStoreMode store_mode = nexus.GetKeyedAccessStoreMode(); 788 KeyedAccessStoreMode store_mode = nexus.GetKeyedAccessStoreMode();
799 789
800 // Try to lower the keyed access based on the {nexus}. 790 // Try to lower the keyed access based on the {nexus}.
801 return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kStore, 791 return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kStore,
802 p.language_mode(), store_mode); 792 p.language_mode(), store_mode);
803 } 793 }
804 794
805 JSNativeContextSpecialization::ValueEffectControl 795 JSNativeContextSpecialization::ValueEffectControl
806 JSNativeContextSpecialization::BuildPropertyAccess( 796 JSNativeContextSpecialization::BuildPropertyAccess(
807 Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect, 797 Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect,
808 Node* control, Handle<Name> name, Handle<Context> native_context, 798 Node* control, Handle<Name> name, PropertyAccessInfo const& access_info,
809 PropertyAccessInfo const& access_info, AccessMode access_mode) { 799 AccessMode access_mode) {
810 // Determine actual holder and perform prototype chain checks. 800 // Determine actual holder and perform prototype chain checks.
811 Handle<JSObject> holder; 801 Handle<JSObject> holder;
812 if (access_info.holder().ToHandle(&holder)) { 802 if (access_info.holder().ToHandle(&holder)) {
813 AssumePrototypesStable(access_info.receiver_maps(), native_context, holder); 803 AssumePrototypesStable(access_info.receiver_maps(), holder);
814 } 804 }
815 805
816 // Generate the actual property access. 806 // Generate the actual property access.
817 if (access_info.IsNotFound()) { 807 if (access_info.IsNotFound()) {
818 DCHECK_EQ(AccessMode::kLoad, access_mode); 808 DCHECK_EQ(AccessMode::kLoad, access_mode);
819 value = jsgraph()->UndefinedConstant(); 809 value = jsgraph()->UndefinedConstant();
820 } else if (access_info.IsDataConstant()) { 810 } else if (access_info.IsDataConstant()) {
821 value = jsgraph()->Constant(access_info.constant()); 811 value = jsgraph()->Constant(access_info.constant());
822 if (access_mode == AccessMode::kStore) { 812 if (access_mode == AccessMode::kStore) {
823 Node* check = 813 Node* check =
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 } 1041 }
1052 UNREACHABLE(); 1042 UNREACHABLE();
1053 return kExternalInt8Array; 1043 return kExternalInt8Array;
1054 } 1044 }
1055 1045
1056 } // namespace 1046 } // namespace
1057 1047
1058 JSNativeContextSpecialization::ValueEffectControl 1048 JSNativeContextSpecialization::ValueEffectControl
1059 JSNativeContextSpecialization::BuildElementAccess( 1049 JSNativeContextSpecialization::BuildElementAccess(
1060 Node* receiver, Node* index, Node* value, Node* effect, Node* control, 1050 Node* receiver, Node* index, Node* value, Node* effect, Node* control,
1061 Handle<Context> native_context, ElementAccessInfo const& access_info, 1051 ElementAccessInfo const& access_info, AccessMode access_mode,
1062 AccessMode access_mode, KeyedAccessStoreMode store_mode) { 1052 KeyedAccessStoreMode store_mode) {
1063 // TODO(bmeurer): We currently specialize based on elements kind. We should 1053 // TODO(bmeurer): We currently specialize based on elements kind. We should
1064 // also be able to properly support strings and other JSObjects here. 1054 // also be able to properly support strings and other JSObjects here.
1065 ElementsKind elements_kind = access_info.elements_kind(); 1055 ElementsKind elements_kind = access_info.elements_kind();
1066 MapList const& receiver_maps = access_info.receiver_maps(); 1056 MapList const& receiver_maps = access_info.receiver_maps();
1067 1057
1068 // Load the elements for the {receiver}. 1058 // Load the elements for the {receiver}.
1069 Node* elements = effect = graph()->NewNode( 1059 Node* elements = effect = graph()->NewNode(
1070 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), receiver, 1060 simplified()->LoadField(AccessBuilder::ForJSObjectElements()), receiver,
1071 effect, control); 1061 effect, control);
1072 1062
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
1227 } 1217 }
1228 // Perform the actual backing store access. 1218 // Perform the actual backing store access.
1229 value = effect = 1219 value = effect =
1230 graph()->NewNode(simplified()->LoadElement(element_access), elements, 1220 graph()->NewNode(simplified()->LoadElement(element_access), elements,
1231 index, effect, control); 1221 index, effect, control);
1232 // Handle loading from holey backing stores correctly, by either mapping 1222 // Handle loading from holey backing stores correctly, by either mapping
1233 // the hole to undefined if possible, or deoptimizing otherwise. 1223 // the hole to undefined if possible, or deoptimizing otherwise.
1234 if (elements_kind == FAST_HOLEY_ELEMENTS || 1224 if (elements_kind == FAST_HOLEY_ELEMENTS ||
1235 elements_kind == FAST_HOLEY_SMI_ELEMENTS) { 1225 elements_kind == FAST_HOLEY_SMI_ELEMENTS) {
1236 // Check if we are allowed to turn the hole into undefined. 1226 // Check if we are allowed to turn the hole into undefined.
1237 if (CanTreatHoleAsUndefined(receiver_maps, native_context)) { 1227 if (CanTreatHoleAsUndefined(receiver_maps)) {
1238 // Turn the hole into undefined. 1228 // Turn the hole into undefined.
1239 value = graph()->NewNode(simplified()->ConvertTaggedHoleToUndefined(), 1229 value = graph()->NewNode(simplified()->ConvertTaggedHoleToUndefined(),
1240 value); 1230 value);
1241 } else { 1231 } else {
1242 // Bailout if we see the hole. 1232 // Bailout if we see the hole.
1243 value = effect = graph()->NewNode(simplified()->CheckTaggedHole(), 1233 value = effect = graph()->NewNode(simplified()->CheckTaggedHole(),
1244 value, effect, control); 1234 value, effect, control);
1245 } 1235 }
1246 } else if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) { 1236 } else if (elements_kind == FAST_HOLEY_DOUBLE_ELEMENTS) {
1247 // Perform the hole check on the result. 1237 // Perform the hole check on the result.
1248 CheckFloat64HoleMode mode = CheckFloat64HoleMode::kNeverReturnHole; 1238 CheckFloat64HoleMode mode = CheckFloat64HoleMode::kNeverReturnHole;
1249 // Check if we are allowed to return the hole directly. 1239 // Check if we are allowed to return the hole directly.
1250 if (CanTreatHoleAsUndefined(receiver_maps, native_context)) { 1240 if (CanTreatHoleAsUndefined(receiver_maps)) {
1251 // Return the signaling NaN hole directly if all uses are truncating. 1241 // Return the signaling NaN hole directly if all uses are truncating.
1252 mode = CheckFloat64HoleMode::kAllowReturnHole; 1242 mode = CheckFloat64HoleMode::kAllowReturnHole;
1253 } 1243 }
1254 value = effect = graph()->NewNode(simplified()->CheckFloat64Hole(mode), 1244 value = effect = graph()->NewNode(simplified()->CheckFloat64Hole(mode),
1255 value, effect, control); 1245 value, effect, control);
1256 } 1246 }
1257 } else { 1247 } else {
1258 DCHECK_EQ(AccessMode::kStore, access_mode); 1248 DCHECK_EQ(AccessMode::kStore, access_mode);
1259 if (IsFastSmiElementsKind(elements_kind)) { 1249 if (IsFastSmiElementsKind(elements_kind)) {
1260 value = effect = 1250 value = effect =
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1350 return effect; 1340 return effect;
1351 } 1341 }
1352 default: { 1342 default: {
1353 return graph()->NewNode(simplified()->CheckHeapObject(), receiver, effect, 1343 return graph()->NewNode(simplified()->CheckHeapObject(), receiver, effect,
1354 control); 1344 control);
1355 } 1345 }
1356 } 1346 }
1357 } 1347 }
1358 1348
1359 void JSNativeContextSpecialization::AssumePrototypesStable( 1349 void JSNativeContextSpecialization::AssumePrototypesStable(
1360 std::vector<Handle<Map>> const& receiver_maps, 1350 std::vector<Handle<Map>> const& receiver_maps, Handle<JSObject> holder) {
1361 Handle<Context> native_context, Handle<JSObject> holder) {
1362 // Determine actual holder and perform prototype chain checks. 1351 // Determine actual holder and perform prototype chain checks.
1363 for (auto map : receiver_maps) { 1352 for (auto map : receiver_maps) {
1364 // Perform the implicit ToObject for primitives here. 1353 // Perform the implicit ToObject for primitives here.
1365 // Implemented according to ES6 section 7.3.2 GetV (V, P). 1354 // Implemented according to ES6 section 7.3.2 GetV (V, P).
1366 Handle<JSFunction> constructor; 1355 Handle<JSFunction> constructor;
1367 if (Map::GetConstructorFunction(map, native_context) 1356 if (Map::GetConstructorFunction(map, native_context())
1368 .ToHandle(&constructor)) { 1357 .ToHandle(&constructor)) {
1369 map = handle(constructor->initial_map(), isolate()); 1358 map = handle(constructor->initial_map(), isolate());
1370 } 1359 }
1371 dependencies()->AssumePrototypeMapsStable(map, holder); 1360 dependencies()->AssumePrototypeMapsStable(map, holder);
1372 } 1361 }
1373 } 1362 }
1374 1363
1375 bool JSNativeContextSpecialization::CanTreatHoleAsUndefined( 1364 bool JSNativeContextSpecialization::CanTreatHoleAsUndefined(
1376 std::vector<Handle<Map>> const& receiver_maps, 1365 std::vector<Handle<Map>> const& receiver_maps) {
1377 Handle<Context> native_context) {
1378 // Check if the array prototype chain is intact. 1366 // Check if the array prototype chain is intact.
1379 if (!isolate()->IsFastArrayConstructorPrototypeChainIntact()) return false; 1367 if (!isolate()->IsFastArrayConstructorPrototypeChainIntact()) return false;
1380 1368
1381 // Make sure both the initial Array and Object prototypes are stable. 1369 // Make sure both the initial Array and Object prototypes are stable.
1382 Handle<JSObject> initial_array_prototype( 1370 Handle<JSObject> initial_array_prototype(
1383 native_context->initial_array_prototype(), isolate()); 1371 native_context()->initial_array_prototype(), isolate());
1384 Handle<JSObject> initial_object_prototype( 1372 Handle<JSObject> initial_object_prototype(
1385 native_context->initial_object_prototype(), isolate()); 1373 native_context()->initial_object_prototype(), isolate());
1386 if (!initial_array_prototype->map()->is_stable() || 1374 if (!initial_array_prototype->map()->is_stable() ||
1387 !initial_object_prototype->map()->is_stable()) { 1375 !initial_object_prototype->map()->is_stable()) {
1388 return false; 1376 return false;
1389 } 1377 }
1390 1378
1391 // Check if all {receiver_maps} either have the initial Array.prototype 1379 // Check if all {receiver_maps} either have the initial Array.prototype
1392 // or the initial Object.prototype as their prototype, as those are 1380 // or the initial Object.prototype as their prototype, as those are
1393 // guarded by the array protector cell. 1381 // guarded by the array protector cell.
1394 for (Handle<Map> map : receiver_maps) { 1382 for (Handle<Map> map : receiver_maps) {
1395 if (map->prototype() != *initial_array_prototype && 1383 if (map->prototype() != *initial_array_prototype &&
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 if (initial_map->constructor_or_backpointer() == *mnewtarget.Value()) { 1472 if (initial_map->constructor_or_backpointer() == *mnewtarget.Value()) {
1485 DCHECK_EQ(*initial_map, initial_map->FindRootMap()); 1473 DCHECK_EQ(*initial_map, initial_map->FindRootMap());
1486 return initial_map; 1474 return initial_map;
1487 } 1475 }
1488 } 1476 }
1489 } 1477 }
1490 } 1478 }
1491 return MaybeHandle<Map>(); 1479 return MaybeHandle<Map>();
1492 } 1480 }
1493 1481
1494 MaybeHandle<Context> JSNativeContextSpecialization::GetNativeContext(
1495 Node* node) {
1496 Node* const context = NodeProperties::GetContextInput(node);
1497 return NodeProperties::GetSpecializationNativeContext(context,
1498 native_context());
1499 }
1500
1501
1502 Graph* JSNativeContextSpecialization::graph() const { 1482 Graph* JSNativeContextSpecialization::graph() const {
1503 return jsgraph()->graph(); 1483 return jsgraph()->graph();
1504 } 1484 }
1505 1485
1506
1507 Isolate* JSNativeContextSpecialization::isolate() const { 1486 Isolate* JSNativeContextSpecialization::isolate() const {
1508 return jsgraph()->isolate(); 1487 return jsgraph()->isolate();
1509 } 1488 }
1510 1489
1511
1512 Factory* JSNativeContextSpecialization::factory() const { 1490 Factory* JSNativeContextSpecialization::factory() const {
1513 return isolate()->factory(); 1491 return isolate()->factory();
1514 } 1492 }
1515 1493
1516
1517 MachineOperatorBuilder* JSNativeContextSpecialization::machine() const { 1494 MachineOperatorBuilder* JSNativeContextSpecialization::machine() const {
1518 return jsgraph()->machine(); 1495 return jsgraph()->machine();
1519 } 1496 }
1520 1497
1521
1522 CommonOperatorBuilder* JSNativeContextSpecialization::common() const { 1498 CommonOperatorBuilder* JSNativeContextSpecialization::common() const {
1523 return jsgraph()->common(); 1499 return jsgraph()->common();
1524 } 1500 }
1525 1501
1526
1527 JSOperatorBuilder* JSNativeContextSpecialization::javascript() const { 1502 JSOperatorBuilder* JSNativeContextSpecialization::javascript() const {
1528 return jsgraph()->javascript(); 1503 return jsgraph()->javascript();
1529 } 1504 }
1530 1505
1531
1532 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { 1506 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const {
1533 return jsgraph()->simplified(); 1507 return jsgraph()->simplified();
1534 } 1508 }
1535 1509
1536 } // namespace compiler 1510 } // namespace compiler
1537 } // namespace internal 1511 } // namespace internal
1538 } // namespace v8 1512 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-native-context-specialization.h ('k') | src/compiler/node-properties.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698