OLD | NEW |
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" |
| 11 #include "src/compiler/access-info.h" |
11 #include "src/compiler/js-graph.h" | 12 #include "src/compiler/js-graph.h" |
12 #include "src/compiler/js-operator.h" | 13 #include "src/compiler/js-operator.h" |
13 #include "src/compiler/linkage.h" | 14 #include "src/compiler/linkage.h" |
14 #include "src/compiler/node-matchers.h" | 15 #include "src/compiler/node-matchers.h" |
15 #include "src/field-index-inl.h" | 16 #include "src/field-index-inl.h" |
16 #include "src/isolate-inl.h" | 17 #include "src/isolate-inl.h" |
17 #include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker! | 18 #include "src/objects-inl.h" // TODO(mstarzinger): Temporary cycle breaker! |
18 #include "src/type-cache.h" | 19 #include "src/type-cache.h" |
19 #include "src/type-feedback-vector.h" | 20 #include "src/type-feedback-vector.h" |
20 | 21 |
21 namespace v8 { | 22 namespace v8 { |
22 namespace internal { | 23 namespace internal { |
23 namespace compiler { | 24 namespace compiler { |
24 | 25 |
25 JSNativeContextSpecialization::JSNativeContextSpecialization( | 26 JSNativeContextSpecialization::JSNativeContextSpecialization( |
26 Editor* editor, JSGraph* jsgraph, Flags flags, | 27 Editor* editor, JSGraph* jsgraph, Flags flags, |
27 Handle<Context> native_context, CompilationDependencies* dependencies, | 28 MaybeHandle<Context> native_context, CompilationDependencies* dependencies, |
28 Zone* zone) | 29 Zone* zone) |
29 : AdvancedReducer(editor), | 30 : AdvancedReducer(editor), |
30 jsgraph_(jsgraph), | 31 jsgraph_(jsgraph), |
31 flags_(flags), | 32 flags_(flags), |
32 native_context_(native_context), | 33 native_context_(native_context), |
33 dependencies_(dependencies), | 34 dependencies_(dependencies), |
34 zone_(zone), | 35 zone_(zone), |
35 type_cache_(TypeCache::Get()), | 36 type_cache_(TypeCache::Get()) {} |
36 access_info_factory_(dependencies, native_context, graph()->zone()) {} | |
37 | 37 |
38 | 38 |
39 Reduction JSNativeContextSpecialization::Reduce(Node* node) { | 39 Reduction JSNativeContextSpecialization::Reduce(Node* node) { |
40 switch (node->opcode()) { | 40 switch (node->opcode()) { |
41 case IrOpcode::kJSLoadNamed: | 41 case IrOpcode::kJSLoadNamed: |
42 return ReduceJSLoadNamed(node); | 42 return ReduceJSLoadNamed(node); |
43 case IrOpcode::kJSStoreNamed: | 43 case IrOpcode::kJSStoreNamed: |
44 return ReduceJSStoreNamed(node); | 44 return ReduceJSStoreNamed(node); |
45 case IrOpcode::kJSLoadProperty: | 45 case IrOpcode::kJSLoadProperty: |
46 return ReduceJSLoadProperty(node); | 46 return ReduceJSLoadProperty(node); |
(...skipping 15 matching lines...) Expand all Loading... |
62 node->opcode() == IrOpcode::kJSLoadProperty || | 62 node->opcode() == IrOpcode::kJSLoadProperty || |
63 node->opcode() == IrOpcode::kJSStoreProperty); | 63 node->opcode() == IrOpcode::kJSStoreProperty); |
64 Node* receiver = NodeProperties::GetValueInput(node, 0); | 64 Node* receiver = NodeProperties::GetValueInput(node, 0); |
65 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 65 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
66 Node* effect = NodeProperties::GetEffectInput(node); | 66 Node* effect = NodeProperties::GetEffectInput(node); |
67 Node* control = NodeProperties::GetControlInput(node); | 67 Node* control = NodeProperties::GetControlInput(node); |
68 | 68 |
69 // Not much we can do if deoptimization support is disabled. | 69 // Not much we can do if deoptimization support is disabled. |
70 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | 70 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
71 | 71 |
| 72 // Retrieve the native context from the given {node}. |
| 73 Handle<Context> native_context; |
| 74 if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange(); |
| 75 |
72 // Compute property access infos for the receiver maps. | 76 // Compute property access infos for the receiver maps. |
| 77 AccessInfoFactory access_info_factory(dependencies(), native_context, |
| 78 graph()->zone()); |
73 ZoneVector<PropertyAccessInfo> access_infos(zone()); | 79 ZoneVector<PropertyAccessInfo> access_infos(zone()); |
74 if (!access_info_factory().ComputePropertyAccessInfos( | 80 if (!access_info_factory.ComputePropertyAccessInfos( |
75 receiver_maps, name, access_mode, &access_infos)) { | 81 receiver_maps, name, access_mode, &access_infos)) { |
76 return NoChange(); | 82 return NoChange(); |
77 } | 83 } |
78 | 84 |
79 // Nothing to do if we have no non-deprecated maps. | 85 // Nothing to do if we have no non-deprecated maps. |
80 if (access_infos.empty()) return NoChange(); | 86 if (access_infos.empty()) return NoChange(); |
81 | 87 |
82 // The final states for every polymorphic branch. We join them with | 88 // The final states for every polymorphic branch. We join them with |
83 // Merge++Phi+EffectPhi at the bottom. | 89 // Merge++Phi+EffectPhi at the bottom. |
84 ZoneVector<Node*> values(zone()); | 90 ZoneVector<Node*> values(zone()); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 this_effect = | 182 this_effect = |
177 (this_control_count == 1) | 183 (this_control_count == 1) |
178 ? this_effects.front() | 184 ? this_effects.front() |
179 : graph()->NewNode(common()->EffectPhi(this_control_count), | 185 : graph()->NewNode(common()->EffectPhi(this_control_count), |
180 this_effect_count, &this_effects.front()); | 186 this_effect_count, &this_effects.front()); |
181 } | 187 } |
182 | 188 |
183 // Determine actual holder and perform prototype chain checks. | 189 // Determine actual holder and perform prototype chain checks. |
184 Handle<JSObject> holder; | 190 Handle<JSObject> holder; |
185 if (access_info.holder().ToHandle(&holder)) { | 191 if (access_info.holder().ToHandle(&holder)) { |
186 AssumePrototypesStable(receiver_type, holder); | 192 AssumePrototypesStable(receiver_type, native_context, holder); |
187 } | 193 } |
188 | 194 |
189 // Generate the actual property access. | 195 // Generate the actual property access. |
190 if (access_info.IsNotFound()) { | 196 if (access_info.IsNotFound()) { |
191 DCHECK_EQ(AccessMode::kLoad, access_mode); | 197 DCHECK_EQ(AccessMode::kLoad, access_mode); |
192 if (is_strong(language_mode)) { | 198 if (is_strong(language_mode)) { |
193 // TODO(bmeurer/mstarzinger): Add support for lowering inside try | 199 // TODO(bmeurer/mstarzinger): Add support for lowering inside try |
194 // blocks rewiring the IfException edge to a runtime call/throw. | 200 // blocks rewiring the IfException edge to a runtime call/throw. |
195 exit_controls.push_back(this_control); | 201 exit_controls.push_back(this_control); |
196 continue; | 202 continue; |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 486 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
481 Node* effect = NodeProperties::GetEffectInput(node); | 487 Node* effect = NodeProperties::GetEffectInput(node); |
482 Node* control = NodeProperties::GetControlInput(node); | 488 Node* control = NodeProperties::GetControlInput(node); |
483 | 489 |
484 // Not much we can do if deoptimization support is disabled. | 490 // Not much we can do if deoptimization support is disabled. |
485 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); | 491 if (!(flags() & kDeoptimizationEnabled)) return NoChange(); |
486 | 492 |
487 // TODO(bmeurer): Add support for non-standard stores. | 493 // TODO(bmeurer): Add support for non-standard stores. |
488 if (store_mode != STANDARD_STORE) return NoChange(); | 494 if (store_mode != STANDARD_STORE) return NoChange(); |
489 | 495 |
| 496 // Retrieve the native context from the given {node}. |
| 497 Handle<Context> native_context; |
| 498 if (!GetNativeContext(node).ToHandle(&native_context)) return NoChange(); |
| 499 |
490 // Compute element access infos for the receiver maps. | 500 // Compute element access infos for the receiver maps. |
| 501 AccessInfoFactory access_info_factory(dependencies(), native_context, |
| 502 graph()->zone()); |
491 ZoneVector<ElementAccessInfo> access_infos(zone()); | 503 ZoneVector<ElementAccessInfo> access_infos(zone()); |
492 if (!access_info_factory().ComputeElementAccessInfos( | 504 if (!access_info_factory.ComputeElementAccessInfos(receiver_maps, access_mode, |
493 receiver_maps, access_mode, &access_infos)) { | 505 &access_infos)) { |
494 return NoChange(); | 506 return NoChange(); |
495 } | 507 } |
496 | 508 |
497 // Nothing to do if we have no non-deprecated maps. | 509 // Nothing to do if we have no non-deprecated maps. |
498 if (access_infos.empty()) return NoChange(); | 510 if (access_infos.empty()) return NoChange(); |
499 | 511 |
500 // The final states for every polymorphic branch. We join them with | 512 // The final states for every polymorphic branch. We join them with |
501 // Merge+Phi+EffectPhi at the bottom. | 513 // Merge+Phi+EffectPhi at the bottom. |
502 ZoneVector<Node*> values(zone()); | 514 ZoneVector<Node*> values(zone()); |
503 ZoneVector<Node*> effects(zone()); | 515 ZoneVector<Node*> effects(zone()); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 graph()->NewNode(common()->EffectPhi(this_control_count), | 618 graph()->NewNode(common()->EffectPhi(this_control_count), |
607 this_control_count + 1, &this_effects.front()); | 619 this_control_count + 1, &this_effects.front()); |
608 } | 620 } |
609 } | 621 } |
610 | 622 |
611 // Certain stores need a prototype chain check because shape changes | 623 // Certain stores need a prototype chain check because shape changes |
612 // could allow callbacks on elements in the prototype chain that are | 624 // could allow callbacks on elements in the prototype chain that are |
613 // not compatible with (monomorphic) keyed stores. | 625 // not compatible with (monomorphic) keyed stores. |
614 Handle<JSObject> holder; | 626 Handle<JSObject> holder; |
615 if (access_info.holder().ToHandle(&holder)) { | 627 if (access_info.holder().ToHandle(&holder)) { |
616 AssumePrototypesStable(receiver_type, holder); | 628 AssumePrototypesStable(receiver_type, native_context, holder); |
617 } | 629 } |
618 | 630 |
619 // Check that the {index} is actually a Number. | 631 // Check that the {index} is actually a Number. |
620 if (!NumberMatcher(this_index).HasValue()) { | 632 if (!NumberMatcher(this_index).HasValue()) { |
621 Node* check = | 633 Node* check = |
622 graph()->NewNode(simplified()->ObjectIsNumber(), this_index); | 634 graph()->NewNode(simplified()->ObjectIsNumber(), this_index); |
623 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), | 635 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), |
624 check, this_control); | 636 check, this_control); |
625 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); | 637 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); |
626 this_control = graph()->NewNode(common()->IfTrue(), branch); | 638 this_control = graph()->NewNode(common()->IfTrue(), branch); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 check = graph()->NewNode( | 672 check = graph()->NewNode( |
661 simplified()->ReferenceEqual(Type::Any()), this_elements_map, | 673 simplified()->ReferenceEqual(Type::Any()), this_elements_map, |
662 jsgraph()->HeapConstant(factory()->fixed_array_map())); | 674 jsgraph()->HeapConstant(factory()->fixed_array_map())); |
663 branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, | 675 branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, |
664 this_control); | 676 this_control); |
665 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); | 677 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); |
666 this_control = graph()->NewNode(common()->IfTrue(), branch); | 678 this_control = graph()->NewNode(common()->IfTrue(), branch); |
667 } | 679 } |
668 | 680 |
669 // Load the length of the {receiver}. | 681 // Load the length of the {receiver}. |
670 Node* this_length; | 682 Node* this_length = this_effect = |
671 if (receiver_is_jsarray) { | 683 receiver_is_jsarray |
672 FieldAccess length_access = { | 684 ? graph()->NewNode( |
673 kTaggedBase, JSArray::kLengthOffset, factory()->name_string(), | 685 simplified()->LoadField( |
674 type_cache_.kJSArrayLengthType, kMachAnyTagged}; | 686 AccessBuilder::ForJSArrayLength(elements_kind)), |
675 if (IsFastDoubleElementsKind(elements_kind)) { | 687 this_receiver, this_effect, this_control) |
676 length_access.type = type_cache_.kFixedDoubleArrayLengthType; | 688 : graph()->NewNode( |
677 } else if (IsFastElementsKind(elements_kind)) { | 689 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), |
678 length_access.type = type_cache_.kFixedArrayLengthType; | 690 this_elements, this_effect, this_control); |
679 } | |
680 this_length = this_effect = | |
681 graph()->NewNode(simplified()->LoadField(length_access), | |
682 this_receiver, this_effect, this_control); | |
683 } else { | |
684 this_length = this_effect = graph()->NewNode( | |
685 simplified()->LoadField(AccessBuilder::ForFixedArrayLength()), | |
686 this_elements, this_effect, this_control); | |
687 } | |
688 | 691 |
689 // Check that the {index} is in the valid range for the {receiver}. | 692 // Check that the {index} is in the valid range for the {receiver}. |
690 Node* check = graph()->NewNode(simplified()->NumberLessThan(), this_index, | 693 Node* check = graph()->NewNode(simplified()->NumberLessThan(), this_index, |
691 this_length); | 694 this_length); |
692 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, | 695 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kTrue), check, |
693 this_control); | 696 this_control); |
694 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); | 697 exit_controls.push_back(graph()->NewNode(common()->IfFalse(), branch)); |
695 this_control = graph()->NewNode(common()->IfTrue(), branch); | 698 this_control = graph()->NewNode(common()->IfTrue(), branch); |
696 | 699 |
697 // Compute the element access. | 700 // Compute the element access. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
735 check, this_control); | 738 check, this_control); |
736 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 739 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
737 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 740 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
738 // Check if we are allowed to turn the hole into undefined. | 741 // Check if we are allowed to turn the hole into undefined. |
739 Type* initial_holey_array_type = Type::Class( | 742 Type* initial_holey_array_type = Type::Class( |
740 handle(isolate()->get_initial_js_array_map(elements_kind)), | 743 handle(isolate()->get_initial_js_array_map(elements_kind)), |
741 graph()->zone()); | 744 graph()->zone()); |
742 if (receiver_type->NowIs(initial_holey_array_type) && | 745 if (receiver_type->NowIs(initial_holey_array_type) && |
743 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 746 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
744 // Add a code dependency on the array protector cell. | 747 // Add a code dependency on the array protector cell. |
745 AssumePrototypesStable(receiver_type, | 748 AssumePrototypesStable(receiver_type, native_context, |
746 isolate()->initial_object_prototype()); | 749 isolate()->initial_object_prototype()); |
747 dependencies()->AssumePropertyCell(factory()->array_protector()); | 750 dependencies()->AssumePropertyCell(factory()->array_protector()); |
748 // Turn the hole into undefined. | 751 // Turn the hole into undefined. |
749 this_control = | 752 this_control = |
750 graph()->NewNode(common()->Merge(2), if_true, if_false); | 753 graph()->NewNode(common()->Merge(2), if_true, if_false); |
751 this_value = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), | 754 this_value = graph()->NewNode(common()->Phi(kMachAnyTagged, 2), |
752 jsgraph()->UndefinedConstant(), | 755 jsgraph()->UndefinedConstant(), |
753 this_value, this_control); | 756 this_value, this_control); |
754 element_type = | 757 element_type = |
755 Type::Union(element_type, Type::Undefined(), graph()->zone()); | 758 Type::Union(element_type, Type::Undefined(), graph()->zone()); |
(...skipping 10 matching lines...) Expand all Loading... |
766 // Perform the hole check on the result. | 769 // Perform the hole check on the result. |
767 Node* check = | 770 Node* check = |
768 graph()->NewNode(simplified()->NumberIsHoleNaN(), this_value); | 771 graph()->NewNode(simplified()->NumberIsHoleNaN(), this_value); |
769 // Check if we are allowed to return the hole directly. | 772 // Check if we are allowed to return the hole directly. |
770 Type* initial_holey_array_type = Type::Class( | 773 Type* initial_holey_array_type = Type::Class( |
771 handle(isolate()->get_initial_js_array_map(elements_kind)), | 774 handle(isolate()->get_initial_js_array_map(elements_kind)), |
772 graph()->zone()); | 775 graph()->zone()); |
773 if (receiver_type->NowIs(initial_holey_array_type) && | 776 if (receiver_type->NowIs(initial_holey_array_type) && |
774 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 777 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
775 // Add a code dependency on the array protector cell. | 778 // Add a code dependency on the array protector cell. |
776 AssumePrototypesStable(receiver_type, | 779 AssumePrototypesStable(receiver_type, native_context, |
777 isolate()->initial_object_prototype()); | 780 isolate()->initial_object_prototype()); |
778 dependencies()->AssumePropertyCell(factory()->array_protector()); | 781 dependencies()->AssumePropertyCell(factory()->array_protector()); |
779 // Turn the hole into undefined. | 782 // Turn the hole into undefined. |
780 this_value = graph()->NewNode( | 783 this_value = graph()->NewNode( |
781 common()->Select(kMachAnyTagged, BranchHint::kFalse), check, | 784 common()->Select(kMachAnyTagged, BranchHint::kFalse), check, |
782 jsgraph()->UndefinedConstant(), this_value); | 785 jsgraph()->UndefinedConstant(), this_value); |
783 } else { | 786 } else { |
784 // Deoptimize in case of the hole. | 787 // Deoptimize in case of the hole. |
785 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), | 788 Node* branch = graph()->NewNode(common()->Branch(BranchHint::kFalse), |
786 check, this_control); | 789 check, this_control); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
938 // Extract the keyed access store mode from the KEYED_STORE_IC. | 941 // Extract the keyed access store mode from the KEYED_STORE_IC. |
939 KeyedAccessStoreMode store_mode = nexus.GetKeyedAccessStoreMode(); | 942 KeyedAccessStoreMode store_mode = nexus.GetKeyedAccessStoreMode(); |
940 | 943 |
941 // Try to lower the keyed access based on the {nexus}. | 944 // Try to lower the keyed access based on the {nexus}. |
942 return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kStore, | 945 return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kStore, |
943 p.language_mode(), store_mode); | 946 p.language_mode(), store_mode); |
944 } | 947 } |
945 | 948 |
946 | 949 |
947 void JSNativeContextSpecialization::AssumePrototypesStable( | 950 void JSNativeContextSpecialization::AssumePrototypesStable( |
948 Type* receiver_type, Handle<JSObject> holder) { | 951 Type* receiver_type, Handle<Context> native_context, |
| 952 Handle<JSObject> holder) { |
949 // Determine actual holder and perform prototype chain checks. | 953 // Determine actual holder and perform prototype chain checks. |
950 for (auto i = receiver_type->Classes(); !i.Done(); i.Advance()) { | 954 for (auto i = receiver_type->Classes(); !i.Done(); i.Advance()) { |
951 Handle<Map> map = i.Current(); | 955 Handle<Map> map = i.Current(); |
952 // Perform the implicit ToObject for primitives here. | 956 // Perform the implicit ToObject for primitives here. |
953 // Implemented according to ES6 section 7.3.2 GetV (V, P). | 957 // Implemented according to ES6 section 7.3.2 GetV (V, P). |
954 Handle<JSFunction> constructor; | 958 Handle<JSFunction> constructor; |
955 if (Map::GetConstructorFunction(map, native_context()) | 959 if (Map::GetConstructorFunction(map, native_context) |
956 .ToHandle(&constructor)) { | 960 .ToHandle(&constructor)) { |
957 map = handle(constructor->initial_map(), isolate()); | 961 map = handle(constructor->initial_map(), isolate()); |
958 } | 962 } |
959 for (PrototypeIterator j(map); !j.IsAtEnd(); j.Advance()) { | 963 dependencies()->AssumePrototypeMapsStable(map, holder); |
960 // Check that the {prototype} still has the same map. All prototype | |
961 // maps are guaranteed to be stable, so it's sufficient to add a | |
962 // stability dependency here. | |
963 Handle<JSReceiver> const prototype = | |
964 PrototypeIterator::GetCurrent<JSReceiver>(j); | |
965 dependencies()->AssumeMapStable(handle(prototype->map(), isolate())); | |
966 // Stop once we get to the holder. | |
967 if (prototype.is_identical_to(holder)) break; | |
968 } | |
969 } | 964 } |
970 } | 965 } |
971 | 966 |
972 | 967 |
973 void JSNativeContextSpecialization::MarkAsDeferred(Node* if_projection) { | 968 void JSNativeContextSpecialization::MarkAsDeferred(Node* if_projection) { |
974 Node* branch = NodeProperties::GetControlInput(if_projection); | 969 Node* branch = NodeProperties::GetControlInput(if_projection); |
975 DCHECK_EQ(IrOpcode::kBranch, branch->opcode()); | 970 DCHECK_EQ(IrOpcode::kBranch, branch->opcode()); |
976 if (if_projection->opcode() == IrOpcode::kIfTrue) { | 971 if (if_projection->opcode() == IrOpcode::kIfTrue) { |
977 NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kFalse)); | 972 NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kFalse)); |
978 } else { | 973 } else { |
979 DCHECK_EQ(IrOpcode::kIfFalse, if_projection->opcode()); | 974 DCHECK_EQ(IrOpcode::kIfFalse, if_projection->opcode()); |
980 NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kTrue)); | 975 NodeProperties::ChangeOp(branch, common()->Branch(BranchHint::kTrue)); |
981 } | 976 } |
982 } | 977 } |
983 | 978 |
984 | 979 |
| 980 MaybeHandle<Context> JSNativeContextSpecialization::GetNativeContext( |
| 981 Node* node) { |
| 982 Node* const context = NodeProperties::GetContextInput(node); |
| 983 return NodeProperties::GetSpecializationNativeContext(context, |
| 984 native_context()); |
| 985 } |
| 986 |
| 987 |
985 Graph* JSNativeContextSpecialization::graph() const { | 988 Graph* JSNativeContextSpecialization::graph() const { |
986 return jsgraph()->graph(); | 989 return jsgraph()->graph(); |
987 } | 990 } |
988 | 991 |
989 | 992 |
990 Isolate* JSNativeContextSpecialization::isolate() const { | 993 Isolate* JSNativeContextSpecialization::isolate() const { |
991 return jsgraph()->isolate(); | 994 return jsgraph()->isolate(); |
992 } | 995 } |
993 | 996 |
994 | 997 |
(...skipping 17 matching lines...) Expand all Loading... |
1012 } | 1015 } |
1013 | 1016 |
1014 | 1017 |
1015 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 1018 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
1016 return jsgraph()->simplified(); | 1019 return jsgraph()->simplified(); |
1017 } | 1020 } |
1018 | 1021 |
1019 } // namespace compiler | 1022 } // namespace compiler |
1020 } // namespace internal | 1023 } // namespace internal |
1021 } // namespace v8 | 1024 } // namespace v8 |
OLD | NEW |