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/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 1333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1344 PrepareFrameState(value, stmt->FilterId(), | 1344 PrepareFrameState(value, stmt->FilterId(), |
1345 OutputFrameStateCombine::Push()); | 1345 OutputFrameStateCombine::Push()); |
1346 IfBuilder test_value(this); | 1346 IfBuilder test_value(this); |
1347 Node* test_value_cond = NewNode(javascript()->StrictEqual(), value, | 1347 Node* test_value_cond = NewNode(javascript()->StrictEqual(), value, |
1348 jsgraph()->UndefinedConstant()); | 1348 jsgraph()->UndefinedConstant()); |
1349 test_value.If(test_value_cond, BranchHint::kFalse); | 1349 test_value.If(test_value_cond, BranchHint::kFalse); |
1350 test_value.Then(); | 1350 test_value.Then(); |
1351 test_value.Else(); | 1351 test_value.Else(); |
1352 { | 1352 { |
1353 // Bind value and do loop body. | 1353 // Bind value and do loop body. |
1354 VisitForInAssignment(stmt->each(), value, stmt->AssignmentId()); | 1354 VisitForInAssignment(stmt->each(), value, |
1355 ResolveFeedbackSlot(stmt->EachFeedbackSlot()), | |
Michael Starzinger
2015/06/15 14:20:11
nit: Please pull into local variable for consisten
mvstanton
2015/06/21 13:37:35
Done.
| |
1356 stmt->AssignmentId()); | |
1355 VisitIterationBody(stmt, &for_loop); | 1357 VisitIterationBody(stmt, &for_loop); |
1356 } | 1358 } |
1357 test_value.End(); | 1359 test_value.End(); |
1358 index = environment()->Peek(0); | 1360 index = environment()->Peek(0); |
1359 for_loop.EndBody(); | 1361 for_loop.EndBody(); |
1360 | 1362 |
1361 // Increment counter and continue. | 1363 // Increment counter and continue. |
1362 index = NewNode(javascript()->ForInStep(), index); | 1364 index = NewNode(javascript()->ForInStep(), index); |
1363 environment()->Poke(0, index); | 1365 environment()->Poke(0, index); |
1364 } | 1366 } |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1564 // is needed here since the constructor is created by the class literal. | 1566 // is needed here since the constructor is created by the class literal. |
1565 Node* proto = | 1567 Node* proto = |
1566 BuildLoadObjectField(literal, JSFunction::kPrototypeOrInitialMapOffset); | 1568 BuildLoadObjectField(literal, JSFunction::kPrototypeOrInitialMapOffset); |
1567 | 1569 |
1568 // The class literal and the prototype are both expected on the operand stack | 1570 // The class literal and the prototype are both expected on the operand stack |
1569 // during evaluation of the method values. | 1571 // during evaluation of the method values. |
1570 environment()->Push(literal); | 1572 environment()->Push(literal); |
1571 environment()->Push(proto); | 1573 environment()->Push(proto); |
1572 | 1574 |
1573 // Create nodes to store method values into the literal. | 1575 // Create nodes to store method values into the literal. |
1576 int store_slot_index = 0; | |
1574 for (int i = 0; i < expr->properties()->length(); i++) { | 1577 for (int i = 0; i < expr->properties()->length(); i++) { |
1575 ObjectLiteral::Property* property = expr->properties()->at(i); | 1578 ObjectLiteral::Property* property = expr->properties()->at(i); |
1576 environment()->Push(property->is_static() ? literal : proto); | 1579 environment()->Push(property->is_static() ? literal : proto); |
1577 | 1580 |
1578 VisitForValue(property->key()); | 1581 VisitForValue(property->key()); |
1579 Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i)); | 1582 Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i)); |
1580 environment()->Push(name); | 1583 environment()->Push(name); |
1581 | 1584 |
1582 // The static prototype property is read only. We handle the non computed | 1585 // The static prototype property is read only. We handle the non computed |
1583 // property name case in the parser. Since this is the only case where we | 1586 // property name case in the parser. Since this is the only case where we |
1584 // need to check for an own read only property we special case this so we do | 1587 // need to check for an own read only property we special case this so we do |
1585 // not need to do this for every property. | 1588 // not need to do this for every property. |
1586 if (property->is_static() && property->is_computed_name()) { | 1589 if (property->is_static() && property->is_computed_name()) { |
1587 Node* check = BuildThrowIfStaticPrototype(environment()->Pop(), | 1590 Node* check = BuildThrowIfStaticPrototype(environment()->Pop(), |
1588 expr->GetIdForProperty(i)); | 1591 expr->GetIdForProperty(i)); |
1589 environment()->Push(check); | 1592 environment()->Push(check); |
1590 } | 1593 } |
1591 | 1594 |
1592 VisitForValue(property->value()); | 1595 VisitForValue(property->value()); |
1593 Node* value = environment()->Pop(); | 1596 Node* value = environment()->Pop(); |
1594 Node* key = environment()->Pop(); | 1597 Node* key = environment()->Pop(); |
1595 Node* receiver = environment()->Pop(); | 1598 Node* receiver = environment()->Pop(); |
1596 BuildSetHomeObject(value, receiver, property->value()); | 1599 ResolvedFeedbackSlot slot = ResolveFeedbackSlot( |
1600 expr->SlotForHomeObject(property->value(), &store_slot_index)); | |
1601 BuildSetHomeObject(value, receiver, property->value(), slot); | |
1597 | 1602 |
1598 switch (property->kind()) { | 1603 switch (property->kind()) { |
1599 case ObjectLiteral::Property::CONSTANT: | 1604 case ObjectLiteral::Property::CONSTANT: |
1600 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1605 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1601 case ObjectLiteral::Property::PROTOTYPE: | 1606 case ObjectLiteral::Property::PROTOTYPE: |
1602 UNREACHABLE(); | 1607 UNREACHABLE(); |
1603 case ObjectLiteral::Property::COMPUTED: { | 1608 case ObjectLiteral::Property::COMPUTED: { |
1604 const Operator* op = | 1609 const Operator* op = |
1605 javascript()->CallRuntime(Runtime::kDefineClassMethod, 3); | 1610 javascript()->CallRuntime(Runtime::kDefineClassMethod, 3); |
1606 NewNode(op, receiver, key, value); | 1611 NewNode(op, receiver, key, value); |
(...skipping 19 matching lines...) Expand all Loading... | |
1626 // Transform both the class literal and the prototype to fast properties. | 1631 // Transform both the class literal and the prototype to fast properties. |
1627 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1); | 1632 const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties, 1); |
1628 NewNode(op, environment()->Pop()); // prototype | 1633 NewNode(op, environment()->Pop()); // prototype |
1629 NewNode(op, environment()->Pop()); // literal | 1634 NewNode(op, environment()->Pop()); // literal |
1630 | 1635 |
1631 // Assign to class variable. | 1636 // Assign to class variable. |
1632 if (expr->scope() != NULL) { | 1637 if (expr->scope() != NULL) { |
1633 DCHECK_NOT_NULL(expr->class_variable_proxy()); | 1638 DCHECK_NOT_NULL(expr->class_variable_proxy()); |
1634 Variable* var = expr->class_variable_proxy()->var(); | 1639 Variable* var = expr->class_variable_proxy()->var(); |
1635 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 1640 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
1636 BuildVariableAssignment(var, literal, Token::INIT_CONST, BailoutId::None(), | 1641 ResolvedFeedbackSlot slot = |
1637 states); | 1642 ResolveFeedbackSlot(FLAG_vector_stores |
1643 ? expr->GetNthSlot(store_slot_index++) | |
1644 : FeedbackVectorICSlot::Invalid()); | |
1645 BuildVariableAssignment(var, literal, Token::INIT_CONST, slot, | |
1646 BailoutId::None(), states); | |
1638 } | 1647 } |
1639 | 1648 |
1640 ast_context()->ProduceValue(literal); | 1649 ast_context()->ProduceValue(literal); |
1641 } | 1650 } |
1642 | 1651 |
1643 | 1652 |
1644 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { | 1653 void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { |
1645 UNREACHABLE(); | 1654 UNREACHABLE(); |
1646 } | 1655 } |
1647 | 1656 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1705 Node* literal = NewNode(op, literals_array, literal_index, constants); | 1714 Node* literal = NewNode(op, literals_array, literal_index, constants); |
1706 PrepareFrameState(literal, expr->CreateLiteralId(), | 1715 PrepareFrameState(literal, expr->CreateLiteralId(), |
1707 OutputFrameStateCombine::Push()); | 1716 OutputFrameStateCombine::Push()); |
1708 | 1717 |
1709 // The object is expected on the operand stack during computation of the | 1718 // The object is expected on the operand stack during computation of the |
1710 // property values and is the value of the entire expression. | 1719 // property values and is the value of the entire expression. |
1711 environment()->Push(literal); | 1720 environment()->Push(literal); |
1712 | 1721 |
1713 // Create nodes to store computed values into the literal. | 1722 // Create nodes to store computed values into the literal. |
1714 int property_index = 0; | 1723 int property_index = 0; |
1724 int store_slot_index = 0; | |
1715 AccessorTable accessor_table(zone()); | 1725 AccessorTable accessor_table(zone()); |
1716 for (; property_index < expr->properties()->length(); property_index++) { | 1726 for (; property_index < expr->properties()->length(); property_index++) { |
1717 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1727 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1718 if (property->is_computed_name()) break; | 1728 if (property->is_computed_name()) break; |
1719 if (property->IsCompileTimeValue()) continue; | 1729 if (property->IsCompileTimeValue()) continue; |
1720 | 1730 |
1721 Literal* key = property->key()->AsLiteral(); | 1731 Literal* key = property->key()->AsLiteral(); |
1722 switch (property->kind()) { | 1732 switch (property->kind()) { |
1723 case ObjectLiteral::Property::CONSTANT: | 1733 case ObjectLiteral::Property::CONSTANT: |
1724 UNREACHABLE(); | 1734 UNREACHABLE(); |
1725 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1735 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1726 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1736 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1727 // Fall through. | 1737 // Fall through. |
1728 case ObjectLiteral::Property::COMPUTED: { | 1738 case ObjectLiteral::Property::COMPUTED: { |
1729 // It is safe to use [[Put]] here because the boilerplate already | 1739 // It is safe to use [[Put]] here because the boilerplate already |
1730 // contains computed properties with an uninitialized value. | 1740 // contains computed properties with an uninitialized value. |
1731 if (key->value()->IsInternalizedString()) { | 1741 if (key->value()->IsInternalizedString()) { |
1732 if (property->emit_store()) { | 1742 if (property->emit_store()) { |
1733 VisitForValue(property->value()); | 1743 VisitForValue(property->value()); |
1734 FrameStateBeforeAndAfter states(this, property->value()->id()); | 1744 FrameStateBeforeAndAfter states(this, property->value()->id()); |
1735 Node* value = environment()->Pop(); | 1745 Node* value = environment()->Pop(); |
1736 Handle<Name> name = key->AsPropertyName(); | 1746 Handle<Name> name = key->AsPropertyName(); |
1737 Node* store = | 1747 ResolvedFeedbackSlot slot = |
1738 BuildNamedStore(literal, name, value, TypeFeedbackId::None()); | 1748 FLAG_vector_stores |
1749 ? ResolveFeedbackSlot(expr->GetNthSlot(store_slot_index++)) | |
1750 : ResolvedFeedbackSlot(); | |
1751 Node* store = BuildNamedStore(literal, name, value, slot, | |
1752 TypeFeedbackId::None()); | |
1739 states.AddToNode(store, key->id(), | 1753 states.AddToNode(store, key->id(), |
1740 OutputFrameStateCombine::Ignore()); | 1754 OutputFrameStateCombine::Ignore()); |
1741 BuildSetHomeObject(value, literal, property->value()); | 1755 ResolvedFeedbackSlot home_slot = ResolveFeedbackSlot( |
1756 expr->SlotForHomeObject(property->value(), &store_slot_index)); | |
1757 BuildSetHomeObject(value, literal, property->value(), home_slot); | |
1742 } else { | 1758 } else { |
1743 VisitForEffect(property->value()); | 1759 VisitForEffect(property->value()); |
1744 } | 1760 } |
1745 break; | 1761 break; |
1746 } | 1762 } |
1747 environment()->Push(literal); // Duplicate receiver. | 1763 environment()->Push(literal); // Duplicate receiver. |
1748 VisitForValue(property->key()); | 1764 VisitForValue(property->key()); |
1749 VisitForValue(property->value()); | 1765 VisitForValue(property->value()); |
1750 Node* value = environment()->Pop(); | 1766 Node* value = environment()->Pop(); |
1751 Node* key = environment()->Pop(); | 1767 Node* key = environment()->Pop(); |
1752 Node* receiver = environment()->Pop(); | 1768 Node* receiver = environment()->Pop(); |
1753 if (property->emit_store()) { | 1769 if (property->emit_store()) { |
1754 Node* language = jsgraph()->Constant(SLOPPY); | 1770 Node* language = jsgraph()->Constant(SLOPPY); |
1755 const Operator* op = | 1771 const Operator* op = |
1756 javascript()->CallRuntime(Runtime::kSetProperty, 4); | 1772 javascript()->CallRuntime(Runtime::kSetProperty, 4); |
1757 Node* set_property = NewNode(op, receiver, key, value, language); | 1773 Node* set_property = NewNode(op, receiver, key, value, language); |
1758 // SetProperty should not lazy deopt on an object literal. | 1774 // SetProperty should not lazy deopt on an object literal. |
1759 PrepareFrameState(set_property, BailoutId::None()); | 1775 PrepareFrameState(set_property, BailoutId::None()); |
1760 BuildSetHomeObject(value, receiver, property->value()); | 1776 ResolvedFeedbackSlot home_slot = ResolveFeedbackSlot( |
1777 expr->SlotForHomeObject(property->value(), &store_slot_index)); | |
1778 BuildSetHomeObject(value, receiver, property->value(), home_slot); | |
1761 } | 1779 } |
1762 break; | 1780 break; |
1763 } | 1781 } |
1764 case ObjectLiteral::Property::PROTOTYPE: { | 1782 case ObjectLiteral::Property::PROTOTYPE: { |
1765 environment()->Push(literal); // Duplicate receiver. | 1783 environment()->Push(literal); // Duplicate receiver. |
1766 VisitForValue(property->value()); | 1784 VisitForValue(property->value()); |
1767 Node* value = environment()->Pop(); | 1785 Node* value = environment()->Pop(); |
1768 Node* receiver = environment()->Pop(); | 1786 Node* receiver = environment()->Pop(); |
1769 DCHECK(property->emit_store()); | 1787 DCHECK(property->emit_store()); |
1770 const Operator* op = | 1788 const Operator* op = |
(...skipping 15 matching lines...) Expand all Loading... | |
1786 break; | 1804 break; |
1787 } | 1805 } |
1788 } | 1806 } |
1789 | 1807 |
1790 // Create nodes to define accessors, using only a single call to the runtime | 1808 // Create nodes to define accessors, using only a single call to the runtime |
1791 // for each pair of corresponding getters and setters. | 1809 // for each pair of corresponding getters and setters. |
1792 for (AccessorTable::Iterator it = accessor_table.begin(); | 1810 for (AccessorTable::Iterator it = accessor_table.begin(); |
1793 it != accessor_table.end(); ++it) { | 1811 it != accessor_table.end(); ++it) { |
1794 VisitForValue(it->first); | 1812 VisitForValue(it->first); |
1795 VisitForValueOrNull(it->second->getter); | 1813 VisitForValueOrNull(it->second->getter); |
1796 BuildSetHomeObject(environment()->Top(), literal, it->second->getter); | 1814 ResolvedFeedbackSlot slot_getter = ResolveFeedbackSlot( |
1815 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); | |
1816 BuildSetHomeObject(environment()->Top(), literal, it->second->getter, | |
1817 slot_getter); | |
1797 VisitForValueOrNull(it->second->setter); | 1818 VisitForValueOrNull(it->second->setter); |
1798 BuildSetHomeObject(environment()->Top(), literal, it->second->setter); | 1819 ResolvedFeedbackSlot slot_setter = ResolveFeedbackSlot( |
1820 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); | |
1821 BuildSetHomeObject(environment()->Top(), literal, it->second->setter, | |
1822 slot_setter); | |
1799 Node* setter = environment()->Pop(); | 1823 Node* setter = environment()->Pop(); |
1800 Node* getter = environment()->Pop(); | 1824 Node* getter = environment()->Pop(); |
1801 Node* name = environment()->Pop(); | 1825 Node* name = environment()->Pop(); |
1802 Node* attr = jsgraph()->Constant(NONE); | 1826 Node* attr = jsgraph()->Constant(NONE); |
1803 const Operator* op = | 1827 const Operator* op = |
1804 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1828 javascript()->CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
1805 Node* call = NewNode(op, literal, name, getter, setter, attr); | 1829 Node* call = NewNode(op, literal, name, getter, setter, attr); |
1806 // This should not lazy deopt on a new literal. | 1830 // This should not lazy deopt on a new literal. |
1807 PrepareFrameState(call, BailoutId::None()); | 1831 PrepareFrameState(call, BailoutId::None()); |
1808 } | 1832 } |
(...skipping 24 matching lines...) Expand all Loading... | |
1833 | 1857 |
1834 environment()->Push(literal); // Duplicate receiver. | 1858 environment()->Push(literal); // Duplicate receiver. |
1835 VisitForValue(property->key()); | 1859 VisitForValue(property->key()); |
1836 Node* name = BuildToName(environment()->Pop(), | 1860 Node* name = BuildToName(environment()->Pop(), |
1837 expr->GetIdForProperty(property_index)); | 1861 expr->GetIdForProperty(property_index)); |
1838 environment()->Push(name); | 1862 environment()->Push(name); |
1839 VisitForValue(property->value()); | 1863 VisitForValue(property->value()); |
1840 Node* value = environment()->Pop(); | 1864 Node* value = environment()->Pop(); |
1841 Node* key = environment()->Pop(); | 1865 Node* key = environment()->Pop(); |
1842 Node* receiver = environment()->Pop(); | 1866 Node* receiver = environment()->Pop(); |
1843 BuildSetHomeObject(value, receiver, property->value()); | 1867 ResolvedFeedbackSlot slot = ResolveFeedbackSlot( |
1844 | 1868 expr->SlotForHomeObject(property->value(), &store_slot_index)); |
1869 BuildSetHomeObject(value, receiver, property->value(), slot); | |
1845 switch (property->kind()) { | 1870 switch (property->kind()) { |
1846 case ObjectLiteral::Property::CONSTANT: | 1871 case ObjectLiteral::Property::CONSTANT: |
1847 case ObjectLiteral::Property::COMPUTED: | 1872 case ObjectLiteral::Property::COMPUTED: |
1848 case ObjectLiteral::Property::MATERIALIZED_LITERAL: { | 1873 case ObjectLiteral::Property::MATERIALIZED_LITERAL: { |
1849 Node* attr = jsgraph()->Constant(NONE); | 1874 Node* attr = jsgraph()->Constant(NONE); |
1850 const Operator* op = | 1875 const Operator* op = |
1851 javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1876 javascript()->CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
1852 Node* call = NewNode(op, receiver, key, value, attr); | 1877 Node* call = NewNode(op, receiver, key, value, attr); |
1853 PrepareFrameState(call, BailoutId::None()); | 1878 PrepareFrameState(call, BailoutId::None()); |
1854 break; | 1879 break; |
(...skipping 20 matching lines...) Expand all Loading... | |
1875 } | 1900 } |
1876 } | 1901 } |
1877 | 1902 |
1878 // Transform literals that contain functions to fast properties. | 1903 // Transform literals that contain functions to fast properties. |
1879 if (expr->has_function()) { | 1904 if (expr->has_function()) { |
1880 const Operator* op = | 1905 const Operator* op = |
1881 javascript()->CallRuntime(Runtime::kToFastProperties, 1); | 1906 javascript()->CallRuntime(Runtime::kToFastProperties, 1); |
1882 NewNode(op, literal); | 1907 NewNode(op, literal); |
1883 } | 1908 } |
1884 | 1909 |
1910 // Verify that compilation exactly consumed the number of store ic slots that | |
1911 // the ObjectLiteral node had to offer. | |
1912 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); | |
1913 | |
1885 ast_context()->ProduceValue(environment()->Pop()); | 1914 ast_context()->ProduceValue(environment()->Pop()); |
1886 } | 1915 } |
1887 | 1916 |
1888 | 1917 |
1889 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { | 1918 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { |
1890 Node* closure = GetFunctionClosure(); | 1919 Node* closure = GetFunctionClosure(); |
1891 | 1920 |
1892 // Create node to deep-copy the literal boilerplate. | 1921 // Create node to deep-copy the literal boilerplate. |
1893 expr->BuildConstantElements(isolate()); | 1922 expr->BuildConstantElements(isolate()); |
1894 Node* literals_array = | 1923 Node* literals_array = |
(...skipping 17 matching lines...) Expand all Loading... | |
1912 for (; array_index < expr->values()->length(); array_index++) { | 1941 for (; array_index < expr->values()->length(); array_index++) { |
1913 Expression* subexpr = expr->values()->at(array_index); | 1942 Expression* subexpr = expr->values()->at(array_index); |
1914 if (subexpr->IsSpread()) break; | 1943 if (subexpr->IsSpread()) break; |
1915 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1944 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
1916 | 1945 |
1917 VisitForValue(subexpr); | 1946 VisitForValue(subexpr); |
1918 { | 1947 { |
1919 FrameStateBeforeAndAfter states(this, subexpr->id()); | 1948 FrameStateBeforeAndAfter states(this, subexpr->id()); |
1920 Node* value = environment()->Pop(); | 1949 Node* value = environment()->Pop(); |
1921 Node* index = jsgraph()->Constant(array_index); | 1950 Node* index = jsgraph()->Constant(array_index); |
1951 // TODO(mvstanton): this should be a runtime call. We can't use an | |
1952 // IC unless we have it in full code as well. | |
Michael Starzinger
2015/06/15 14:20:11
As discussed offline: It's not the responsibility
mvstanton
2015/06/21 13:37:35
Done.
| |
1922 Node* store = | 1953 Node* store = |
1923 BuildKeyedStore(literal, index, value, TypeFeedbackId::None()); | 1954 BuildKeyedStore(literal, index, value, ResolvedFeedbackSlot(), |
1955 TypeFeedbackId::None()); | |
1924 states.AddToNode(store, expr->GetIdForElement(array_index), | 1956 states.AddToNode(store, expr->GetIdForElement(array_index), |
1925 OutputFrameStateCombine::Ignore()); | 1957 OutputFrameStateCombine::Ignore()); |
1926 } | 1958 } |
1927 } | 1959 } |
1928 | 1960 |
1929 // In case the array literal contains spread expressions it has two parts. The | 1961 // In case the array literal contains spread expressions it has two parts. The |
1930 // first part is the "static" array which has a literal index is handled | 1962 // first part is the "static" array which has a literal index is handled |
1931 // above. The second part is the part after the first spread expression | 1963 // above. The second part is the part after the first spread expression |
1932 // (inclusive) and these elements gets appended to the array. Note that the | 1964 // (inclusive) and these elements gets appended to the array. Note that the |
1933 // number elements an iterable produces is unknown ahead of time. | 1965 // number elements an iterable produces is unknown ahead of time. |
(...skipping 23 matching lines...) Expand all Loading... | |
1957 | 1989 |
1958 PrepareFrameState(result, expr->GetIdForElement(array_index)); | 1990 PrepareFrameState(result, expr->GetIdForElement(array_index)); |
1959 environment()->Push(result); | 1991 environment()->Push(result); |
1960 } | 1992 } |
1961 | 1993 |
1962 ast_context()->ProduceValue(environment()->Pop()); | 1994 ast_context()->ProduceValue(environment()->Pop()); |
1963 } | 1995 } |
1964 | 1996 |
1965 | 1997 |
1966 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, | 1998 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, |
1999 const ResolvedFeedbackSlot& slot, | |
1967 BailoutId bailout_id) { | 2000 BailoutId bailout_id) { |
1968 DCHECK(expr->IsValidReferenceExpression()); | 2001 DCHECK(expr->IsValidReferenceExpression()); |
1969 | 2002 |
1970 // Left-hand side can only be a property, a global or a variable slot. | 2003 // Left-hand side can only be a property, a global or a variable slot. |
1971 Property* property = expr->AsProperty(); | 2004 Property* property = expr->AsProperty(); |
1972 LhsKind assign_type = Property::GetAssignType(property); | 2005 LhsKind assign_type = Property::GetAssignType(property); |
1973 | 2006 |
1974 // Evaluate LHS expression and store the value. | 2007 // Evaluate LHS expression and store the value. |
1975 switch (assign_type) { | 2008 switch (assign_type) { |
1976 case VARIABLE: { | 2009 case VARIABLE: { |
1977 Variable* var = expr->AsVariableProxy()->var(); | 2010 Variable* var = expr->AsVariableProxy()->var(); |
1978 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 2011 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
1979 BuildVariableAssignment(var, value, Token::ASSIGN, bailout_id, states); | 2012 BuildVariableAssignment(var, value, Token::ASSIGN, slot, bailout_id, |
2013 states); | |
1980 break; | 2014 break; |
1981 } | 2015 } |
1982 case NAMED_PROPERTY: { | 2016 case NAMED_PROPERTY: { |
1983 environment()->Push(value); | 2017 environment()->Push(value); |
1984 VisitForValue(property->obj()); | 2018 VisitForValue(property->obj()); |
1985 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2019 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
1986 Node* object = environment()->Pop(); | 2020 Node* object = environment()->Pop(); |
1987 value = environment()->Pop(); | 2021 value = environment()->Pop(); |
1988 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2022 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
1989 Node* store = | 2023 Node* store = |
1990 BuildNamedStore(object, name, value, TypeFeedbackId::None()); | 2024 BuildNamedStore(object, name, value, slot, TypeFeedbackId::None()); |
1991 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2025 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); |
1992 break; | 2026 break; |
1993 } | 2027 } |
1994 case KEYED_PROPERTY: { | 2028 case KEYED_PROPERTY: { |
1995 environment()->Push(value); | 2029 environment()->Push(value); |
1996 VisitForValue(property->obj()); | 2030 VisitForValue(property->obj()); |
1997 VisitForValue(property->key()); | 2031 VisitForValue(property->key()); |
1998 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2032 FrameStateBeforeAndAfter states(this, property->key()->id()); |
1999 Node* key = environment()->Pop(); | 2033 Node* key = environment()->Pop(); |
2000 Node* object = environment()->Pop(); | 2034 Node* object = environment()->Pop(); |
2001 value = environment()->Pop(); | 2035 value = environment()->Pop(); |
2002 Node* store = BuildKeyedStore(object, key, value, TypeFeedbackId::None()); | 2036 Node* store = |
2037 BuildKeyedStore(object, key, value, slot, TypeFeedbackId::None()); | |
2003 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2038 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); |
2004 break; | 2039 break; |
2005 } | 2040 } |
2006 case NAMED_SUPER_PROPERTY: { | 2041 case NAMED_SUPER_PROPERTY: { |
2007 environment()->Push(value); | 2042 environment()->Push(value); |
2008 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2043 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2009 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2044 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
2010 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2045 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2011 Node* home_object = environment()->Pop(); | 2046 Node* home_object = environment()->Pop(); |
2012 Node* receiver = environment()->Pop(); | 2047 Node* receiver = environment()->Pop(); |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2154 } else { | 2189 } else { |
2155 VisitForValue(expr->value()); | 2190 VisitForValue(expr->value()); |
2156 if (needs_frame_state_before) { | 2191 if (needs_frame_state_before) { |
2157 before_store_id = expr->value()->id(); | 2192 before_store_id = expr->value()->id(); |
2158 } | 2193 } |
2159 } | 2194 } |
2160 | 2195 |
2161 FrameStateBeforeAndAfter store_states(this, before_store_id); | 2196 FrameStateBeforeAndAfter store_states(this, before_store_id); |
2162 // Store the value. | 2197 // Store the value. |
2163 Node* value = environment()->Pop(); | 2198 Node* value = environment()->Pop(); |
2199 ResolvedFeedbackSlot slot = ResolveFeedbackSlot(expr->AssignmentSlot()); | |
2164 switch (assign_type) { | 2200 switch (assign_type) { |
2165 case VARIABLE: { | 2201 case VARIABLE: { |
2166 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2202 Variable* variable = expr->target()->AsVariableProxy()->var(); |
2167 BuildVariableAssignment(variable, value, expr->op(), expr->id(), | 2203 BuildVariableAssignment(variable, value, expr->op(), slot, expr->id(), |
2168 store_states, ast_context()->GetStateCombine()); | 2204 store_states, ast_context()->GetStateCombine()); |
2169 break; | 2205 break; |
2170 } | 2206 } |
2171 case NAMED_PROPERTY: { | 2207 case NAMED_PROPERTY: { |
2172 Node* object = environment()->Pop(); | 2208 Node* object = environment()->Pop(); |
2173 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2209 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2174 Node* store = | 2210 Node* store = BuildNamedStore(object, name, value, slot, |
2175 BuildNamedStore(object, name, value, expr->AssignmentFeedbackId()); | 2211 expr->AssignmentFeedbackId()); |
2176 store_states.AddToNode(store, expr->id(), | 2212 store_states.AddToNode(store, expr->id(), |
2177 ast_context()->GetStateCombine()); | 2213 ast_context()->GetStateCombine()); |
2178 break; | 2214 break; |
2179 } | 2215 } |
2180 case KEYED_PROPERTY: { | 2216 case KEYED_PROPERTY: { |
2181 Node* key = environment()->Pop(); | 2217 Node* key = environment()->Pop(); |
2182 Node* object = environment()->Pop(); | 2218 Node* object = environment()->Pop(); |
2183 Node* store = | 2219 Node* store = BuildKeyedStore(object, key, value, slot, |
2184 BuildKeyedStore(object, key, value, expr->AssignmentFeedbackId()); | 2220 expr->AssignmentFeedbackId()); |
2185 store_states.AddToNode(store, expr->id(), | 2221 store_states.AddToNode(store, expr->id(), |
2186 ast_context()->GetStateCombine()); | 2222 ast_context()->GetStateCombine()); |
2187 break; | 2223 break; |
2188 } | 2224 } |
2189 case NAMED_SUPER_PROPERTY: { | 2225 case NAMED_SUPER_PROPERTY: { |
2190 Node* home_object = environment()->Pop(); | 2226 Node* home_object = environment()->Pop(); |
2191 Node* receiver = environment()->Pop(); | 2227 Node* receiver = environment()->Pop(); |
2192 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2228 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2193 Node* store = BuildNamedSuperStore(receiver, home_object, name, value, | 2229 Node* store = BuildNamedSuperStore(receiver, home_object, name, value, |
2194 expr->AssignmentFeedbackId()); | 2230 expr->AssignmentFeedbackId()); |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2642 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 2678 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
2643 value = | 2679 value = |
2644 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); | 2680 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); |
2645 // This should never deoptimize because we have converted to number | 2681 // This should never deoptimize because we have converted to number |
2646 // before. | 2682 // before. |
2647 states.AddToNode(value, BailoutId::None(), | 2683 states.AddToNode(value, BailoutId::None(), |
2648 OutputFrameStateCombine::Ignore()); | 2684 OutputFrameStateCombine::Ignore()); |
2649 } | 2685 } |
2650 | 2686 |
2651 // Store the value. | 2687 // Store the value. |
2688 ResolvedFeedbackSlot slot = ResolveFeedbackSlot(expr->CountSlot()); | |
2652 switch (assign_type) { | 2689 switch (assign_type) { |
2653 case VARIABLE: { | 2690 case VARIABLE: { |
2654 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2691 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
2655 environment()->Push(value); | 2692 environment()->Push(value); |
2656 BuildVariableAssignment(variable, value, expr->op(), expr->AssignmentId(), | 2693 BuildVariableAssignment(variable, value, expr->op(), slot, |
2657 store_states); | 2694 expr->AssignmentId(), store_states); |
2658 environment()->Pop(); | 2695 environment()->Pop(); |
2659 break; | 2696 break; |
2660 } | 2697 } |
2661 case NAMED_PROPERTY: { | 2698 case NAMED_PROPERTY: { |
2662 Node* object = environment()->Pop(); | 2699 Node* object = environment()->Pop(); |
2663 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2700 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2664 Node* store = | 2701 Node* store = BuildNamedStore(object, name, value, slot, |
2665 BuildNamedStore(object, name, value, expr->CountStoreFeedbackId()); | 2702 expr->CountStoreFeedbackId()); |
2666 environment()->Push(value); | 2703 environment()->Push(value); |
2667 store_states.AddToNode(store, expr->AssignmentId(), | 2704 store_states.AddToNode(store, expr->AssignmentId(), |
2668 OutputFrameStateCombine::Ignore()); | 2705 OutputFrameStateCombine::Ignore()); |
2669 environment()->Pop(); | 2706 environment()->Pop(); |
2670 break; | 2707 break; |
2671 } | 2708 } |
2672 case KEYED_PROPERTY: { | 2709 case KEYED_PROPERTY: { |
2673 Node* key = environment()->Pop(); | 2710 Node* key = environment()->Pop(); |
2674 Node* object = environment()->Pop(); | 2711 Node* object = environment()->Pop(); |
2675 Node* store = | 2712 Node* store = BuildKeyedStore(object, key, value, slot, |
2676 BuildKeyedStore(object, key, value, expr->CountStoreFeedbackId()); | 2713 expr->CountStoreFeedbackId()); |
2677 environment()->Push(value); | 2714 environment()->Push(value); |
2678 store_states.AddToNode(store, expr->AssignmentId(), | 2715 store_states.AddToNode(store, expr->AssignmentId(), |
2679 OutputFrameStateCombine::Ignore()); | 2716 OutputFrameStateCombine::Ignore()); |
2680 environment()->Pop(); | 2717 environment()->Pop(); |
2681 break; | 2718 break; |
2682 } | 2719 } |
2683 case NAMED_SUPER_PROPERTY: { | 2720 case NAMED_SUPER_PROPERTY: { |
2684 Node* home_object = environment()->Pop(); | 2721 Node* home_object = environment()->Pop(); |
2685 Node* receiver = environment()->Pop(); | 2722 Node* receiver = environment()->Pop(); |
2686 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2723 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3098 | 3135 |
3099 // Allocate and initialize a new arguments object. | 3136 // Allocate and initialize a new arguments object. |
3100 Node* callee = GetFunctionClosure(); | 3137 Node* callee = GetFunctionClosure(); |
3101 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1); | 3138 const Operator* op = javascript()->CallRuntime(Runtime::kNewArguments, 1); |
3102 Node* object = NewNode(op, callee); | 3139 Node* object = NewNode(op, callee); |
3103 | 3140 |
3104 // Assign the object to the arguments variable. | 3141 // Assign the object to the arguments variable. |
3105 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); | 3142 DCHECK(arguments->IsContextSlot() || arguments->IsStackAllocated()); |
3106 // This should never lazy deopt, so it is fine to send invalid bailout id. | 3143 // This should never lazy deopt, so it is fine to send invalid bailout id. |
3107 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 3144 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
3108 BuildVariableAssignment(arguments, object, Token::ASSIGN, BailoutId::None(), | 3145 ResolvedFeedbackSlot slot; |
3109 states); | 3146 BuildVariableAssignment(arguments, object, Token::ASSIGN, slot, |
3147 BailoutId::None(), states); | |
3110 | 3148 |
3111 return object; | 3149 return object; |
3112 } | 3150 } |
3113 | 3151 |
3114 | 3152 |
3115 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { | 3153 Node* AstGraphBuilder::BuildRestArgumentsArray(Variable* rest, int index) { |
3116 if (rest == NULL) return NULL; | 3154 if (rest == NULL) return NULL; |
3117 | 3155 |
3118 DCHECK(index >= 0); | 3156 DCHECK(index >= 0); |
3119 const Operator* op = javascript()->CallRuntime(Runtime::kNewRestParamSlow, 2); | 3157 const Operator* op = javascript()->CallRuntime(Runtime::kNewRestParamSlow, 2); |
3120 Node* object = NewNode(op, jsgraph()->SmiConstant(index), | 3158 Node* object = NewNode(op, jsgraph()->SmiConstant(index), |
3121 jsgraph()->SmiConstant(language_mode())); | 3159 jsgraph()->SmiConstant(language_mode())); |
3122 | 3160 |
3123 // Assign the object to the rest array | 3161 // Assign the object to the rest array |
3124 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | 3162 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); |
3125 // This should never lazy deopt, so it is fine to send invalid bailout id. | 3163 // This should never lazy deopt, so it is fine to send invalid bailout id. |
3126 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 3164 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
3127 BuildVariableAssignment(rest, object, Token::ASSIGN, BailoutId::None(), | 3165 ResolvedFeedbackSlot slot; |
3166 BuildVariableAssignment(rest, object, Token::ASSIGN, slot, BailoutId::None(), | |
3128 states); | 3167 states); |
3129 | 3168 |
3130 return object; | 3169 return object; |
3131 } | 3170 } |
3132 | 3171 |
3133 | 3172 |
3134 Node* AstGraphBuilder::BuildThisFunctionVar(Variable* this_function_var) { | 3173 Node* AstGraphBuilder::BuildThisFunctionVar(Variable* this_function_var) { |
3135 if (this_function_var == nullptr) return nullptr; | 3174 if (this_function_var == nullptr) return nullptr; |
3136 | 3175 |
3137 Node* this_function = GetFunctionClosure(); | 3176 Node* this_function = GetFunctionClosure(); |
3138 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 3177 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
3178 ResolvedFeedbackSlot slot; | |
3139 BuildVariableAssignment(this_function_var, this_function, Token::INIT_CONST, | 3179 BuildVariableAssignment(this_function_var, this_function, Token::INIT_CONST, |
3140 BailoutId::None(), states); | 3180 slot, BailoutId::None(), states); |
3141 return this_function; | 3181 return this_function; |
3142 } | 3182 } |
3143 | 3183 |
3144 | 3184 |
3145 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, | 3185 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, |
3146 Node* not_hole) { | 3186 Node* not_hole) { |
3147 Node* the_hole = jsgraph()->TheHoleConstant(); | 3187 Node* the_hole = jsgraph()->TheHoleConstant(); |
3148 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 3188 Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); |
3149 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, | 3189 return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, |
3150 for_hole, not_hole); | 3190 for_hole, not_hole); |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3314 PrepareFrameState(result, bailout_id, combine); | 3354 PrepareFrameState(result, bailout_id, combine); |
3315 return result; | 3355 return result; |
3316 } | 3356 } |
3317 } | 3357 } |
3318 UNREACHABLE(); | 3358 UNREACHABLE(); |
3319 return NULL; | 3359 return NULL; |
3320 } | 3360 } |
3321 | 3361 |
3322 | 3362 |
3323 Node* AstGraphBuilder::BuildVariableAssignment( | 3363 Node* AstGraphBuilder::BuildVariableAssignment( |
3324 Variable* variable, Node* value, Token::Value op, BailoutId bailout_id, | 3364 Variable* variable, Node* value, Token::Value op, |
3365 const ResolvedFeedbackSlot& slot, BailoutId bailout_id, | |
3325 FrameStateBeforeAndAfter& states, OutputFrameStateCombine combine) { | 3366 FrameStateBeforeAndAfter& states, OutputFrameStateCombine combine) { |
3326 Node* the_hole = jsgraph()->TheHoleConstant(); | 3367 Node* the_hole = jsgraph()->TheHoleConstant(); |
3327 VariableMode mode = variable->mode(); | 3368 VariableMode mode = variable->mode(); |
3328 switch (variable->location()) { | 3369 switch (variable->location()) { |
3329 case Variable::UNALLOCATED: { | 3370 case Variable::UNALLOCATED: { |
3330 // Global var, const, or let variable. | 3371 // Global var, const, or let variable. |
3331 Node* global = BuildLoadGlobalObject(); | 3372 Node* global = BuildLoadGlobalObject(); |
3332 Handle<Name> name = variable->name(); | 3373 Handle<Name> name = variable->name(); |
3333 Node* store = | 3374 Node* store = |
3334 BuildNamedStore(global, name, value, TypeFeedbackId::None()); | 3375 BuildNamedStore(global, name, value, slot, TypeFeedbackId::None()); |
3335 states.AddToNode(store, bailout_id, combine); | 3376 states.AddToNode(store, bailout_id, combine); |
3336 return store; | 3377 return store; |
3337 } | 3378 } |
3338 case Variable::PARAMETER: | 3379 case Variable::PARAMETER: |
3339 case Variable::LOCAL: | 3380 case Variable::LOCAL: |
3340 // Local var, const, or let variable. | 3381 // Local var, const, or let variable. |
3341 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 3382 if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { |
3342 // Perform an initialization check for legacy const variables. | 3383 // Perform an initialization check for legacy const variables. |
3343 Node* current = environment()->Lookup(variable); | 3384 Node* current = environment()->Lookup(variable); |
3344 if (current->op() != the_hole->op()) { | 3385 if (current->op() != the_hole->op()) { |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3457 const ResolvedFeedbackSlot& feedback, | 3498 const ResolvedFeedbackSlot& feedback, |
3458 ContextualMode mode) { | 3499 ContextualMode mode) { |
3459 const Operator* op = | 3500 const Operator* op = |
3460 javascript()->LoadNamed(MakeUnique(name), feedback, mode); | 3501 javascript()->LoadNamed(MakeUnique(name), feedback, mode); |
3461 return Record(js_type_feedback_, NewNode(op, object, GetFeedbackVector()), | 3502 return Record(js_type_feedback_, NewNode(op, object, GetFeedbackVector()), |
3462 feedback.slot()); | 3503 feedback.slot()); |
3463 } | 3504 } |
3464 | 3505 |
3465 | 3506 |
3466 Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value, | 3507 Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value, |
3508 const ResolvedFeedbackSlot& feedback, | |
3467 TypeFeedbackId id) { | 3509 TypeFeedbackId id) { |
3468 const Operator* op = javascript()->StoreProperty(language_mode()); | 3510 const Operator* op = javascript()->StoreProperty(language_mode(), feedback); |
3469 return Record(js_type_feedback_, NewNode(op, object, key, value), id); | 3511 return Record(js_type_feedback_, NewNode(op, object, key, value), id); |
3470 } | 3512 } |
3471 | 3513 |
3472 | 3514 |
3473 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name, | 3515 Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name, |
3474 Node* value, TypeFeedbackId id) { | 3516 Node* value, |
3517 const ResolvedFeedbackSlot& feedback, | |
3518 TypeFeedbackId id) { | |
3475 const Operator* op = | 3519 const Operator* op = |
3476 javascript()->StoreNamed(language_mode(), MakeUnique(name)); | 3520 javascript()->StoreNamed(language_mode(), feedback, MakeUnique(name)); |
3477 return Record(js_type_feedback_, NewNode(op, object, value), id); | 3521 return Record(js_type_feedback_, NewNode(op, object, value), id); |
3478 } | 3522 } |
3479 | 3523 |
3480 | 3524 |
3481 Node* AstGraphBuilder::BuildNamedSuperLoad( | 3525 Node* AstGraphBuilder::BuildNamedSuperLoad( |
3482 Node* receiver, Node* home_object, Handle<Name> name, | 3526 Node* receiver, Node* home_object, Handle<Name> name, |
3483 const ResolvedFeedbackSlot& feedback) { | 3527 const ResolvedFeedbackSlot& feedback) { |
3484 Node* name_node = jsgraph()->Constant(name); | 3528 Node* name_node = jsgraph()->Constant(name); |
3485 const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3); | 3529 const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3); |
3486 Node* value = NewNode(op, receiver, home_object, name_node); | 3530 Node* value = NewNode(op, receiver, home_object, name_node); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3605 | 3649 |
3606 | 3650 |
3607 Node* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) { | 3651 Node* AstGraphBuilder::BuildToObject(Node* input, BailoutId bailout_id) { |
3608 Node* object = NewNode(javascript()->ToObject(), input); | 3652 Node* object = NewNode(javascript()->ToObject(), input); |
3609 PrepareFrameState(object, bailout_id, OutputFrameStateCombine::Push()); | 3653 PrepareFrameState(object, bailout_id, OutputFrameStateCombine::Push()); |
3610 return object; | 3654 return object; |
3611 } | 3655 } |
3612 | 3656 |
3613 | 3657 |
3614 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object, | 3658 Node* AstGraphBuilder::BuildSetHomeObject(Node* value, Node* home_object, |
3615 Expression* expr) { | 3659 Expression* expr, |
3660 const ResolvedFeedbackSlot& slot) { | |
3616 if (!FunctionLiteral::NeedsHomeObject(expr)) return value; | 3661 if (!FunctionLiteral::NeedsHomeObject(expr)) return value; |
3617 Handle<Name> name = isolate()->factory()->home_object_symbol(); | 3662 Handle<Name> name = isolate()->factory()->home_object_symbol(); |
3618 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 3663 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
3619 Node* store = | 3664 Node* store = |
3620 BuildNamedStore(value, name, home_object, TypeFeedbackId::None()); | 3665 BuildNamedStore(value, name, home_object, slot, TypeFeedbackId::None()); |
3621 states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore()); | 3666 states.AddToNode(store, BailoutId::None(), OutputFrameStateCombine::Ignore()); |
3622 return store; | 3667 return store; |
3623 } | 3668 } |
3624 | 3669 |
3625 | 3670 |
3626 Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) { | 3671 Node* AstGraphBuilder::BuildThrowError(Node* exception, BailoutId bailout_id) { |
3627 const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1); | 3672 const Operator* op = javascript()->CallRuntime(Runtime::kThrow, 1); |
3628 Node* call = NewNode(op, exception); | 3673 Node* call = NewNode(op, exception); |
3629 PrepareFrameState(call, bailout_id); | 3674 PrepareFrameState(call, bailout_id); |
3630 Node* control = NewNode(common()->Throw(), call); | 3675 Node* control = NewNode(common()->Throw(), call); |
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4057 // Phi does not exist yet, introduce one. | 4102 // Phi does not exist yet, introduce one. |
4058 value = NewPhi(inputs, value, control); | 4103 value = NewPhi(inputs, value, control); |
4059 value->ReplaceInput(inputs - 1, other); | 4104 value->ReplaceInput(inputs - 1, other); |
4060 } | 4105 } |
4061 return value; | 4106 return value; |
4062 } | 4107 } |
4063 | 4108 |
4064 } // namespace compiler | 4109 } // namespace compiler |
4065 } // namespace internal | 4110 } // namespace internal |
4066 } // namespace v8 | 4111 } // namespace v8 |
OLD | NEW |