| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1241 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); | 1241 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); |
| 1242 __ Mov(x3, x0); | 1242 __ Mov(x3, x0); |
| 1243 __ Cbz(x0, loop_statement.continue_label()); | 1243 __ Cbz(x0, loop_statement.continue_label()); |
| 1244 | 1244 |
| 1245 // Update the 'each' property or variable from the possibly filtered | 1245 // Update the 'each' property or variable from the possibly filtered |
| 1246 // entry in register x3. | 1246 // entry in register x3. |
| 1247 __ Bind(&update_each); | 1247 __ Bind(&update_each); |
| 1248 __ Mov(result_register(), x3); | 1248 __ Mov(result_register(), x3); |
| 1249 // Perform the assignment as if via '='. | 1249 // Perform the assignment as if via '='. |
| 1250 { EffectContext context(this); | 1250 { EffectContext context(this); |
| 1251 EmitAssignment(stmt->each()); | 1251 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
| 1252 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); | 1252 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); |
| 1253 } | 1253 } |
| 1254 | 1254 |
| 1255 // Generate code for the body of the loop. | 1255 // Generate code for the body of the loop. |
| 1256 Visit(stmt->body()); | 1256 Visit(stmt->body()); |
| 1257 | 1257 |
| 1258 // Generate code for going to the next element by incrementing | 1258 // Generate code for going to the next element by incrementing |
| 1259 // the index (smi) stored on top of the stack. | 1259 // the index (smi) stored on top of the stack. |
| 1260 __ Bind(loop_statement.continue_label()); | 1260 __ Bind(loop_statement.continue_label()); |
| 1261 // TODO(all): We could use a callee saved register to avoid popping. | 1261 // TODO(all): We could use a callee saved register to avoid popping. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1326 __ Mov(x10, Operand(isolate()->factory()->undefined_value())); | 1326 __ Mov(x10, Operand(isolate()->factory()->undefined_value())); |
| 1327 __ cmp(x0, x10); | 1327 __ cmp(x0, x10); |
| 1328 Label done; | 1328 Label done; |
| 1329 __ b(&done, ne); | 1329 __ b(&done, ne); |
| 1330 __ CallRuntime(Runtime::kThrowNonMethodError, 0); | 1330 __ CallRuntime(Runtime::kThrowNonMethodError, 0); |
| 1331 __ bind(&done); | 1331 __ bind(&done); |
| 1332 } | 1332 } |
| 1333 | 1333 |
| 1334 | 1334 |
| 1335 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1335 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1336 int offset) { | 1336 int offset, |
| 1337 FeedbackVectorICSlot slot) { |
| 1337 if (NeedsHomeObject(initializer)) { | 1338 if (NeedsHomeObject(initializer)) { |
| 1338 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1339 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
| 1339 __ Mov(StoreDescriptor::NameRegister(), | 1340 __ Mov(StoreDescriptor::NameRegister(), |
| 1340 Operand(isolate()->factory()->home_object_symbol())); | 1341 Operand(isolate()->factory()->home_object_symbol())); |
| 1341 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); | 1342 __ Peek(StoreDescriptor::ValueRegister(), offset * kPointerSize); |
| 1343 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1342 CallStoreIC(); | 1344 CallStoreIC(); |
| 1343 } | 1345 } |
| 1344 } | 1346 } |
| 1345 | 1347 |
| 1346 | 1348 |
| 1347 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1349 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1348 TypeofState typeof_state, | 1350 TypeofState typeof_state, |
| 1349 Label* slow) { | 1351 Label* slow) { |
| 1350 Register current = cp; | 1352 Register current = cp; |
| 1351 Register next = x10; | 1353 Register next = x10; |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1647 __ CallStub(&stub); | 1649 __ CallStub(&stub); |
| 1648 } | 1650 } |
| 1649 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1651 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1650 | 1652 |
| 1651 // If result_saved is true the result is on top of the stack. If | 1653 // If result_saved is true the result is on top of the stack. If |
| 1652 // result_saved is false the result is in x0. | 1654 // result_saved is false the result is in x0. |
| 1653 bool result_saved = false; | 1655 bool result_saved = false; |
| 1654 | 1656 |
| 1655 AccessorTable accessor_table(zone()); | 1657 AccessorTable accessor_table(zone()); |
| 1656 int property_index = 0; | 1658 int property_index = 0; |
| 1659 // store_slot_index points to the vector ic slot for the next store ic used. |
| 1660 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots |
| 1661 // and must be updated if the number of store ics emitted here changes. |
| 1662 int store_slot_index = 0; |
| 1657 for (; property_index < expr->properties()->length(); property_index++) { | 1663 for (; property_index < expr->properties()->length(); property_index++) { |
| 1658 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1664 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1659 if (property->is_computed_name()) break; | 1665 if (property->is_computed_name()) break; |
| 1660 if (property->IsCompileTimeValue()) continue; | 1666 if (property->IsCompileTimeValue()) continue; |
| 1661 | 1667 |
| 1662 Literal* key = property->key()->AsLiteral(); | 1668 Literal* key = property->key()->AsLiteral(); |
| 1663 Expression* value = property->value(); | 1669 Expression* value = property->value(); |
| 1664 if (!result_saved) { | 1670 if (!result_saved) { |
| 1665 __ Push(x0); // Save result on stack | 1671 __ Push(x0); // Save result on stack |
| 1666 result_saved = true; | 1672 result_saved = true; |
| 1667 } | 1673 } |
| 1668 switch (property->kind()) { | 1674 switch (property->kind()) { |
| 1669 case ObjectLiteral::Property::CONSTANT: | 1675 case ObjectLiteral::Property::CONSTANT: |
| 1670 UNREACHABLE(); | 1676 UNREACHABLE(); |
| 1671 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1677 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1672 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1678 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1673 // Fall through. | 1679 // Fall through. |
| 1674 case ObjectLiteral::Property::COMPUTED: | 1680 case ObjectLiteral::Property::COMPUTED: |
| 1675 // It is safe to use [[Put]] here because the boilerplate already | 1681 // It is safe to use [[Put]] here because the boilerplate already |
| 1676 // contains computed properties with an uninitialized value. | 1682 // contains computed properties with an uninitialized value. |
| 1677 if (key->value()->IsInternalizedString()) { | 1683 if (key->value()->IsInternalizedString()) { |
| 1678 if (property->emit_store()) { | 1684 if (property->emit_store()) { |
| 1679 VisitForAccumulatorValue(value); | 1685 VisitForAccumulatorValue(value); |
| 1680 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 1686 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
| 1681 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value())); | 1687 __ Mov(StoreDescriptor::NameRegister(), Operand(key->value())); |
| 1682 __ Peek(StoreDescriptor::ReceiverRegister(), 0); | 1688 __ Peek(StoreDescriptor::ReceiverRegister(), 0); |
| 1683 CallStoreIC(key->LiteralFeedbackId()); | 1689 if (FLAG_vector_stores) { |
| 1690 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1691 CallStoreIC(); |
| 1692 } else { |
| 1693 CallStoreIC(key->LiteralFeedbackId()); |
| 1694 } |
| 1684 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1695 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1685 | 1696 |
| 1686 if (NeedsHomeObject(value)) { | 1697 if (NeedsHomeObject(value)) { |
| 1687 __ Mov(StoreDescriptor::ReceiverRegister(), x0); | 1698 __ Mov(StoreDescriptor::ReceiverRegister(), x0); |
| 1688 __ Mov(StoreDescriptor::NameRegister(), | 1699 __ Mov(StoreDescriptor::NameRegister(), |
| 1689 Operand(isolate()->factory()->home_object_symbol())); | 1700 Operand(isolate()->factory()->home_object_symbol())); |
| 1690 __ Peek(StoreDescriptor::ValueRegister(), 0); | 1701 __ Peek(StoreDescriptor::ValueRegister(), 0); |
| 1702 if (FLAG_vector_stores) { |
| 1703 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1704 } |
| 1691 CallStoreIC(); | 1705 CallStoreIC(); |
| 1692 } | 1706 } |
| 1693 } else { | 1707 } else { |
| 1694 VisitForEffect(value); | 1708 VisitForEffect(value); |
| 1695 } | 1709 } |
| 1696 break; | 1710 break; |
| 1697 } | 1711 } |
| 1698 __ Peek(x0, 0); | 1712 __ Peek(x0, 0); |
| 1699 __ Push(x0); | 1713 __ Push(x0); |
| 1700 VisitForStackValue(key); | 1714 VisitForStackValue(key); |
| 1701 VisitForStackValue(value); | 1715 VisitForStackValue(value); |
| 1702 if (property->emit_store()) { | 1716 if (property->emit_store()) { |
| 1703 EmitSetHomeObjectIfNeeded(value, 2); | 1717 EmitSetHomeObjectIfNeeded( |
| 1718 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1704 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode | 1719 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode |
| 1705 __ Push(x0); | 1720 __ Push(x0); |
| 1706 __ CallRuntime(Runtime::kSetProperty, 4); | 1721 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1707 } else { | 1722 } else { |
| 1708 __ Drop(3); | 1723 __ Drop(3); |
| 1709 } | 1724 } |
| 1710 break; | 1725 break; |
| 1711 case ObjectLiteral::Property::PROTOTYPE: | 1726 case ObjectLiteral::Property::PROTOTYPE: |
| 1712 DCHECK(property->emit_store()); | 1727 DCHECK(property->emit_store()); |
| 1713 // Duplicate receiver on stack. | 1728 // Duplicate receiver on stack. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1731 | 1746 |
| 1732 // Emit code to define accessors, using only a single call to the runtime for | 1747 // Emit code to define accessors, using only a single call to the runtime for |
| 1733 // each pair of corresponding getters and setters. | 1748 // each pair of corresponding getters and setters. |
| 1734 for (AccessorTable::Iterator it = accessor_table.begin(); | 1749 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1735 it != accessor_table.end(); | 1750 it != accessor_table.end(); |
| 1736 ++it) { | 1751 ++it) { |
| 1737 __ Peek(x10, 0); // Duplicate receiver. | 1752 __ Peek(x10, 0); // Duplicate receiver. |
| 1738 __ Push(x10); | 1753 __ Push(x10); |
| 1739 VisitForStackValue(it->first); | 1754 VisitForStackValue(it->first); |
| 1740 EmitAccessor(it->second->getter); | 1755 EmitAccessor(it->second->getter); |
| 1741 EmitSetHomeObjectIfNeeded(it->second->getter, 2); | 1756 EmitSetHomeObjectIfNeeded( |
| 1757 it->second->getter, 2, |
| 1758 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); |
| 1742 EmitAccessor(it->second->setter); | 1759 EmitAccessor(it->second->setter); |
| 1743 EmitSetHomeObjectIfNeeded(it->second->setter, 3); | 1760 EmitSetHomeObjectIfNeeded( |
| 1761 it->second->setter, 3, |
| 1762 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); |
| 1744 __ Mov(x10, Smi::FromInt(NONE)); | 1763 __ Mov(x10, Smi::FromInt(NONE)); |
| 1745 __ Push(x10); | 1764 __ Push(x10); |
| 1746 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1765 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1747 } | 1766 } |
| 1748 | 1767 |
| 1749 // Object literals have two parts. The "static" part on the left contains no | 1768 // Object literals have two parts. The "static" part on the left contains no |
| 1750 // computed property names, and so we can compute its map ahead of time; see | 1769 // computed property names, and so we can compute its map ahead of time; see |
| 1751 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1770 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1752 // starts with the first computed property name, and continues with all | 1771 // starts with the first computed property name, and continues with all |
| 1753 // properties to its right. All the code from above initializes the static | 1772 // properties to its right. All the code from above initializes the static |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1768 __ Push(x10); | 1787 __ Push(x10); |
| 1769 | 1788 |
| 1770 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1789 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1771 DCHECK(!property->is_computed_name()); | 1790 DCHECK(!property->is_computed_name()); |
| 1772 VisitForStackValue(value); | 1791 VisitForStackValue(value); |
| 1773 DCHECK(property->emit_store()); | 1792 DCHECK(property->emit_store()); |
| 1774 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1793 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1775 } else { | 1794 } else { |
| 1776 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1795 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1777 VisitForStackValue(value); | 1796 VisitForStackValue(value); |
| 1778 EmitSetHomeObjectIfNeeded(value, 2); | 1797 EmitSetHomeObjectIfNeeded( |
| 1798 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1779 | 1799 |
| 1780 switch (property->kind()) { | 1800 switch (property->kind()) { |
| 1781 case ObjectLiteral::Property::CONSTANT: | 1801 case ObjectLiteral::Property::CONSTANT: |
| 1782 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1802 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1783 case ObjectLiteral::Property::COMPUTED: | 1803 case ObjectLiteral::Property::COMPUTED: |
| 1784 if (property->emit_store()) { | 1804 if (property->emit_store()) { |
| 1785 __ Mov(x0, Smi::FromInt(NONE)); | 1805 __ Mov(x0, Smi::FromInt(NONE)); |
| 1786 __ Push(x0); | 1806 __ Push(x0); |
| 1787 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1807 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1788 } else { | 1808 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1814 __ Peek(x0, 0); | 1834 __ Peek(x0, 0); |
| 1815 __ Push(x0); | 1835 __ Push(x0); |
| 1816 __ CallRuntime(Runtime::kToFastProperties, 1); | 1836 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1817 } | 1837 } |
| 1818 | 1838 |
| 1819 if (result_saved) { | 1839 if (result_saved) { |
| 1820 context()->PlugTOS(); | 1840 context()->PlugTOS(); |
| 1821 } else { | 1841 } else { |
| 1822 context()->Plug(x0); | 1842 context()->Plug(x0); |
| 1823 } | 1843 } |
| 1844 |
| 1845 // Verify that compilation exactly consumed the number of store ic slots that |
| 1846 // the ObjectLiteral node had to offer. |
| 1847 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); |
| 1824 } | 1848 } |
| 1825 | 1849 |
| 1826 | 1850 |
| 1827 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1851 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1828 Comment cmnt(masm_, "[ ArrayLiteral"); | 1852 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1829 | 1853 |
| 1830 expr->BuildConstantElements(isolate()); | 1854 expr->BuildConstantElements(isolate()); |
| 1831 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1855 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1832 bool has_fast_elements = | 1856 bool has_fast_elements = |
| 1833 IsFastObjectElementsKind(expr->constant_elements_kind()); | 1857 IsFastObjectElementsKind(expr->constant_elements_kind()); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1926 } | 1950 } |
| 1927 } | 1951 } |
| 1928 | 1952 |
| 1929 | 1953 |
| 1930 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1954 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
| 1931 DCHECK(expr->target()->IsValidReferenceExpression()); | 1955 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1932 | 1956 |
| 1933 Comment cmnt(masm_, "[ Assignment"); | 1957 Comment cmnt(masm_, "[ Assignment"); |
| 1934 | 1958 |
| 1935 Property* property = expr->target()->AsProperty(); | 1959 Property* property = expr->target()->AsProperty(); |
| 1936 LhsKind assign_type = GetAssignType(property); | 1960 LhsKind assign_type = Property::GetAssignType(property); |
| 1937 | 1961 |
| 1938 // Evaluate LHS expression. | 1962 // Evaluate LHS expression. |
| 1939 switch (assign_type) { | 1963 switch (assign_type) { |
| 1940 case VARIABLE: | 1964 case VARIABLE: |
| 1941 // Nothing to do here. | 1965 // Nothing to do here. |
| 1942 break; | 1966 break; |
| 1943 case NAMED_PROPERTY: | 1967 case NAMED_PROPERTY: |
| 1944 if (expr->is_compound()) { | 1968 if (expr->is_compound()) { |
| 1945 // We need the receiver both on the stack and in the register. | 1969 // We need the receiver both on the stack and in the register. |
| 1946 VisitForStackValue(property->obj()); | 1970 VisitForStackValue(property->obj()); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2035 VisitForAccumulatorValue(expr->value()); | 2059 VisitForAccumulatorValue(expr->value()); |
| 2036 } | 2060 } |
| 2037 | 2061 |
| 2038 // Record source position before possible IC call. | 2062 // Record source position before possible IC call. |
| 2039 SetSourcePosition(expr->position()); | 2063 SetSourcePosition(expr->position()); |
| 2040 | 2064 |
| 2041 // Store the value. | 2065 // Store the value. |
| 2042 switch (assign_type) { | 2066 switch (assign_type) { |
| 2043 case VARIABLE: | 2067 case VARIABLE: |
| 2044 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2068 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 2045 expr->op()); | 2069 expr->op(), expr->AssignmentSlot()); |
| 2046 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2070 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2047 context()->Plug(x0); | 2071 context()->Plug(x0); |
| 2048 break; | 2072 break; |
| 2049 case NAMED_PROPERTY: | 2073 case NAMED_PROPERTY: |
| 2050 EmitNamedPropertyAssignment(expr); | 2074 EmitNamedPropertyAssignment(expr); |
| 2051 break; | 2075 break; |
| 2052 case NAMED_SUPER_PROPERTY: | 2076 case NAMED_SUPER_PROPERTY: |
| 2053 EmitNamedSuperPropertyStore(property); | 2077 EmitNamedSuperPropertyStore(property); |
| 2054 context()->Plug(x0); | 2078 context()->Plug(x0); |
| 2055 break; | 2079 break; |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2283 } | 2307 } |
| 2284 | 2308 |
| 2285 // prototype | 2309 // prototype |
| 2286 __ CallRuntime(Runtime::kToFastProperties, 1); | 2310 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2287 | 2311 |
| 2288 // constructor | 2312 // constructor |
| 2289 __ CallRuntime(Runtime::kToFastProperties, 1); | 2313 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 2290 } | 2314 } |
| 2291 | 2315 |
| 2292 | 2316 |
| 2293 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2317 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 2318 FeedbackVectorICSlot slot) { |
| 2294 DCHECK(expr->IsValidReferenceExpression()); | 2319 DCHECK(expr->IsValidReferenceExpression()); |
| 2295 | 2320 |
| 2296 Property* prop = expr->AsProperty(); | 2321 Property* prop = expr->AsProperty(); |
| 2297 LhsKind assign_type = GetAssignType(prop); | 2322 LhsKind assign_type = Property::GetAssignType(prop); |
| 2298 | 2323 |
| 2299 switch (assign_type) { | 2324 switch (assign_type) { |
| 2300 case VARIABLE: { | 2325 case VARIABLE: { |
| 2301 Variable* var = expr->AsVariableProxy()->var(); | 2326 Variable* var = expr->AsVariableProxy()->var(); |
| 2302 EffectContext context(this); | 2327 EffectContext context(this); |
| 2303 EmitVariableAssignment(var, Token::ASSIGN); | 2328 EmitVariableAssignment(var, Token::ASSIGN, slot); |
| 2304 break; | 2329 break; |
| 2305 } | 2330 } |
| 2306 case NAMED_PROPERTY: { | 2331 case NAMED_PROPERTY: { |
| 2307 __ Push(x0); // Preserve value. | 2332 __ Push(x0); // Preserve value. |
| 2308 VisitForAccumulatorValue(prop->obj()); | 2333 VisitForAccumulatorValue(prop->obj()); |
| 2309 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid | 2334 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid |
| 2310 // this copy. | 2335 // this copy. |
| 2311 __ Mov(StoreDescriptor::ReceiverRegister(), x0); | 2336 __ Mov(StoreDescriptor::ReceiverRegister(), x0); |
| 2312 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. | 2337 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2313 __ Mov(StoreDescriptor::NameRegister(), | 2338 __ Mov(StoreDescriptor::NameRegister(), |
| 2314 Operand(prop->key()->AsLiteral()->value())); | 2339 Operand(prop->key()->AsLiteral()->value())); |
| 2340 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2315 CallStoreIC(); | 2341 CallStoreIC(); |
| 2316 break; | 2342 break; |
| 2317 } | 2343 } |
| 2318 case NAMED_SUPER_PROPERTY: { | 2344 case NAMED_SUPER_PROPERTY: { |
| 2319 __ Push(x0); | 2345 __ Push(x0); |
| 2320 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 2346 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 2321 EmitLoadHomeObject(prop->obj()->AsSuperReference()); | 2347 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 2322 // stack: value, this; x0: home_object | 2348 // stack: value, this; x0: home_object |
| 2323 Register scratch = x10; | 2349 Register scratch = x10; |
| 2324 Register scratch2 = x11; | 2350 Register scratch2 = x11; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2351 EmitKeyedSuperPropertyStore(prop); | 2377 EmitKeyedSuperPropertyStore(prop); |
| 2352 break; | 2378 break; |
| 2353 } | 2379 } |
| 2354 case KEYED_PROPERTY: { | 2380 case KEYED_PROPERTY: { |
| 2355 __ Push(x0); // Preserve value. | 2381 __ Push(x0); // Preserve value. |
| 2356 VisitForStackValue(prop->obj()); | 2382 VisitForStackValue(prop->obj()); |
| 2357 VisitForAccumulatorValue(prop->key()); | 2383 VisitForAccumulatorValue(prop->key()); |
| 2358 __ Mov(StoreDescriptor::NameRegister(), x0); | 2384 __ Mov(StoreDescriptor::NameRegister(), x0); |
| 2359 __ Pop(StoreDescriptor::ReceiverRegister(), | 2385 __ Pop(StoreDescriptor::ReceiverRegister(), |
| 2360 StoreDescriptor::ValueRegister()); | 2386 StoreDescriptor::ValueRegister()); |
| 2387 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2361 Handle<Code> ic = | 2388 Handle<Code> ic = |
| 2362 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2389 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2363 CallIC(ic); | 2390 CallIC(ic); |
| 2364 break; | 2391 break; |
| 2365 } | 2392 } |
| 2366 } | 2393 } |
| 2367 context()->Plug(x0); | 2394 context()->Plug(x0); |
| 2368 } | 2395 } |
| 2369 | 2396 |
| 2370 | 2397 |
| 2371 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2398 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 2372 Variable* var, MemOperand location) { | 2399 Variable* var, MemOperand location) { |
| 2373 __ Str(result_register(), location); | 2400 __ Str(result_register(), location); |
| 2374 if (var->IsContextSlot()) { | 2401 if (var->IsContextSlot()) { |
| 2375 // RecordWrite may destroy all its register arguments. | 2402 // RecordWrite may destroy all its register arguments. |
| 2376 __ Mov(x10, result_register()); | 2403 __ Mov(x10, result_register()); |
| 2377 int offset = Context::SlotOffset(var->index()); | 2404 int offset = Context::SlotOffset(var->index()); |
| 2378 __ RecordWriteContextSlot( | 2405 __ RecordWriteContextSlot( |
| 2379 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); | 2406 x1, offset, x10, x11, kLRHasBeenSaved, kDontSaveFPRegs); |
| 2380 } | 2407 } |
| 2381 } | 2408 } |
| 2382 | 2409 |
| 2383 | 2410 |
| 2384 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2411 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2385 Token::Value op) { | 2412 FeedbackVectorICSlot slot) { |
| 2386 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); | 2413 ASM_LOCATION("FullCodeGenerator::EmitVariableAssignment"); |
| 2387 if (var->IsUnallocated()) { | 2414 if (var->IsUnallocated()) { |
| 2388 // Global var, const, or let. | 2415 // Global var, const, or let. |
| 2389 __ Mov(StoreDescriptor::NameRegister(), Operand(var->name())); | 2416 __ Mov(StoreDescriptor::NameRegister(), Operand(var->name())); |
| 2390 __ Ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); | 2417 __ Ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectMemOperand()); |
| 2418 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2391 CallStoreIC(); | 2419 CallStoreIC(); |
| 2392 | 2420 |
| 2393 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2421 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2394 // Non-initializing assignment to let variable needs a write barrier. | 2422 // Non-initializing assignment to let variable needs a write barrier. |
| 2395 DCHECK(!var->IsLookupSlot()); | 2423 DCHECK(!var->IsLookupSlot()); |
| 2396 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2424 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2397 Label assign; | 2425 Label assign; |
| 2398 MemOperand location = VarOperand(var, x1); | 2426 MemOperand location = VarOperand(var, x1); |
| 2399 __ Ldr(x10, location); | 2427 __ Ldr(x10, location); |
| 2400 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); | 2428 __ JumpIfNotRoot(x10, Heap::kTheHoleValueRootIndex, &assign); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2476 // Assignment to a property, using a named store IC. | 2504 // Assignment to a property, using a named store IC. |
| 2477 Property* prop = expr->target()->AsProperty(); | 2505 Property* prop = expr->target()->AsProperty(); |
| 2478 DCHECK(prop != NULL); | 2506 DCHECK(prop != NULL); |
| 2479 DCHECK(prop->key()->IsLiteral()); | 2507 DCHECK(prop->key()->IsLiteral()); |
| 2480 | 2508 |
| 2481 // Record source code position before IC call. | 2509 // Record source code position before IC call. |
| 2482 SetSourcePosition(expr->position()); | 2510 SetSourcePosition(expr->position()); |
| 2483 __ Mov(StoreDescriptor::NameRegister(), | 2511 __ Mov(StoreDescriptor::NameRegister(), |
| 2484 Operand(prop->key()->AsLiteral()->value())); | 2512 Operand(prop->key()->AsLiteral()->value())); |
| 2485 __ Pop(StoreDescriptor::ReceiverRegister()); | 2513 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 2486 CallStoreIC(expr->AssignmentFeedbackId()); | 2514 if (FLAG_vector_stores) { |
| 2515 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2516 CallStoreIC(); |
| 2517 } else { |
| 2518 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2519 } |
| 2487 | 2520 |
| 2488 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2521 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2489 context()->Plug(x0); | 2522 context()->Plug(x0); |
| 2490 } | 2523 } |
| 2491 | 2524 |
| 2492 | 2525 |
| 2493 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2526 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2494 // Assignment to named property of super. | 2527 // Assignment to named property of super. |
| 2495 // x0 : value | 2528 // x0 : value |
| 2496 // stack : receiver ('this'), home_object | 2529 // stack : receiver ('this'), home_object |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2525 // Assignment to a property, using a keyed store IC. | 2558 // Assignment to a property, using a keyed store IC. |
| 2526 | 2559 |
| 2527 // Record source code position before IC call. | 2560 // Record source code position before IC call. |
| 2528 SetSourcePosition(expr->position()); | 2561 SetSourcePosition(expr->position()); |
| 2529 // TODO(all): Could we pass this in registers rather than on the stack? | 2562 // TODO(all): Could we pass this in registers rather than on the stack? |
| 2530 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); | 2563 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); |
| 2531 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 2564 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
| 2532 | 2565 |
| 2533 Handle<Code> ic = | 2566 Handle<Code> ic = |
| 2534 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2567 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2535 CallIC(ic, expr->AssignmentFeedbackId()); | 2568 if (FLAG_vector_stores) { |
| 2569 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2570 CallIC(ic); |
| 2571 } else { |
| 2572 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2573 } |
| 2536 | 2574 |
| 2537 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2575 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2538 context()->Plug(x0); | 2576 context()->Plug(x0); |
| 2539 } | 2577 } |
| 2540 | 2578 |
| 2541 | 2579 |
| 2542 void FullCodeGenerator::VisitProperty(Property* expr) { | 2580 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2543 Comment cmnt(masm_, "[ Property"); | 2581 Comment cmnt(masm_, "[ Property"); |
| 2544 Expression* key = expr->key(); | 2582 Expression* key = expr->key(); |
| 2545 | 2583 |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2775 | 2813 |
| 2776 | 2814 |
| 2777 void FullCodeGenerator::EmitLoadSuperConstructor() { | 2815 void FullCodeGenerator::EmitLoadSuperConstructor() { |
| 2778 __ ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 2816 __ ldr(x0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2779 __ Push(x0); | 2817 __ Push(x0); |
| 2780 __ CallRuntime(Runtime::kGetPrototype, 1); | 2818 __ CallRuntime(Runtime::kGetPrototype, 1); |
| 2781 } | 2819 } |
| 2782 | 2820 |
| 2783 | 2821 |
| 2784 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 2822 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 2785 SuperReference* super_ref) { | 2823 SuperReference* super_ref, FeedbackVectorICSlot slot) { |
| 2786 Variable* this_var = super_ref->this_var()->var(); | 2824 Variable* this_var = super_ref->this_var()->var(); |
| 2787 GetVar(x1, this_var); | 2825 GetVar(x1, this_var); |
| 2788 Label uninitialized_this; | 2826 Label uninitialized_this; |
| 2789 __ JumpIfRoot(x1, Heap::kTheHoleValueRootIndex, &uninitialized_this); | 2827 __ JumpIfRoot(x1, Heap::kTheHoleValueRootIndex, &uninitialized_this); |
| 2790 __ Mov(x0, Operand(this_var->name())); | 2828 __ Mov(x0, Operand(this_var->name())); |
| 2791 __ Push(x0); | 2829 __ Push(x0); |
| 2792 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2830 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2793 __ bind(&uninitialized_this); | 2831 __ bind(&uninitialized_this); |
| 2794 | 2832 |
| 2795 EmitVariableAssignment(this_var, Token::INIT_CONST); | 2833 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
| 2796 } | 2834 } |
| 2797 | 2835 |
| 2798 | 2836 |
| 2799 void FullCodeGenerator::VisitCall(Call* expr) { | 2837 void FullCodeGenerator::VisitCall(Call* expr) { |
| 2800 #ifdef DEBUG | 2838 #ifdef DEBUG |
| 2801 // We want to verify that RecordJSReturnSite gets called on all paths | 2839 // We want to verify that RecordJSReturnSite gets called on all paths |
| 2802 // through this function. Avoid early returns. | 2840 // through this function. Avoid early returns. |
| 2803 expr->return_is_recorded_ = false; | 2841 expr->return_is_recorded_ = false; |
| 2804 #endif | 2842 #endif |
| 2805 | 2843 |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3013 __ LoadObject(x2, FeedbackVector()); | 3051 __ LoadObject(x2, FeedbackVector()); |
| 3014 __ Mov(x3, SmiFromSlot(expr->CallFeedbackSlot())); | 3052 __ Mov(x3, SmiFromSlot(expr->CallFeedbackSlot())); |
| 3015 | 3053 |
| 3016 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3054 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
| 3017 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3055 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3018 | 3056 |
| 3019 __ Drop(1); | 3057 __ Drop(1); |
| 3020 | 3058 |
| 3021 RecordJSReturnSite(expr); | 3059 RecordJSReturnSite(expr); |
| 3022 | 3060 |
| 3023 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); | 3061 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), |
| 3062 expr->CallFeedbackICSlot()); |
| 3024 context()->Plug(x0); | 3063 context()->Plug(x0); |
| 3025 } | 3064 } |
| 3026 | 3065 |
| 3027 | 3066 |
| 3028 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3067 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 3029 ZoneList<Expression*>* args = expr->arguments(); | 3068 ZoneList<Expression*>* args = expr->arguments(); |
| 3030 DCHECK(args->length() == 1); | 3069 DCHECK(args->length() == 1); |
| 3031 | 3070 |
| 3032 VisitForAccumulatorValue(args->at(0)); | 3071 VisitForAccumulatorValue(args->at(0)); |
| 3033 | 3072 |
| (...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4300 // Push NewTarget | 4339 // Push NewTarget |
| 4301 DCHECK(args->at(2)->IsVariableProxy()); | 4340 DCHECK(args->at(2)->IsVariableProxy()); |
| 4302 VisitForStackValue(args->at(2)); | 4341 VisitForStackValue(args->at(2)); |
| 4303 | 4342 |
| 4304 EmitCallJSRuntimeFunction(call); | 4343 EmitCallJSRuntimeFunction(call); |
| 4305 | 4344 |
| 4306 // Restore context register. | 4345 // Restore context register. |
| 4307 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4346 __ Ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4308 context()->DropAndPlug(1, x0); | 4347 context()->DropAndPlug(1, x0); |
| 4309 | 4348 |
| 4349 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
| 4310 EmitInitializeThisAfterSuper(super_reference); | 4350 EmitInitializeThisAfterSuper(super_reference); |
| 4311 } | 4351 } |
| 4312 | 4352 |
| 4313 | 4353 |
| 4314 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4354 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4315 // Push the builtins object as the receiver. | 4355 // Push the builtins object as the receiver. |
| 4316 __ Ldr(x10, GlobalObjectMemOperand()); | 4356 __ Ldr(x10, GlobalObjectMemOperand()); |
| 4317 __ Ldr(LoadDescriptor::ReceiverRegister(), | 4357 __ Ldr(LoadDescriptor::ReceiverRegister(), |
| 4318 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); | 4358 FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); |
| 4319 __ Push(LoadDescriptor::ReceiverRegister()); | 4359 __ Push(LoadDescriptor::ReceiverRegister()); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4500 } | 4540 } |
| 4501 | 4541 |
| 4502 | 4542 |
| 4503 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4543 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4504 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4544 DCHECK(expr->expression()->IsValidReferenceExpression()); |
| 4505 | 4545 |
| 4506 Comment cmnt(masm_, "[ CountOperation"); | 4546 Comment cmnt(masm_, "[ CountOperation"); |
| 4507 SetSourcePosition(expr->position()); | 4547 SetSourcePosition(expr->position()); |
| 4508 | 4548 |
| 4509 Property* prop = expr->expression()->AsProperty(); | 4549 Property* prop = expr->expression()->AsProperty(); |
| 4510 LhsKind assign_type = GetAssignType(prop); | 4550 LhsKind assign_type = Property::GetAssignType(prop); |
| 4511 | 4551 |
| 4512 // Evaluate expression and get value. | 4552 // Evaluate expression and get value. |
| 4513 if (assign_type == VARIABLE) { | 4553 if (assign_type == VARIABLE) { |
| 4514 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4554 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4515 AccumulatorValueContext context(this); | 4555 AccumulatorValueContext context(this); |
| 4516 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4556 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4517 } else { | 4557 } else { |
| 4518 // Reserve space for result of postfix operation. | 4558 // Reserve space for result of postfix operation. |
| 4519 if (expr->is_postfix() && !context()->IsEffect()) { | 4559 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4520 __ Push(xzr); | 4560 __ Push(xzr); |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4663 patch_site.EmitPatchInfo(); | 4703 patch_site.EmitPatchInfo(); |
| 4664 } | 4704 } |
| 4665 __ Bind(&done); | 4705 __ Bind(&done); |
| 4666 | 4706 |
| 4667 // Store the value returned in x0. | 4707 // Store the value returned in x0. |
| 4668 switch (assign_type) { | 4708 switch (assign_type) { |
| 4669 case VARIABLE: | 4709 case VARIABLE: |
| 4670 if (expr->is_postfix()) { | 4710 if (expr->is_postfix()) { |
| 4671 { EffectContext context(this); | 4711 { EffectContext context(this); |
| 4672 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4712 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4673 Token::ASSIGN); | 4713 Token::ASSIGN, expr->CountSlot()); |
| 4674 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4714 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4675 context.Plug(x0); | 4715 context.Plug(x0); |
| 4676 } | 4716 } |
| 4677 // For all contexts except EffectConstant We have the result on | 4717 // For all contexts except EffectConstant We have the result on |
| 4678 // top of the stack. | 4718 // top of the stack. |
| 4679 if (!context()->IsEffect()) { | 4719 if (!context()->IsEffect()) { |
| 4680 context()->PlugTOS(); | 4720 context()->PlugTOS(); |
| 4681 } | 4721 } |
| 4682 } else { | 4722 } else { |
| 4683 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4723 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4684 Token::ASSIGN); | 4724 Token::ASSIGN, expr->CountSlot()); |
| 4685 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4725 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4686 context()->Plug(x0); | 4726 context()->Plug(x0); |
| 4687 } | 4727 } |
| 4688 break; | 4728 break; |
| 4689 case NAMED_PROPERTY: { | 4729 case NAMED_PROPERTY: { |
| 4690 __ Mov(StoreDescriptor::NameRegister(), | 4730 __ Mov(StoreDescriptor::NameRegister(), |
| 4691 Operand(prop->key()->AsLiteral()->value())); | 4731 Operand(prop->key()->AsLiteral()->value())); |
| 4692 __ Pop(StoreDescriptor::ReceiverRegister()); | 4732 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4693 CallStoreIC(expr->CountStoreFeedbackId()); | 4733 if (FLAG_vector_stores) { |
| 4734 EmitLoadStoreICSlot(expr->CountSlot()); |
| 4735 CallStoreIC(); |
| 4736 } else { |
| 4737 CallStoreIC(expr->CountStoreFeedbackId()); |
| 4738 } |
| 4694 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4739 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4695 if (expr->is_postfix()) { | 4740 if (expr->is_postfix()) { |
| 4696 if (!context()->IsEffect()) { | 4741 if (!context()->IsEffect()) { |
| 4697 context()->PlugTOS(); | 4742 context()->PlugTOS(); |
| 4698 } | 4743 } |
| 4699 } else { | 4744 } else { |
| 4700 context()->Plug(x0); | 4745 context()->Plug(x0); |
| 4701 } | 4746 } |
| 4702 break; | 4747 break; |
| 4703 } | 4748 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4721 } else { | 4766 } else { |
| 4722 context()->Plug(x0); | 4767 context()->Plug(x0); |
| 4723 } | 4768 } |
| 4724 break; | 4769 break; |
| 4725 } | 4770 } |
| 4726 case KEYED_PROPERTY: { | 4771 case KEYED_PROPERTY: { |
| 4727 __ Pop(StoreDescriptor::NameRegister()); | 4772 __ Pop(StoreDescriptor::NameRegister()); |
| 4728 __ Pop(StoreDescriptor::ReceiverRegister()); | 4773 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4729 Handle<Code> ic = | 4774 Handle<Code> ic = |
| 4730 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 4775 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 4731 CallIC(ic, expr->CountStoreFeedbackId()); | 4776 if (FLAG_vector_stores) { |
| 4777 EmitLoadStoreICSlot(expr->CountSlot()); |
| 4778 CallIC(ic); |
| 4779 } else { |
| 4780 CallIC(ic, expr->CountStoreFeedbackId()); |
| 4781 } |
| 4732 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4782 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4733 if (expr->is_postfix()) { | 4783 if (expr->is_postfix()) { |
| 4734 if (!context()->IsEffect()) { | 4784 if (!context()->IsEffect()) { |
| 4735 context()->PlugTOS(); | 4785 context()->PlugTOS(); |
| 4736 } | 4786 } |
| 4737 } else { | 4787 } else { |
| 4738 context()->Plug(x0); | 4788 context()->Plug(x0); |
| 4739 } | 4789 } |
| 4740 break; | 4790 break; |
| 4741 } | 4791 } |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5387 void FullCodeGenerator::ClearPendingMessage() { | 5437 void FullCodeGenerator::ClearPendingMessage() { |
| 5388 DCHECK(!result_register().is(x10)); | 5438 DCHECK(!result_register().is(x10)); |
| 5389 ExternalReference pending_message_obj = | 5439 ExternalReference pending_message_obj = |
| 5390 ExternalReference::address_of_pending_message_obj(isolate()); | 5440 ExternalReference::address_of_pending_message_obj(isolate()); |
| 5391 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex); | 5441 __ LoadRoot(x10, Heap::kTheHoleValueRootIndex); |
| 5392 __ Mov(x13, pending_message_obj); | 5442 __ Mov(x13, pending_message_obj); |
| 5393 __ Str(x10, MemOperand(x13)); | 5443 __ Str(x10, MemOperand(x13)); |
| 5394 } | 5444 } |
| 5395 | 5445 |
| 5396 | 5446 |
| 5447 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { |
| 5448 DCHECK(FLAG_vector_stores && !slot.IsInvalid()); |
| 5449 __ Mov(VectorStoreICTrampolineDescriptor::SlotRegister(), SmiFromSlot(slot)); |
| 5450 } |
| 5451 |
| 5452 |
| 5397 #undef __ | 5453 #undef __ |
| 5398 | 5454 |
| 5399 | 5455 |
| 5400 void BackEdgeTable::PatchAt(Code* unoptimized_code, | 5456 void BackEdgeTable::PatchAt(Code* unoptimized_code, |
| 5401 Address pc, | 5457 Address pc, |
| 5402 BackEdgeState target_state, | 5458 BackEdgeState target_state, |
| 5403 Code* replacement_code) { | 5459 Code* replacement_code) { |
| 5404 // Turn the jump into a nop. | 5460 // Turn the jump into a nop. |
| 5405 Address branch_address = pc - 3 * kInstructionSize; | 5461 Address branch_address = pc - 3 * kInstructionSize; |
| 5406 PatchingAssembler patcher(branch_address, 1); | 5462 PatchingAssembler patcher(branch_address, 1); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5488 } | 5544 } |
| 5489 } | 5545 } |
| 5490 | 5546 |
| 5491 return INTERRUPT; | 5547 return INTERRUPT; |
| 5492 } | 5548 } |
| 5493 | 5549 |
| 5494 | 5550 |
| 5495 } } // namespace v8::internal | 5551 } } // namespace v8::internal |
| 5496 | 5552 |
| 5497 #endif // V8_TARGET_ARCH_ARM64 | 5553 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |