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 |