| 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/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
| 7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
| 8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 1755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1766 } else if (p.arity() == 1) { | 1766 } else if (p.arity() == 1) { |
| 1767 Node* length = NodeProperties::GetValueInput(node, 2); | 1767 Node* length = NodeProperties::GetValueInput(node, 2); |
| 1768 Type* length_type = NodeProperties::GetType(length); | 1768 Type* length_type = NodeProperties::GetType(length); |
| 1769 if (length_type->Is(type_cache_.kElementLoopUnrollType)) { | 1769 if (length_type->Is(type_cache_.kElementLoopUnrollType)) { |
| 1770 int capacity = static_cast<int>(length_type->Max()); | 1770 int capacity = static_cast<int>(length_type->Max()); |
| 1771 return ReduceNewArray(node, length, capacity, site); | 1771 return ReduceNewArray(node, length, capacity, site); |
| 1772 } | 1772 } |
| 1773 } | 1773 } |
| 1774 } | 1774 } |
| 1775 | 1775 |
| 1776 // Reduce {node} to the appropriate ArrayConstructorStub backend. | |
| 1777 // Note that these stubs "behave" like JSFunctions, which means they | |
| 1778 // expect a receiver on the stack, which they remove. We just push | |
| 1779 // undefined for the receiver. | |
| 1780 ElementsKind elements_kind = site->GetElementsKind(); | |
| 1781 AllocationSiteOverrideMode override_mode = | |
| 1782 (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE) | |
| 1783 ? DISABLE_ALLOCATION_SITES | |
| 1784 : DONT_OVERRIDE; | |
| 1785 if (p.arity() == 0) { | |
| 1786 ArrayNoArgumentConstructorStub stub(isolate(), elements_kind, | |
| 1787 override_mode); | |
| 1788 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 1789 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 1, | |
| 1790 CallDescriptor::kNeedsFrameState); | |
| 1791 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | |
| 1792 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | |
| 1793 node->InsertInput(graph()->zone(), 3, jsgraph()->UndefinedConstant()); | |
| 1794 NodeProperties::ChangeOp(node, common()->Call(desc)); | |
| 1795 return Changed(node); | |
| 1796 } else if (p.arity() == 1) { | |
| 1797 // TODO(bmeurer): Optimize for the 0 length non-holey case? | |
| 1798 ArraySingleArgumentConstructorStub stub( | |
| 1799 isolate(), GetHoleyElementsKind(elements_kind), override_mode); | |
| 1800 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 1801 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, | |
| 1802 CallDescriptor::kNeedsFrameState); | |
| 1803 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | |
| 1804 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | |
| 1805 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(1)); | |
| 1806 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); | |
| 1807 NodeProperties::ChangeOp(node, common()->Call(desc)); | |
| 1808 return Changed(node); | |
| 1809 } else { | |
| 1810 int const arity = static_cast<int>(p.arity()); | |
| 1811 ArrayNArgumentsConstructorStub stub(isolate(), elements_kind, | |
| 1812 override_mode); | |
| 1813 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 1814 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), | |
| 1815 arity + 1, CallDescriptor::kNeedsFrameState); | |
| 1816 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | |
| 1817 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | |
| 1818 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity)); | |
| 1819 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); | |
| 1820 NodeProperties::ChangeOp(node, common()->Call(desc)); | |
| 1821 return Changed(node); | |
| 1822 } | |
| 1823 } | |
| 1824 | |
| 1825 | |
| 1826 Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) { | |
| 1827 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); | |
| 1828 CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); | |
| 1829 Handle<SharedFunctionInfo> shared = p.shared_info(); | |
| 1830 | |
| 1831 // Use the FastNewClosureStub that allocates in new space only for nested | |
| 1832 // functions that don't need literals cloning. | |
| 1833 if (p.pretenure() == NOT_TENURED && shared->num_literals() == 0) { | |
| 1834 Isolate* isolate = jsgraph()->isolate(); | |
| 1835 Callable callable = CodeFactory::FastNewClosure( | |
| 1836 isolate, shared->language_mode(), shared->kind()); | |
| 1837 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 1838 isolate, graph()->zone(), callable.descriptor(), 0, | |
| 1839 CallDescriptor::kNoFlags); | |
| 1840 const Operator* new_op = common()->Call(desc); | |
| 1841 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | |
| 1842 node->InsertInput(graph()->zone(), 0, stub_code); | |
| 1843 node->InsertInput(graph()->zone(), 1, jsgraph()->HeapConstant(shared)); | |
| 1844 NodeProperties::ChangeOp(node, new_op); | |
| 1845 return Changed(node); | |
| 1846 } | |
| 1847 | |
| 1848 return NoChange(); | 1776 return NoChange(); |
| 1849 } | 1777 } |
| 1850 | 1778 |
| 1851 | 1779 |
| 1852 Reduction JSTypedLowering::ReduceJSCreateIterResultObject(Node* node) { | 1780 Reduction JSTypedLowering::ReduceJSCreateIterResultObject(Node* node) { |
| 1853 DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode()); | 1781 DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode()); |
| 1854 Node* value = NodeProperties::GetValueInput(node, 0); | 1782 Node* value = NodeProperties::GetValueInput(node, 0); |
| 1855 Node* done = NodeProperties::GetValueInput(node, 1); | 1783 Node* done = NodeProperties::GetValueInput(node, 1); |
| 1856 Node* context = NodeProperties::GetContextInput(node); | 1784 Node* context = NodeProperties::GetContextInput(node); |
| 1857 Node* effect = NodeProperties::GetEffectInput(node); | 1785 Node* effect = NodeProperties::GetEffectInput(node); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1873 a.Store(AccessBuilder::ForJSObjectElements(), | 1801 a.Store(AccessBuilder::ForJSObjectElements(), |
| 1874 jsgraph()->EmptyFixedArrayConstant()); | 1802 jsgraph()->EmptyFixedArrayConstant()); |
| 1875 a.Store(AccessBuilder::ForJSIteratorResultValue(), value); | 1803 a.Store(AccessBuilder::ForJSIteratorResultValue(), value); |
| 1876 a.Store(AccessBuilder::ForJSIteratorResultDone(), done); | 1804 a.Store(AccessBuilder::ForJSIteratorResultDone(), done); |
| 1877 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); | 1805 STATIC_ASSERT(JSIteratorResult::kSize == 5 * kPointerSize); |
| 1878 a.FinishAndChange(node); | 1806 a.FinishAndChange(node); |
| 1879 return Changed(node); | 1807 return Changed(node); |
| 1880 } | 1808 } |
| 1881 | 1809 |
| 1882 | 1810 |
| 1883 Reduction JSTypedLowering::ReduceJSCreateLiteralArray(Node* node) { | |
| 1884 DCHECK_EQ(IrOpcode::kJSCreateLiteralArray, node->opcode()); | |
| 1885 CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); | |
| 1886 Handle<FixedArray> const constants = Handle<FixedArray>::cast(p.constant()); | |
| 1887 int const length = constants->length(); | |
| 1888 int const flags = p.flags(); | |
| 1889 | |
| 1890 // Use the FastCloneShallowArrayStub only for shallow boilerplates up to the | |
| 1891 // initial length limit for arrays with "fast" elements kind. | |
| 1892 // TODO(rossberg): Teach strong mode to FastCloneShallowArrayStub. | |
| 1893 if ((flags & ArrayLiteral::kShallowElements) != 0 && | |
| 1894 (flags & ArrayLiteral::kIsStrong) == 0 && | |
| 1895 length < JSArray::kInitialMaxFastElementArray) { | |
| 1896 Isolate* isolate = jsgraph()->isolate(); | |
| 1897 Callable callable = CodeFactory::FastCloneShallowArray(isolate); | |
| 1898 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 1899 isolate, graph()->zone(), callable.descriptor(), 0, | |
| 1900 (OperatorProperties::GetFrameStateInputCount(node->op()) != 0) | |
| 1901 ? CallDescriptor::kNeedsFrameState | |
| 1902 : CallDescriptor::kNoFlags); | |
| 1903 const Operator* new_op = common()->Call(desc); | |
| 1904 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | |
| 1905 Node* literal_index = jsgraph()->SmiConstant(p.index()); | |
| 1906 Node* constant_elements = jsgraph()->HeapConstant(constants); | |
| 1907 node->InsertInput(graph()->zone(), 0, stub_code); | |
| 1908 node->InsertInput(graph()->zone(), 2, literal_index); | |
| 1909 node->InsertInput(graph()->zone(), 3, constant_elements); | |
| 1910 NodeProperties::ChangeOp(node, new_op); | |
| 1911 return Changed(node); | |
| 1912 } | |
| 1913 | |
| 1914 return NoChange(); | |
| 1915 } | |
| 1916 | |
| 1917 | |
| 1918 Reduction JSTypedLowering::ReduceJSCreateLiteralObject(Node* node) { | |
| 1919 DCHECK_EQ(IrOpcode::kJSCreateLiteralObject, node->opcode()); | |
| 1920 CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); | |
| 1921 Handle<FixedArray> const constants = Handle<FixedArray>::cast(p.constant()); | |
| 1922 // Constants are pairs, see ObjectLiteral::properties_count(). | |
| 1923 int const length = constants->length() / 2; | |
| 1924 int const flags = p.flags(); | |
| 1925 | |
| 1926 // Use the FastCloneShallowObjectStub only for shallow boilerplates without | |
| 1927 // elements up to the number of properties that the stubs can handle. | |
| 1928 if ((flags & ObjectLiteral::kShallowProperties) != 0 && | |
| 1929 length <= FastCloneShallowObjectStub::kMaximumClonedProperties) { | |
| 1930 Isolate* isolate = jsgraph()->isolate(); | |
| 1931 Callable callable = CodeFactory::FastCloneShallowObject(isolate, length); | |
| 1932 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 1933 isolate, graph()->zone(), callable.descriptor(), 0, | |
| 1934 (OperatorProperties::GetFrameStateInputCount(node->op()) != 0) | |
| 1935 ? CallDescriptor::kNeedsFrameState | |
| 1936 : CallDescriptor::kNoFlags); | |
| 1937 const Operator* new_op = common()->Call(desc); | |
| 1938 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | |
| 1939 Node* literal_index = jsgraph()->SmiConstant(p.index()); | |
| 1940 Node* literal_flags = jsgraph()->SmiConstant(flags); | |
| 1941 Node* constant_elements = jsgraph()->HeapConstant(constants); | |
| 1942 node->InsertInput(graph()->zone(), 0, stub_code); | |
| 1943 node->InsertInput(graph()->zone(), 2, literal_index); | |
| 1944 node->InsertInput(graph()->zone(), 3, constant_elements); | |
| 1945 node->InsertInput(graph()->zone(), 4, literal_flags); | |
| 1946 NodeProperties::ChangeOp(node, new_op); | |
| 1947 return Changed(node); | |
| 1948 } | |
| 1949 | |
| 1950 return NoChange(); | |
| 1951 } | |
| 1952 | |
| 1953 | |
| 1954 Reduction JSTypedLowering::ReduceJSCreateFunctionContext(Node* node) { | 1811 Reduction JSTypedLowering::ReduceJSCreateFunctionContext(Node* node) { |
| 1955 DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode()); | 1812 DCHECK_EQ(IrOpcode::kJSCreateFunctionContext, node->opcode()); |
| 1956 int slot_count = OpParameter<int>(node->op()); | 1813 int slot_count = OpParameter<int>(node->op()); |
| 1957 Node* const closure = NodeProperties::GetValueInput(node, 0); | 1814 Node* const closure = NodeProperties::GetValueInput(node, 0); |
| 1958 | 1815 |
| 1959 // Use inline allocation for function contexts up to a size limit. | 1816 // Use inline allocation for function contexts up to a size limit. |
| 1960 if (slot_count < kFunctionContextAllocationLimit) { | 1817 if (slot_count < kFunctionContextAllocationLimit) { |
| 1961 // JSCreateFunctionContext[slot_count < limit]](fun) | 1818 // JSCreateFunctionContext[slot_count < limit]](fun) |
| 1962 Node* effect = NodeProperties::GetEffectInput(node); | 1819 Node* effect = NodeProperties::GetEffectInput(node); |
| 1963 Node* control = NodeProperties::GetControlInput(node); | 1820 Node* control = NodeProperties::GetControlInput(node); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1976 a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX), | 1833 a.Store(AccessBuilder::ForContextSlot(Context::NATIVE_CONTEXT_INDEX), |
| 1977 native_context); | 1834 native_context); |
| 1978 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { | 1835 for (int i = Context::MIN_CONTEXT_SLOTS; i < context_length; ++i) { |
| 1979 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant()); | 1836 a.Store(AccessBuilder::ForContextSlot(i), jsgraph()->UndefinedConstant()); |
| 1980 } | 1837 } |
| 1981 RelaxControls(node); | 1838 RelaxControls(node); |
| 1982 a.FinishAndChange(node); | 1839 a.FinishAndChange(node); |
| 1983 return Changed(node); | 1840 return Changed(node); |
| 1984 } | 1841 } |
| 1985 | 1842 |
| 1986 // Use the FastNewContextStub only for function contexts up maximum size. | |
| 1987 if (slot_count <= FastNewContextStub::kMaximumSlots) { | |
| 1988 Isolate* isolate = jsgraph()->isolate(); | |
| 1989 Callable callable = CodeFactory::FastNewContext(isolate, slot_count); | |
| 1990 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 1991 isolate, graph()->zone(), callable.descriptor(), 0, | |
| 1992 CallDescriptor::kNoFlags); | |
| 1993 const Operator* new_op = common()->Call(desc); | |
| 1994 Node* stub_code = jsgraph()->HeapConstant(callable.code()); | |
| 1995 node->InsertInput(graph()->zone(), 0, stub_code); | |
| 1996 NodeProperties::ChangeOp(node, new_op); | |
| 1997 return Changed(node); | |
| 1998 } | |
| 1999 | |
| 2000 return NoChange(); | 1843 return NoChange(); |
| 2001 } | 1844 } |
| 2002 | 1845 |
| 2003 | 1846 |
| 2004 Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) { | 1847 Reduction JSTypedLowering::ReduceJSCreateWithContext(Node* node) { |
| 2005 DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode()); | 1848 DCHECK_EQ(IrOpcode::kJSCreateWithContext, node->opcode()); |
| 2006 Node* object = NodeProperties::GetValueInput(node, 0); | 1849 Node* object = NodeProperties::GetValueInput(node, 0); |
| 2007 Node* closure = NodeProperties::GetValueInput(node, 1); | 1850 Node* closure = NodeProperties::GetValueInput(node, 1); |
| 2008 Node* effect = NodeProperties::GetEffectInput(node); | 1851 Node* effect = NodeProperties::GetEffectInput(node); |
| 2009 Node* control = NodeProperties::GetControlInput(node); | 1852 Node* control = NodeProperties::GetControlInput(node); |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2470 case IrOpcode::kJSStoreContext: | 2313 case IrOpcode::kJSStoreContext: |
| 2471 return ReduceJSStoreContext(node); | 2314 return ReduceJSStoreContext(node); |
| 2472 case IrOpcode::kJSConvertReceiver: | 2315 case IrOpcode::kJSConvertReceiver: |
| 2473 return ReduceJSConvertReceiver(node); | 2316 return ReduceJSConvertReceiver(node); |
| 2474 case IrOpcode::kJSCreate: | 2317 case IrOpcode::kJSCreate: |
| 2475 return ReduceJSCreate(node); | 2318 return ReduceJSCreate(node); |
| 2476 case IrOpcode::kJSCreateArguments: | 2319 case IrOpcode::kJSCreateArguments: |
| 2477 return ReduceJSCreateArguments(node); | 2320 return ReduceJSCreateArguments(node); |
| 2478 case IrOpcode::kJSCreateArray: | 2321 case IrOpcode::kJSCreateArray: |
| 2479 return ReduceJSCreateArray(node); | 2322 return ReduceJSCreateArray(node); |
| 2480 case IrOpcode::kJSCreateClosure: | |
| 2481 return ReduceJSCreateClosure(node); | |
| 2482 case IrOpcode::kJSCreateIterResultObject: | 2323 case IrOpcode::kJSCreateIterResultObject: |
| 2483 return ReduceJSCreateIterResultObject(node); | 2324 return ReduceJSCreateIterResultObject(node); |
| 2484 case IrOpcode::kJSCreateLiteralArray: | |
| 2485 return ReduceJSCreateLiteralArray(node); | |
| 2486 case IrOpcode::kJSCreateLiteralObject: | |
| 2487 return ReduceJSCreateLiteralObject(node); | |
| 2488 case IrOpcode::kJSCreateFunctionContext: | 2325 case IrOpcode::kJSCreateFunctionContext: |
| 2489 return ReduceJSCreateFunctionContext(node); | 2326 return ReduceJSCreateFunctionContext(node); |
| 2490 case IrOpcode::kJSCreateWithContext: | 2327 case IrOpcode::kJSCreateWithContext: |
| 2491 return ReduceJSCreateWithContext(node); | 2328 return ReduceJSCreateWithContext(node); |
| 2492 case IrOpcode::kJSCreateCatchContext: | 2329 case IrOpcode::kJSCreateCatchContext: |
| 2493 return ReduceJSCreateCatchContext(node); | 2330 return ReduceJSCreateCatchContext(node); |
| 2494 case IrOpcode::kJSCreateBlockContext: | 2331 case IrOpcode::kJSCreateBlockContext: |
| 2495 return ReduceJSCreateBlockContext(node); | 2332 return ReduceJSCreateBlockContext(node); |
| 2496 case IrOpcode::kJSCallConstruct: | 2333 case IrOpcode::kJSCallConstruct: |
| 2497 return ReduceJSCallConstruct(node); | 2334 return ReduceJSCallConstruct(node); |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2681 } | 2518 } |
| 2682 | 2519 |
| 2683 | 2520 |
| 2684 CompilationDependencies* JSTypedLowering::dependencies() const { | 2521 CompilationDependencies* JSTypedLowering::dependencies() const { |
| 2685 return dependencies_; | 2522 return dependencies_; |
| 2686 } | 2523 } |
| 2687 | 2524 |
| 2688 } // namespace compiler | 2525 } // namespace compiler |
| 2689 } // namespace internal | 2526 } // namespace internal |
| 2690 } // namespace v8 | 2527 } // namespace v8 |
| OLD | NEW |