| 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" |
| (...skipping 535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 return Replace(value); | 546 return Replace(value); |
| 547 } | 547 } |
| 548 | 548 |
| 549 // Lookup the {name} on the global object instead. | 549 // Lookup the {name} on the global object instead. |
| 550 return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore); | 550 return ReduceGlobalAccess(node, nullptr, value, name, AccessMode::kStore); |
| 551 } | 551 } |
| 552 | 552 |
| 553 Reduction JSNativeContextSpecialization::ReduceNamedAccess( | 553 Reduction JSNativeContextSpecialization::ReduceNamedAccess( |
| 554 Node* node, Node* value, MapHandleList const& receiver_maps, | 554 Node* node, Node* value, MapHandleList const& receiver_maps, |
| 555 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, | 555 Handle<Name> name, AccessMode access_mode, LanguageMode language_mode, |
| 556 Handle<FeedbackVector> vector, FeedbackSlot slot, Node* index) { | 556 Node* index) { |
| 557 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || | 557 DCHECK(node->opcode() == IrOpcode::kJSLoadNamed || |
| 558 node->opcode() == IrOpcode::kJSStoreNamed || | 558 node->opcode() == IrOpcode::kJSStoreNamed || |
| 559 node->opcode() == IrOpcode::kJSLoadProperty || | 559 node->opcode() == IrOpcode::kJSLoadProperty || |
| 560 node->opcode() == IrOpcode::kJSStoreProperty || | 560 node->opcode() == IrOpcode::kJSStoreProperty || |
| 561 node->opcode() == IrOpcode::kJSStoreNamedOwn); | 561 node->opcode() == IrOpcode::kJSStoreNamedOwn); |
| 562 Node* receiver = NodeProperties::GetValueInput(node, 0); | 562 Node* receiver = NodeProperties::GetValueInput(node, 0); |
| 563 Node* context = NodeProperties::GetContextInput(node); | 563 Node* context = NodeProperties::GetContextInput(node); |
| 564 Node* frame_state = NodeProperties::GetFrameStateInput(node); | 564 Node* frame_state = NodeProperties::GetFrameStateInput(node); |
| 565 Node* effect = NodeProperties::GetEffectInput(node); | 565 Node* effect = NodeProperties::GetEffectInput(node); |
| 566 Node* control = NodeProperties::GetControlInput(node); | 566 Node* control = NodeProperties::GetControlInput(node); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 592 } | 592 } |
| 593 | 593 |
| 594 // TODO(turbofan): Add support for inlining into try blocks. | 594 // TODO(turbofan): Add support for inlining into try blocks. |
| 595 bool is_exceptional = NodeProperties::IsExceptionalCall(node); | 595 bool is_exceptional = NodeProperties::IsExceptionalCall(node); |
| 596 for (const auto& access_info : access_infos) { | 596 for (const auto& access_info : access_infos) { |
| 597 if (access_info.IsAccessorConstant()) { | 597 if (access_info.IsAccessorConstant()) { |
| 598 // Accessor in try-blocks are not supported yet. | 598 // Accessor in try-blocks are not supported yet. |
| 599 if (is_exceptional || !(flags() & kAccessorInliningEnabled)) { | 599 if (is_exceptional || !(flags() & kAccessorInliningEnabled)) { |
| 600 return NoChange(); | 600 return NoChange(); |
| 601 } | 601 } |
| 602 } else if (access_info.IsGeneric()) { | |
| 603 // We do not handle generic calls in try blocks. | |
| 604 if (is_exceptional) return NoChange(); | |
| 605 // We only handle the generic store IC case. | |
| 606 if (!vector->IsStoreIC(slot)) { | |
| 607 return NoChange(); | |
| 608 } | |
| 609 } | 602 } |
| 610 } | 603 } |
| 611 | 604 |
| 612 // Nothing to do if we have no non-deprecated maps. | 605 // Nothing to do if we have no non-deprecated maps. |
| 613 if (access_infos.empty()) { | 606 if (access_infos.empty()) { |
| 614 return ReduceSoftDeoptimize( | 607 return ReduceSoftDeoptimize( |
| 615 node, DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); | 608 node, DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); |
| 616 } | 609 } |
| 617 | 610 |
| 618 // Ensure that {index} matches the specified {name} (if {index} is given). | 611 // Ensure that {index} matches the specified {name} (if {index} is given). |
| (...skipping 18 matching lines...) Expand all Loading... |
| 637 } else { | 630 } else { |
| 638 // Monomorphic property access. | 631 // Monomorphic property access. |
| 639 receiver = BuildCheckHeapObject(receiver, &effect, control); | 632 receiver = BuildCheckHeapObject(receiver, &effect, control); |
| 640 effect = BuildCheckMaps(receiver, effect, control, | 633 effect = BuildCheckMaps(receiver, effect, control, |
| 641 access_info.receiver_maps()); | 634 access_info.receiver_maps()); |
| 642 } | 635 } |
| 643 | 636 |
| 644 // Generate the actual property access. | 637 // Generate the actual property access. |
| 645 ValueEffectControl continuation = BuildPropertyAccess( | 638 ValueEffectControl continuation = BuildPropertyAccess( |
| 646 receiver, value, context, frame_state, effect, control, name, | 639 receiver, value, context, frame_state, effect, control, name, |
| 647 access_info, access_mode, language_mode, vector, slot); | 640 access_info, access_mode, language_mode); |
| 648 value = continuation.value(); | 641 value = continuation.value(); |
| 649 effect = continuation.effect(); | 642 effect = continuation.effect(); |
| 650 control = continuation.control(); | 643 control = continuation.control(); |
| 651 } else { | 644 } else { |
| 652 // The final states for every polymorphic branch. We join them with | 645 // The final states for every polymorphic branch. We join them with |
| 653 // Merge+Phi+EffectPhi at the bottom. | 646 // Merge+Phi+EffectPhi at the bottom. |
| 654 ZoneVector<Node*> values(zone()); | 647 ZoneVector<Node*> values(zone()); |
| 655 ZoneVector<Node*> effects(zone()); | 648 ZoneVector<Node*> effects(zone()); |
| 656 ZoneVector<Node*> controls(zone()); | 649 ZoneVector<Node*> controls(zone()); |
| 657 | 650 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 graph()->NewNode(common()->Merge(this_control_count), | 733 graph()->NewNode(common()->Merge(this_control_count), |
| 741 this_control_count, &this_controls.front()); | 734 this_control_count, &this_controls.front()); |
| 742 this_effects.push_back(this_control); | 735 this_effects.push_back(this_control); |
| 743 this_effect = | 736 this_effect = |
| 744 graph()->NewNode(common()->EffectPhi(this_control_count), | 737 graph()->NewNode(common()->EffectPhi(this_control_count), |
| 745 this_control_count + 1, &this_effects.front()); | 738 this_control_count + 1, &this_effects.front()); |
| 746 } | 739 } |
| 747 } | 740 } |
| 748 | 741 |
| 749 // Generate the actual property access. | 742 // Generate the actual property access. |
| 750 ValueEffectControl continuation = | 743 ValueEffectControl continuation = BuildPropertyAccess( |
| 751 BuildPropertyAccess(this_receiver, this_value, context, frame_state, | 744 this_receiver, this_value, context, frame_state, this_effect, |
| 752 this_effect, this_control, name, access_info, | 745 this_control, name, access_info, access_mode, language_mode); |
| 753 access_mode, language_mode, vector, slot); | |
| 754 values.push_back(continuation.value()); | 746 values.push_back(continuation.value()); |
| 755 effects.push_back(continuation.effect()); | 747 effects.push_back(continuation.effect()); |
| 756 controls.push_back(continuation.control()); | 748 controls.push_back(continuation.control()); |
| 757 } | 749 } |
| 758 | 750 |
| 759 DCHECK_NULL(fallthrough_control); | 751 DCHECK_NULL(fallthrough_control); |
| 760 | 752 |
| 761 // Generate the final merge point for all (polymorphic) branches. | 753 // Generate the final merge point for all (polymorphic) branches. |
| 762 int const control_count = static_cast<int>(controls.size()); | 754 int const control_count = static_cast<int>(controls.size()); |
| 763 if (control_count == 0) { | 755 if (control_count == 0) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 816 if (flags() & kBailoutOnUninitialized) { | 808 if (flags() & kBailoutOnUninitialized) { |
| 817 return ReduceSoftDeoptimize( | 809 return ReduceSoftDeoptimize( |
| 818 node, | 810 node, |
| 819 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); | 811 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess); |
| 820 } | 812 } |
| 821 return NoChange(); | 813 return NoChange(); |
| 822 } | 814 } |
| 823 | 815 |
| 824 // Try to lower the named access based on the {receiver_maps}. | 816 // Try to lower the named access based on the {receiver_maps}. |
| 825 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, | 817 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, |
| 826 language_mode, nexus.vector_handle(), nexus.slot()); | 818 language_mode); |
| 827 } | 819 } |
| 828 | 820 |
| 829 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { | 821 Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { |
| 830 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); | 822 DCHECK_EQ(IrOpcode::kJSLoadNamed, node->opcode()); |
| 831 NamedAccess const& p = NamedAccessOf(node->op()); | 823 NamedAccess const& p = NamedAccessOf(node->op()); |
| 832 Node* const receiver = NodeProperties::GetValueInput(node, 0); | 824 Node* const receiver = NodeProperties::GetValueInput(node, 0); |
| 833 Node* const value = jsgraph()->Dead(); | 825 Node* const value = jsgraph()->Dead(); |
| 834 | 826 |
| 835 // Check if we have a constant receiver. | 827 // Check if we have a constant receiver. |
| 836 HeapObjectMatcher m(receiver); | 828 HeapObjectMatcher m(receiver); |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1218 // so we limit the constant indices to primitives at this point. | 1210 // so we limit the constant indices to primitives at this point. |
| 1219 Handle<Name> name; | 1211 Handle<Name> name; |
| 1220 if (Object::ToName(isolate(), mindex.Value()).ToHandle(&name)) { | 1212 if (Object::ToName(isolate(), mindex.Value()).ToHandle(&name)) { |
| 1221 uint32_t array_index; | 1213 uint32_t array_index; |
| 1222 if (name->AsArrayIndex(&array_index)) { | 1214 if (name->AsArrayIndex(&array_index)) { |
| 1223 // Use the constant array index. | 1215 // Use the constant array index. |
| 1224 index = jsgraph()->Constant(static_cast<double>(array_index)); | 1216 index = jsgraph()->Constant(static_cast<double>(array_index)); |
| 1225 } else { | 1217 } else { |
| 1226 name = factory()->InternalizeName(name); | 1218 name = factory()->InternalizeName(name); |
| 1227 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, | 1219 return ReduceNamedAccess(node, value, receiver_maps, name, access_mode, |
| 1228 language_mode, nexus.vector_handle(), | 1220 language_mode); |
| 1229 nexus.slot()); | |
| 1230 } | 1221 } |
| 1231 } | 1222 } |
| 1232 } | 1223 } |
| 1233 | 1224 |
| 1234 // Check if we have feedback for a named access. | 1225 // Check if we have feedback for a named access. |
| 1235 if (Name* name = nexus.FindFirstName()) { | 1226 if (Name* name = nexus.FindFirstName()) { |
| 1236 return ReduceNamedAccess( | 1227 return ReduceNamedAccess(node, value, receiver_maps, |
| 1237 node, value, receiver_maps, handle(name, isolate()), access_mode, | 1228 handle(name, isolate()), access_mode, |
| 1238 language_mode, nexus.vector_handle(), nexus.slot(), index); | 1229 language_mode, index); |
| 1239 } else if (nexus.GetKeyType() != ELEMENT) { | 1230 } else if (nexus.GetKeyType() != ELEMENT) { |
| 1240 // The KeyedLoad/StoreIC has seen non-element accesses, so we cannot assume | 1231 // The KeyedLoad/StoreIC has seen non-element accesses, so we cannot assume |
| 1241 // that the {index} is a valid array index, thus we just let the IC continue | 1232 // that the {index} is a valid array index, thus we just let the IC continue |
| 1242 // to deal with this load/store. | 1233 // to deal with this load/store. |
| 1243 return NoChange(); | 1234 return NoChange(); |
| 1244 } else if (nexus.ic_state() == MEGAMORPHIC) { | 1235 } else if (nexus.ic_state() == MEGAMORPHIC) { |
| 1245 // The KeyedLoad/StoreIC uses the MEGAMORPHIC state to guard the assumption | 1236 // The KeyedLoad/StoreIC uses the MEGAMORPHIC state to guard the assumption |
| 1246 // that a numeric {index} is within the valid bounds for {receiver}, i.e. | 1237 // that a numeric {index} is within the valid bounds for {receiver}, i.e. |
| 1247 // it transitions to MEGAMORPHIC once it sees an out-of-bounds access. Thus | 1238 // it transitions to MEGAMORPHIC once it sees an out-of-bounds access. Thus |
| 1248 // we cannot continue here if the IC state is MEGAMORPHIC. | 1239 // we cannot continue here if the IC state is MEGAMORPHIC. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1302 | 1293 |
| 1303 // Try to lower the keyed access based on the {nexus}. | 1294 // Try to lower the keyed access based on the {nexus}. |
| 1304 return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kStore, | 1295 return ReduceKeyedAccess(node, index, value, nexus, AccessMode::kStore, |
| 1305 p.language_mode(), store_mode); | 1296 p.language_mode(), store_mode); |
| 1306 } | 1297 } |
| 1307 | 1298 |
| 1308 JSNativeContextSpecialization::ValueEffectControl | 1299 JSNativeContextSpecialization::ValueEffectControl |
| 1309 JSNativeContextSpecialization::BuildPropertyAccess( | 1300 JSNativeContextSpecialization::BuildPropertyAccess( |
| 1310 Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect, | 1301 Node* receiver, Node* value, Node* context, Node* frame_state, Node* effect, |
| 1311 Node* control, Handle<Name> name, PropertyAccessInfo const& access_info, | 1302 Node* control, Handle<Name> name, PropertyAccessInfo const& access_info, |
| 1312 AccessMode access_mode, LanguageMode language_mode, | 1303 AccessMode access_mode, LanguageMode language_mode) { |
| 1313 Handle<FeedbackVector> vector, FeedbackSlot slot) { | |
| 1314 // Determine actual holder and perform prototype chain checks. | 1304 // Determine actual holder and perform prototype chain checks. |
| 1315 Handle<JSObject> holder; | 1305 Handle<JSObject> holder; |
| 1316 if (access_info.holder().ToHandle(&holder)) { | 1306 if (access_info.holder().ToHandle(&holder)) { |
| 1317 DCHECK_NE(AccessMode::kStoreInLiteral, access_mode); | 1307 DCHECK_NE(AccessMode::kStoreInLiteral, access_mode); |
| 1318 AssumePrototypesStable(access_info.receiver_maps(), holder); | 1308 AssumePrototypesStable(access_info.receiver_maps(), holder); |
| 1319 } | 1309 } |
| 1320 | 1310 |
| 1321 // Generate the actual property access. | 1311 // Generate the actual property access. |
| 1322 if (access_info.IsNotFound()) { | 1312 if (access_info.IsNotFound()) { |
| 1323 DCHECK_EQ(AccessMode::kLoad, access_mode); | 1313 DCHECK_EQ(AccessMode::kLoad, access_mode); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1404 ValueEffectControl value_effect_control = InlineApiCall( | 1394 ValueEffectControl value_effect_control = InlineApiCall( |
| 1405 receiver, context, target, frame_state0, value, effect, control, | 1395 receiver, context, target, frame_state0, value, effect, control, |
| 1406 shared_info, function_template_info); | 1396 shared_info, function_template_info); |
| 1407 value = value_effect_control.value(); | 1397 value = value_effect_control.value(); |
| 1408 effect = value_effect_control.effect(); | 1398 effect = value_effect_control.effect(); |
| 1409 control = value_effect_control.control(); | 1399 control = value_effect_control.control(); |
| 1410 } | 1400 } |
| 1411 break; | 1401 break; |
| 1412 } | 1402 } |
| 1413 } | 1403 } |
| 1414 } else if (access_info.IsDataField() || access_info.IsDataConstantField()) { | 1404 } else { |
| 1405 DCHECK(access_info.IsDataField() || access_info.IsDataConstantField()); |
| 1415 FieldIndex const field_index = access_info.field_index(); | 1406 FieldIndex const field_index = access_info.field_index(); |
| 1416 Type* const field_type = access_info.field_type(); | 1407 Type* const field_type = access_info.field_type(); |
| 1417 MachineRepresentation const field_representation = | 1408 MachineRepresentation const field_representation = |
| 1418 access_info.field_representation(); | 1409 access_info.field_representation(); |
| 1419 if (access_mode == AccessMode::kLoad) { | 1410 if (access_mode == AccessMode::kLoad) { |
| 1420 if (access_info.holder().ToHandle(&holder)) { | 1411 if (access_info.holder().ToHandle(&holder)) { |
| 1421 receiver = jsgraph()->Constant(holder); | 1412 receiver = jsgraph()->Constant(holder); |
| 1422 } | 1413 } |
| 1423 // Optimize immutable property loads. | 1414 // Optimize immutable property loads. |
| 1424 HeapObjectMatcher m(receiver); | 1415 HeapObjectMatcher m(receiver); |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1654 effect = graph()->NewNode(simplified()->StoreField(field_access), | 1645 effect = graph()->NewNode(simplified()->StoreField(field_access), |
| 1655 storage, value, effect, control); | 1646 storage, value, effect, control); |
| 1656 effect = graph()->NewNode(common()->FinishRegion(), | 1647 effect = graph()->NewNode(common()->FinishRegion(), |
| 1657 jsgraph()->UndefinedConstant(), effect); | 1648 jsgraph()->UndefinedConstant(), effect); |
| 1658 } else { | 1649 } else { |
| 1659 // Regular non-transitioning field store. | 1650 // Regular non-transitioning field store. |
| 1660 effect = graph()->NewNode(simplified()->StoreField(field_access), | 1651 effect = graph()->NewNode(simplified()->StoreField(field_access), |
| 1661 storage, value, effect, control); | 1652 storage, value, effect, control); |
| 1662 } | 1653 } |
| 1663 } | 1654 } |
| 1664 } else { | |
| 1665 DCHECK(access_info.IsGeneric()); | |
| 1666 DCHECK_EQ(AccessMode::kStore, access_mode); | |
| 1667 DCHECK(vector->IsStoreIC(slot)); | |
| 1668 DCHECK_EQ(vector->GetLanguageMode(slot), language_mode); | |
| 1669 Callable callable = | |
| 1670 CodeFactory::StoreICInOptimizedCode(isolate(), language_mode); | |
| 1671 const CallInterfaceDescriptor& descriptor = callable.descriptor(); | |
| 1672 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 1673 isolate(), graph()->zone(), descriptor, | |
| 1674 descriptor.GetStackParameterCount(), CallDescriptor::kNeedsFrameState, | |
| 1675 Operator::kNoProperties); | |
| 1676 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | |
| 1677 Node* name_node = jsgraph()->HeapConstant(name); | |
| 1678 Node* slot_node = jsgraph()->Constant(vector->GetIndex(slot)); | |
| 1679 Node* vector_node = jsgraph()->HeapConstant(vector); | |
| 1680 | |
| 1681 Node* inputs[] = {stub_code, receiver, name_node, value, slot_node, | |
| 1682 vector_node, context, frame_state, effect, control}; | |
| 1683 | |
| 1684 value = effect = control = | |
| 1685 graph()->NewNode(common()->Call(desc), arraysize(inputs), inputs); | |
| 1686 } | 1655 } |
| 1687 | 1656 |
| 1688 return ValueEffectControl(value, effect, control); | 1657 return ValueEffectControl(value, effect, control); |
| 1689 } | 1658 } |
| 1690 | 1659 |
| 1691 Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral( | 1660 Reduction JSNativeContextSpecialization::ReduceJSStoreDataPropertyInLiteral( |
| 1692 Node* node) { | 1661 Node* node) { |
| 1693 DCHECK_EQ(IrOpcode::kJSStoreDataPropertyInLiteral, node->opcode()); | 1662 DCHECK_EQ(IrOpcode::kJSStoreDataPropertyInLiteral, node->opcode()); |
| 1694 | 1663 |
| 1695 FeedbackParameter const& p = FeedbackParameterOf(node->op()); | 1664 FeedbackParameter const& p = FeedbackParameterOf(node->op()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1720 | 1689 |
| 1721 PropertyAccessInfo access_info; | 1690 PropertyAccessInfo access_info; |
| 1722 AccessInfoFactory access_info_factory(dependencies(), native_context(), | 1691 AccessInfoFactory access_info_factory(dependencies(), native_context(), |
| 1723 graph()->zone()); | 1692 graph()->zone()); |
| 1724 if (!access_info_factory.ComputePropertyAccessInfo( | 1693 if (!access_info_factory.ComputePropertyAccessInfo( |
| 1725 receiver_map, cached_name, AccessMode::kStoreInLiteral, | 1694 receiver_map, cached_name, AccessMode::kStoreInLiteral, |
| 1726 &access_info)) { | 1695 &access_info)) { |
| 1727 return NoChange(); | 1696 return NoChange(); |
| 1728 } | 1697 } |
| 1729 | 1698 |
| 1730 if (access_info.IsGeneric()) { | |
| 1731 return NoChange(); | |
| 1732 } | |
| 1733 | |
| 1734 Node* receiver = NodeProperties::GetValueInput(node, 0); | 1699 Node* receiver = NodeProperties::GetValueInput(node, 0); |
| 1735 Node* effect = NodeProperties::GetEffectInput(node); | 1700 Node* effect = NodeProperties::GetEffectInput(node); |
| 1736 Node* control = NodeProperties::GetControlInput(node); | 1701 Node* control = NodeProperties::GetControlInput(node); |
| 1737 | 1702 |
| 1738 // Monomorphic property access. | 1703 // Monomorphic property access. |
| 1739 receiver = BuildCheckHeapObject(receiver, &effect, control); | 1704 receiver = BuildCheckHeapObject(receiver, &effect, control); |
| 1740 | 1705 |
| 1741 effect = | 1706 effect = |
| 1742 BuildCheckMaps(receiver, effect, control, access_info.receiver_maps()); | 1707 BuildCheckMaps(receiver, effect, control, access_info.receiver_maps()); |
| 1743 | 1708 |
| 1744 // Ensure that {name} matches the cached name. | 1709 // Ensure that {name} matches the cached name. |
| 1745 Node* name = NodeProperties::GetValueInput(node, 1); | 1710 Node* name = NodeProperties::GetValueInput(node, 1); |
| 1746 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), name, | 1711 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), name, |
| 1747 jsgraph()->HeapConstant(cached_name)); | 1712 jsgraph()->HeapConstant(cached_name)); |
| 1748 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); | 1713 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); |
| 1749 | 1714 |
| 1750 Node* value = NodeProperties::GetValueInput(node, 2); | 1715 Node* value = NodeProperties::GetValueInput(node, 2); |
| 1751 Node* context = NodeProperties::GetContextInput(node); | 1716 Node* context = NodeProperties::GetContextInput(node); |
| 1752 Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node); | 1717 Node* frame_state_lazy = NodeProperties::GetFrameStateInput(node); |
| 1753 | 1718 |
| 1754 // Generate the actual property access. | 1719 // Generate the actual property access. |
| 1755 ValueEffectControl continuation = BuildPropertyAccess( | 1720 ValueEffectControl continuation = BuildPropertyAccess( |
| 1756 receiver, value, context, frame_state_lazy, effect, control, cached_name, | 1721 receiver, value, context, frame_state_lazy, effect, control, cached_name, |
| 1757 access_info, AccessMode::kStoreInLiteral, LanguageMode::SLOPPY, | 1722 access_info, AccessMode::kStoreInLiteral, LanguageMode::SLOPPY); |
| 1758 p.feedback().vector(), p.feedback().slot()); | |
| 1759 value = continuation.value(); | 1723 value = continuation.value(); |
| 1760 effect = continuation.effect(); | 1724 effect = continuation.effect(); |
| 1761 control = continuation.control(); | 1725 control = continuation.control(); |
| 1762 | 1726 |
| 1763 ReplaceWithValue(node, value, effect, control); | 1727 ReplaceWithValue(node, value, effect, control); |
| 1764 return Replace(value); | 1728 return Replace(value); |
| 1765 } | 1729 } |
| 1766 | 1730 |
| 1767 namespace { | 1731 namespace { |
| 1768 | 1732 |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2377 return jsgraph()->javascript(); | 2341 return jsgraph()->javascript(); |
| 2378 } | 2342 } |
| 2379 | 2343 |
| 2380 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { | 2344 SimplifiedOperatorBuilder* JSNativeContextSpecialization::simplified() const { |
| 2381 return jsgraph()->simplified(); | 2345 return jsgraph()->simplified(); |
| 2382 } | 2346 } |
| 2383 | 2347 |
| 2384 } // namespace compiler | 2348 } // namespace compiler |
| 2385 } // namespace internal | 2349 } // namespace internal |
| 2386 } // namespace v8 | 2350 } // namespace v8 |
| OLD | NEW |