OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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-typed-lowering.h" | 5 #include "src/compiler/js-typed-lowering.h" |
6 | 6 |
7 #include "src/ast/modules.h" | 7 #include "src/ast/modules.h" |
8 #include "src/builtins/builtins-utils.h" | 8 #include "src/builtins/builtins-utils.h" |
9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
10 #include "src/compilation-dependencies.h" | 10 #include "src/compilation-dependencies.h" |
(...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1708 return Changed(value); | 1708 return Changed(value); |
1709 } | 1709 } |
1710 | 1710 |
1711 Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { | 1711 Reduction JSTypedLowering::ReduceJSConvertReceiver(Node* node) { |
1712 DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode()); | 1712 DCHECK_EQ(IrOpcode::kJSConvertReceiver, node->opcode()); |
1713 ConvertReceiverMode mode = ConvertReceiverModeOf(node->op()); | 1713 ConvertReceiverMode mode = ConvertReceiverModeOf(node->op()); |
1714 Node* receiver = NodeProperties::GetValueInput(node, 0); | 1714 Node* receiver = NodeProperties::GetValueInput(node, 0); |
1715 Type* receiver_type = NodeProperties::GetType(receiver); | 1715 Type* receiver_type = NodeProperties::GetType(receiver); |
1716 Node* context = NodeProperties::GetContextInput(node); | 1716 Node* context = NodeProperties::GetContextInput(node); |
1717 Type* context_type = NodeProperties::GetType(context); | 1717 Type* context_type = NodeProperties::GetType(context); |
1718 Node* frame_state = NodeProperties::GetFrameStateInput(node); | |
1719 Node* effect = NodeProperties::GetEffectInput(node); | 1718 Node* effect = NodeProperties::GetEffectInput(node); |
1720 Node* control = NodeProperties::GetControlInput(node); | 1719 Node* control = NodeProperties::GetControlInput(node); |
1721 | 1720 |
1722 // Check if {receiver} is known to be a receiver. | 1721 // Check if {receiver} is known to be a receiver. |
1723 if (receiver_type->Is(Type::Receiver())) { | 1722 if (receiver_type->Is(Type::Receiver())) { |
1724 ReplaceWithValue(node, receiver, effect, control); | 1723 ReplaceWithValue(node, receiver, effect, control); |
1725 return Replace(receiver); | 1724 return Replace(receiver); |
1726 } | 1725 } |
1727 | 1726 |
1728 // If the {receiver} is known to be null or undefined, we can just replace it | 1727 // If the {receiver} is known to be null or undefined, we can just replace it |
(...skipping 26 matching lines...) Expand all Loading... |
1755 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); | 1754 graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); |
1756 | 1755 |
1757 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); | 1756 Node* if_true = graph()->NewNode(common()->IfTrue(), branch); |
1758 Node* etrue = effect; | 1757 Node* etrue = effect; |
1759 Node* rtrue = receiver; | 1758 Node* rtrue = receiver; |
1760 | 1759 |
1761 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); | 1760 Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
1762 Node* efalse = effect; | 1761 Node* efalse = effect; |
1763 Node* rfalse; | 1762 Node* rfalse; |
1764 { | 1763 { |
1765 // Convert {receiver} using the ToObjectStub. | 1764 // Convert {receiver} using the ToObjectStub. The call does not require a |
| 1765 // frame-state in this case, because neither null nor undefined is passed. |
1766 Callable callable = CodeFactory::ToObject(isolate()); | 1766 Callable callable = CodeFactory::ToObject(isolate()); |
1767 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( | 1767 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
1768 isolate(), graph()->zone(), callable.descriptor(), 0, | 1768 isolate(), graph()->zone(), callable.descriptor(), 0, |
1769 CallDescriptor::kNeedsFrameState, node->op()->properties()); | 1769 CallDescriptor::kNoFlags, node->op()->properties()); |
1770 rfalse = efalse = graph()->NewNode( | 1770 rfalse = efalse = graph()->NewNode( |
1771 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), | 1771 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), |
1772 receiver, context, frame_state, efalse); | 1772 receiver, context, efalse); |
1773 } | 1773 } |
1774 | 1774 |
1775 control = graph()->NewNode(common()->Merge(2), if_true, if_false); | 1775 control = graph()->NewNode(common()->Merge(2), if_true, if_false); |
1776 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); | 1776 effect = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, control); |
1777 | 1777 |
1778 // Morph the {node} into an appropriate Phi. | 1778 // Morph the {node} into an appropriate Phi. |
1779 ReplaceWithValue(node, node, effect, control); | 1779 ReplaceWithValue(node, node, effect, control); |
1780 node->ReplaceInput(0, rtrue); | 1780 node->ReplaceInput(0, rtrue); |
1781 node->ReplaceInput(1, rfalse); | 1781 node->ReplaceInput(1, rfalse); |
1782 node->ReplaceInput(2, control); | 1782 node->ReplaceInput(2, control); |
(...skipping 29 matching lines...) Expand all Loading... |
1812 // We just use {receiver} directly. | 1812 // We just use {receiver} directly. |
1813 Node* if_noop = if_true0; | 1813 Node* if_noop = if_true0; |
1814 Node* enoop = effect; | 1814 Node* enoop = effect; |
1815 Node* rnoop = receiver; | 1815 Node* rnoop = receiver; |
1816 | 1816 |
1817 // Convert {receiver} using ToObject. | 1817 // Convert {receiver} using ToObject. |
1818 Node* if_convert = if_false2; | 1818 Node* if_convert = if_false2; |
1819 Node* econvert = effect; | 1819 Node* econvert = effect; |
1820 Node* rconvert; | 1820 Node* rconvert; |
1821 { | 1821 { |
1822 // Convert {receiver} using the ToObjectStub. | 1822 // Convert {receiver} using the ToObjectStub. The call does not require a |
| 1823 // frame-state in this case, because neither null nor undefined is passed. |
1823 Callable callable = CodeFactory::ToObject(isolate()); | 1824 Callable callable = CodeFactory::ToObject(isolate()); |
1824 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( | 1825 CallDescriptor const* const desc = Linkage::GetStubCallDescriptor( |
1825 isolate(), graph()->zone(), callable.descriptor(), 0, | 1826 isolate(), graph()->zone(), callable.descriptor(), 0, |
1826 CallDescriptor::kNeedsFrameState, node->op()->properties()); | 1827 CallDescriptor::kNoFlags, node->op()->properties()); |
1827 rconvert = econvert = graph()->NewNode( | 1828 rconvert = econvert = graph()->NewNode( |
1828 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), | 1829 common()->Call(desc), jsgraph()->HeapConstant(callable.code()), |
1829 receiver, context, frame_state, econvert); | 1830 receiver, context, econvert); |
1830 } | 1831 } |
1831 | 1832 |
1832 // Replace {receiver} with global proxy of {context}. | 1833 // Replace {receiver} with global proxy of {context}. |
1833 Node* if_global = graph()->NewNode(common()->Merge(2), if_true1, if_true2); | 1834 Node* if_global = graph()->NewNode(common()->Merge(2), if_true1, if_true2); |
1834 Node* eglobal = effect; | 1835 Node* eglobal = effect; |
1835 Node* rglobal; | 1836 Node* rglobal; |
1836 { | 1837 { |
1837 if (context_type->IsHeapConstant()) { | 1838 if (context_type->IsHeapConstant()) { |
1838 Handle<JSObject> global_proxy( | 1839 Handle<JSObject> global_proxy( |
1839 Handle<Context>::cast(context_type->AsHeapConstant()->Value()) | 1840 Handle<Context>::cast(context_type->AsHeapConstant()->Value()) |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2056 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); | 2057 DCHECK_EQ(IrOpcode::kJSCall, node->opcode()); |
2057 CallParameters const& p = CallParametersOf(node->op()); | 2058 CallParameters const& p = CallParametersOf(node->op()); |
2058 int const arity = static_cast<int>(p.arity() - 2); | 2059 int const arity = static_cast<int>(p.arity() - 2); |
2059 ConvertReceiverMode convert_mode = p.convert_mode(); | 2060 ConvertReceiverMode convert_mode = p.convert_mode(); |
2060 Node* target = NodeProperties::GetValueInput(node, 0); | 2061 Node* target = NodeProperties::GetValueInput(node, 0); |
2061 Type* target_type = NodeProperties::GetType(target); | 2062 Type* target_type = NodeProperties::GetType(target); |
2062 Node* receiver = NodeProperties::GetValueInput(node, 1); | 2063 Node* receiver = NodeProperties::GetValueInput(node, 1); |
2063 Type* receiver_type = NodeProperties::GetType(receiver); | 2064 Type* receiver_type = NodeProperties::GetType(receiver); |
2064 Node* effect = NodeProperties::GetEffectInput(node); | 2065 Node* effect = NodeProperties::GetEffectInput(node); |
2065 Node* control = NodeProperties::GetControlInput(node); | 2066 Node* control = NodeProperties::GetControlInput(node); |
2066 Node* frame_state = NodeProperties::FindFrameStateBefore(node); | |
2067 | 2067 |
2068 // Try to infer receiver {convert_mode} from {receiver} type. | 2068 // Try to infer receiver {convert_mode} from {receiver} type. |
2069 if (receiver_type->Is(Type::NullOrUndefined())) { | 2069 if (receiver_type->Is(Type::NullOrUndefined())) { |
2070 convert_mode = ConvertReceiverMode::kNullOrUndefined; | 2070 convert_mode = ConvertReceiverMode::kNullOrUndefined; |
2071 } else if (!receiver_type->Maybe(Type::NullOrUndefined())) { | 2071 } else if (!receiver_type->Maybe(Type::NullOrUndefined())) { |
2072 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 2072 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
2073 } | 2073 } |
2074 | 2074 |
2075 // Check if {target} is a known JSFunction. | 2075 // Check if {target} is a known JSFunction. |
2076 if (target_type->IsHeapConstant() && | 2076 if (target_type->IsHeapConstant() && |
(...skipping 12 matching lines...) Expand all Loading... |
2089 Node* context = effect = graph()->NewNode( | 2089 Node* context = effect = graph()->NewNode( |
2090 simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target, | 2090 simplified()->LoadField(AccessBuilder::ForJSFunctionContext()), target, |
2091 effect, control); | 2091 effect, control); |
2092 NodeProperties::ReplaceContextInput(node, context); | 2092 NodeProperties::ReplaceContextInput(node, context); |
2093 | 2093 |
2094 // Check if we need to convert the {receiver}. | 2094 // Check if we need to convert the {receiver}. |
2095 if (is_sloppy(shared->language_mode()) && !shared->native() && | 2095 if (is_sloppy(shared->language_mode()) && !shared->native() && |
2096 !receiver_type->Is(Type::Receiver())) { | 2096 !receiver_type->Is(Type::Receiver())) { |
2097 receiver = effect = | 2097 receiver = effect = |
2098 graph()->NewNode(javascript()->ConvertReceiver(convert_mode), | 2098 graph()->NewNode(javascript()->ConvertReceiver(convert_mode), |
2099 receiver, context, frame_state, effect, control); | 2099 receiver, context, effect, control); |
2100 NodeProperties::ReplaceValueInput(node, receiver, 1); | 2100 NodeProperties::ReplaceValueInput(node, receiver, 1); |
2101 } | 2101 } |
2102 | 2102 |
2103 // Update the effect dependency for the {node}. | 2103 // Update the effect dependency for the {node}. |
2104 NodeProperties::ReplaceEffectInput(node, effect); | 2104 NodeProperties::ReplaceEffectInput(node, effect); |
2105 | 2105 |
2106 // Compute flags for the call. | 2106 // Compute flags for the call. |
2107 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; | 2107 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState; |
2108 if (p.tail_call_mode() == TailCallMode::kAllow) { | 2108 if (p.tail_call_mode() == TailCallMode::kAllow) { |
2109 flags |= CallDescriptor::kSupportsTailCalls; | 2109 flags |= CallDescriptor::kSupportsTailCalls; |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2461 } | 2461 } |
2462 | 2462 |
2463 | 2463 |
2464 CompilationDependencies* JSTypedLowering::dependencies() const { | 2464 CompilationDependencies* JSTypedLowering::dependencies() const { |
2465 return dependencies_; | 2465 return dependencies_; |
2466 } | 2466 } |
2467 | 2467 |
2468 } // namespace compiler | 2468 } // namespace compiler |
2469 } // namespace internal | 2469 } // namespace internal |
2470 } // namespace v8 | 2470 } // namespace v8 |
OLD | NEW |