| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_ARM | 7 #if V8_TARGET_ARCH_ARM |
| 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 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); | 1257 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); |
| 1258 __ mov(r3, Operand(r0), SetCC); | 1258 __ mov(r3, Operand(r0), SetCC); |
| 1259 __ b(eq, loop_statement.continue_label()); | 1259 __ b(eq, loop_statement.continue_label()); |
| 1260 | 1260 |
| 1261 // Update the 'each' property or variable from the possibly filtered | 1261 // Update the 'each' property or variable from the possibly filtered |
| 1262 // entry in register r3. | 1262 // entry in register r3. |
| 1263 __ bind(&update_each); | 1263 __ bind(&update_each); |
| 1264 __ mov(result_register(), r3); | 1264 __ mov(result_register(), r3); |
| 1265 // Perform the assignment as if via '='. | 1265 // Perform the assignment as if via '='. |
| 1266 { EffectContext context(this); | 1266 { EffectContext context(this); |
| 1267 EmitAssignment(stmt->each()); | 1267 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
| 1268 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); | 1268 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); |
| 1269 } | 1269 } |
| 1270 | 1270 |
| 1271 // Generate code for the body of the loop. | 1271 // Generate code for the body of the loop. |
| 1272 Visit(stmt->body()); | 1272 Visit(stmt->body()); |
| 1273 | 1273 |
| 1274 // Generate code for the going to the next element by incrementing | 1274 // Generate code for the going to the next element by incrementing |
| 1275 // the index (smi) stored on top of the stack. | 1275 // the index (smi) stored on top of the stack. |
| 1276 __ bind(loop_statement.continue_label()); | 1276 __ bind(loop_statement.continue_label()); |
| 1277 __ pop(r0); | 1277 __ pop(r0); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 | 1340 |
| 1341 __ cmp(r0, Operand(isolate()->factory()->undefined_value())); | 1341 __ cmp(r0, Operand(isolate()->factory()->undefined_value())); |
| 1342 Label done; | 1342 Label done; |
| 1343 __ b(ne, &done); | 1343 __ b(ne, &done); |
| 1344 __ CallRuntime(Runtime::kThrowNonMethodError, 0); | 1344 __ CallRuntime(Runtime::kThrowNonMethodError, 0); |
| 1345 __ bind(&done); | 1345 __ bind(&done); |
| 1346 } | 1346 } |
| 1347 | 1347 |
| 1348 | 1348 |
| 1349 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1349 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1350 int offset) { | 1350 int offset, |
| 1351 FeedbackVectorICSlot slot) { |
| 1351 if (NeedsHomeObject(initializer)) { | 1352 if (NeedsHomeObject(initializer)) { |
| 1352 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1353 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
| 1353 __ mov(StoreDescriptor::NameRegister(), | 1354 __ mov(StoreDescriptor::NameRegister(), |
| 1354 Operand(isolate()->factory()->home_object_symbol())); | 1355 Operand(isolate()->factory()->home_object_symbol())); |
| 1355 __ ldr(StoreDescriptor::ValueRegister(), | 1356 __ ldr(StoreDescriptor::ValueRegister(), |
| 1356 MemOperand(sp, offset * kPointerSize)); | 1357 MemOperand(sp, offset * kPointerSize)); |
| 1358 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1357 CallStoreIC(); | 1359 CallStoreIC(); |
| 1358 } | 1360 } |
| 1359 } | 1361 } |
| 1360 | 1362 |
| 1361 | 1363 |
| 1362 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1364 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1363 TypeofState typeof_state, | 1365 TypeofState typeof_state, |
| 1364 Label* slow) { | 1366 Label* slow) { |
| 1365 Register current = cp; | 1367 Register current = cp; |
| 1366 Register next = r1; | 1368 Register next = r1; |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1671 __ CallStub(&stub); | 1673 __ CallStub(&stub); |
| 1672 } | 1674 } |
| 1673 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1675 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1674 | 1676 |
| 1675 // If result_saved is true the result is on top of the stack. If | 1677 // If result_saved is true the result is on top of the stack. If |
| 1676 // result_saved is false the result is in r0. | 1678 // result_saved is false the result is in r0. |
| 1677 bool result_saved = false; | 1679 bool result_saved = false; |
| 1678 | 1680 |
| 1679 AccessorTable accessor_table(zone()); | 1681 AccessorTable accessor_table(zone()); |
| 1680 int property_index = 0; | 1682 int property_index = 0; |
| 1683 // store_slot_index points to the vector ic slot for the next store ic used. |
| 1684 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots |
| 1685 // and must be updated if the number of store ics emitted here changes. |
| 1686 int store_slot_index = 0; |
| 1681 for (; property_index < expr->properties()->length(); property_index++) { | 1687 for (; property_index < expr->properties()->length(); property_index++) { |
| 1682 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1688 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1683 if (property->is_computed_name()) break; | 1689 if (property->is_computed_name()) break; |
| 1684 if (property->IsCompileTimeValue()) continue; | 1690 if (property->IsCompileTimeValue()) continue; |
| 1685 | 1691 |
| 1686 Literal* key = property->key()->AsLiteral(); | 1692 Literal* key = property->key()->AsLiteral(); |
| 1687 Expression* value = property->value(); | 1693 Expression* value = property->value(); |
| 1688 if (!result_saved) { | 1694 if (!result_saved) { |
| 1689 __ push(r0); // Save result on stack | 1695 __ push(r0); // Save result on stack |
| 1690 result_saved = true; | 1696 result_saved = true; |
| 1691 } | 1697 } |
| 1692 switch (property->kind()) { | 1698 switch (property->kind()) { |
| 1693 case ObjectLiteral::Property::CONSTANT: | 1699 case ObjectLiteral::Property::CONSTANT: |
| 1694 UNREACHABLE(); | 1700 UNREACHABLE(); |
| 1695 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1701 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1696 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1702 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1697 // Fall through. | 1703 // Fall through. |
| 1698 case ObjectLiteral::Property::COMPUTED: | 1704 case ObjectLiteral::Property::COMPUTED: |
| 1699 // It is safe to use [[Put]] here because the boilerplate already | 1705 // It is safe to use [[Put]] here because the boilerplate already |
| 1700 // contains computed properties with an uninitialized value. | 1706 // contains computed properties with an uninitialized value. |
| 1701 if (key->value()->IsInternalizedString()) { | 1707 if (key->value()->IsInternalizedString()) { |
| 1702 if (property->emit_store()) { | 1708 if (property->emit_store()) { |
| 1703 VisitForAccumulatorValue(value); | 1709 VisitForAccumulatorValue(value); |
| 1704 DCHECK(StoreDescriptor::ValueRegister().is(r0)); | 1710 DCHECK(StoreDescriptor::ValueRegister().is(r0)); |
| 1705 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); | 1711 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); |
| 1706 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1712 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
| 1707 CallStoreIC(key->LiteralFeedbackId()); | 1713 if (FLAG_vector_stores) { |
| 1714 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1715 CallStoreIC(); |
| 1716 } else { |
| 1717 CallStoreIC(key->LiteralFeedbackId()); |
| 1718 } |
| 1708 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1719 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1709 | 1720 |
| 1710 if (NeedsHomeObject(value)) { | 1721 if (NeedsHomeObject(value)) { |
| 1711 __ Move(StoreDescriptor::ReceiverRegister(), r0); | 1722 __ Move(StoreDescriptor::ReceiverRegister(), r0); |
| 1712 __ mov(StoreDescriptor::NameRegister(), | 1723 __ mov(StoreDescriptor::NameRegister(), |
| 1713 Operand(isolate()->factory()->home_object_symbol())); | 1724 Operand(isolate()->factory()->home_object_symbol())); |
| 1714 __ ldr(StoreDescriptor::ValueRegister(), MemOperand(sp)); | 1725 __ ldr(StoreDescriptor::ValueRegister(), MemOperand(sp)); |
| 1726 if (FLAG_vector_stores) { |
| 1727 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1728 } |
| 1715 CallStoreIC(); | 1729 CallStoreIC(); |
| 1716 } | 1730 } |
| 1717 } else { | 1731 } else { |
| 1718 VisitForEffect(value); | 1732 VisitForEffect(value); |
| 1719 } | 1733 } |
| 1720 break; | 1734 break; |
| 1721 } | 1735 } |
| 1722 // Duplicate receiver on stack. | 1736 // Duplicate receiver on stack. |
| 1723 __ ldr(r0, MemOperand(sp)); | 1737 __ ldr(r0, MemOperand(sp)); |
| 1724 __ push(r0); | 1738 __ push(r0); |
| 1725 VisitForStackValue(key); | 1739 VisitForStackValue(key); |
| 1726 VisitForStackValue(value); | 1740 VisitForStackValue(value); |
| 1727 if (property->emit_store()) { | 1741 if (property->emit_store()) { |
| 1728 EmitSetHomeObjectIfNeeded(value, 2); | 1742 EmitSetHomeObjectIfNeeded( |
| 1743 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1729 __ mov(r0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes | 1744 __ mov(r0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes |
| 1730 __ push(r0); | 1745 __ push(r0); |
| 1731 __ CallRuntime(Runtime::kSetProperty, 4); | 1746 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1732 } else { | 1747 } else { |
| 1733 __ Drop(3); | 1748 __ Drop(3); |
| 1734 } | 1749 } |
| 1735 break; | 1750 break; |
| 1736 case ObjectLiteral::Property::PROTOTYPE: | 1751 case ObjectLiteral::Property::PROTOTYPE: |
| 1737 // Duplicate receiver on stack. | 1752 // Duplicate receiver on stack. |
| 1738 __ ldr(r0, MemOperand(sp)); | 1753 __ ldr(r0, MemOperand(sp)); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1757 | 1772 |
| 1758 // Emit code to define accessors, using only a single call to the runtime for | 1773 // Emit code to define accessors, using only a single call to the runtime for |
| 1759 // each pair of corresponding getters and setters. | 1774 // each pair of corresponding getters and setters. |
| 1760 for (AccessorTable::Iterator it = accessor_table.begin(); | 1775 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1761 it != accessor_table.end(); | 1776 it != accessor_table.end(); |
| 1762 ++it) { | 1777 ++it) { |
| 1763 __ ldr(r0, MemOperand(sp)); // Duplicate receiver. | 1778 __ ldr(r0, MemOperand(sp)); // Duplicate receiver. |
| 1764 __ push(r0); | 1779 __ push(r0); |
| 1765 VisitForStackValue(it->first); | 1780 VisitForStackValue(it->first); |
| 1766 EmitAccessor(it->second->getter); | 1781 EmitAccessor(it->second->getter); |
| 1767 EmitSetHomeObjectIfNeeded(it->second->getter, 2); | 1782 EmitSetHomeObjectIfNeeded( |
| 1783 it->second->getter, 2, |
| 1784 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); |
| 1768 EmitAccessor(it->second->setter); | 1785 EmitAccessor(it->second->setter); |
| 1769 EmitSetHomeObjectIfNeeded(it->second->setter, 3); | 1786 EmitSetHomeObjectIfNeeded( |
| 1787 it->second->setter, 3, |
| 1788 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); |
| 1770 __ mov(r0, Operand(Smi::FromInt(NONE))); | 1789 __ mov(r0, Operand(Smi::FromInt(NONE))); |
| 1771 __ push(r0); | 1790 __ push(r0); |
| 1772 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1791 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1773 } | 1792 } |
| 1774 | 1793 |
| 1775 // Object literals have two parts. The "static" part on the left contains no | 1794 // Object literals have two parts. The "static" part on the left contains no |
| 1776 // computed property names, and so we can compute its map ahead of time; see | 1795 // computed property names, and so we can compute its map ahead of time; see |
| 1777 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1796 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1778 // starts with the first computed property name, and continues with all | 1797 // starts with the first computed property name, and continues with all |
| 1779 // properties to its right. All the code from above initializes the static | 1798 // properties to its right. All the code from above initializes the static |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1794 __ push(r0); | 1813 __ push(r0); |
| 1795 | 1814 |
| 1796 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1815 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1797 DCHECK(!property->is_computed_name()); | 1816 DCHECK(!property->is_computed_name()); |
| 1798 VisitForStackValue(value); | 1817 VisitForStackValue(value); |
| 1799 DCHECK(property->emit_store()); | 1818 DCHECK(property->emit_store()); |
| 1800 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1819 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1801 } else { | 1820 } else { |
| 1802 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1821 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1803 VisitForStackValue(value); | 1822 VisitForStackValue(value); |
| 1804 EmitSetHomeObjectIfNeeded(value, 2); | 1823 EmitSetHomeObjectIfNeeded( |
| 1824 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1805 | 1825 |
| 1806 switch (property->kind()) { | 1826 switch (property->kind()) { |
| 1807 case ObjectLiteral::Property::CONSTANT: | 1827 case ObjectLiteral::Property::CONSTANT: |
| 1808 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1828 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1809 case ObjectLiteral::Property::COMPUTED: | 1829 case ObjectLiteral::Property::COMPUTED: |
| 1810 if (property->emit_store()) { | 1830 if (property->emit_store()) { |
| 1811 __ mov(r0, Operand(Smi::FromInt(NONE))); | 1831 __ mov(r0, Operand(Smi::FromInt(NONE))); |
| 1812 __ push(r0); | 1832 __ push(r0); |
| 1813 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1833 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1814 } else { | 1834 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1840 __ ldr(r0, MemOperand(sp)); | 1860 __ ldr(r0, MemOperand(sp)); |
| 1841 __ push(r0); | 1861 __ push(r0); |
| 1842 __ CallRuntime(Runtime::kToFastProperties, 1); | 1862 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1843 } | 1863 } |
| 1844 | 1864 |
| 1845 if (result_saved) { | 1865 if (result_saved) { |
| 1846 context()->PlugTOS(); | 1866 context()->PlugTOS(); |
| 1847 } else { | 1867 } else { |
| 1848 context()->Plug(r0); | 1868 context()->Plug(r0); |
| 1849 } | 1869 } |
| 1870 |
| 1871 // Verify that compilation exactly consumed the number of store ic slots that |
| 1872 // the ObjectLiteral node had to offer. |
| 1873 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); |
| 1850 } | 1874 } |
| 1851 | 1875 |
| 1852 | 1876 |
| 1853 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1877 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1854 Comment cmnt(masm_, "[ ArrayLiteral"); | 1878 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1855 | 1879 |
| 1856 expr->BuildConstantElements(isolate()); | 1880 expr->BuildConstantElements(isolate()); |
| 1857 | 1881 |
| 1858 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1882 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1859 bool has_fast_elements = | 1883 bool has_fast_elements = |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1955 } | 1979 } |
| 1956 } | 1980 } |
| 1957 | 1981 |
| 1958 | 1982 |
| 1959 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1983 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
| 1960 DCHECK(expr->target()->IsValidReferenceExpression()); | 1984 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1961 | 1985 |
| 1962 Comment cmnt(masm_, "[ Assignment"); | 1986 Comment cmnt(masm_, "[ Assignment"); |
| 1963 | 1987 |
| 1964 Property* property = expr->target()->AsProperty(); | 1988 Property* property = expr->target()->AsProperty(); |
| 1965 LhsKind assign_type = GetAssignType(property); | 1989 LhsKind assign_type = Property::GetAssignType(property); |
| 1966 | 1990 |
| 1967 // Evaluate LHS expression. | 1991 // Evaluate LHS expression. |
| 1968 switch (assign_type) { | 1992 switch (assign_type) { |
| 1969 case VARIABLE: | 1993 case VARIABLE: |
| 1970 // Nothing to do here. | 1994 // Nothing to do here. |
| 1971 break; | 1995 break; |
| 1972 case NAMED_PROPERTY: | 1996 case NAMED_PROPERTY: |
| 1973 if (expr->is_compound()) { | 1997 if (expr->is_compound()) { |
| 1974 // We need the receiver both on the stack and in the register. | 1998 // We need the receiver both on the stack and in the register. |
| 1975 VisitForStackValue(property->obj()); | 1999 VisitForStackValue(property->obj()); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2067 VisitForAccumulatorValue(expr->value()); | 2091 VisitForAccumulatorValue(expr->value()); |
| 2068 } | 2092 } |
| 2069 | 2093 |
| 2070 // Record source position before possible IC call. | 2094 // Record source position before possible IC call. |
| 2071 SetSourcePosition(expr->position()); | 2095 SetSourcePosition(expr->position()); |
| 2072 | 2096 |
| 2073 // Store the value. | 2097 // Store the value. |
| 2074 switch (assign_type) { | 2098 switch (assign_type) { |
| 2075 case VARIABLE: | 2099 case VARIABLE: |
| 2076 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2100 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 2077 expr->op()); | 2101 expr->op(), expr->AssignmentSlot()); |
| 2078 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2102 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2079 context()->Plug(r0); | 2103 context()->Plug(r0); |
| 2080 break; | 2104 break; |
| 2081 case NAMED_PROPERTY: | 2105 case NAMED_PROPERTY: |
| 2082 EmitNamedPropertyAssignment(expr); | 2106 EmitNamedPropertyAssignment(expr); |
| 2083 break; | 2107 break; |
| 2084 case NAMED_SUPER_PROPERTY: | 2108 case NAMED_SUPER_PROPERTY: |
| 2085 EmitNamedSuperPropertyStore(property); | 2109 EmitNamedSuperPropertyStore(property); |
| 2086 context()->Plug(r0); | 2110 context()->Plug(r0); |
| 2087 break; | 2111 break; |
| (...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2601 __ pop(r1); | 2625 __ pop(r1); |
| 2602 Handle<Code> code = CodeFactory::BinaryOpIC( | 2626 Handle<Code> code = CodeFactory::BinaryOpIC( |
| 2603 isolate(), op, language_mode()).code(); | 2627 isolate(), op, language_mode()).code(); |
| 2604 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2628 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2605 CallIC(code, expr->BinaryOperationFeedbackId()); | 2629 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2606 patch_site.EmitPatchInfo(); | 2630 patch_site.EmitPatchInfo(); |
| 2607 context()->Plug(r0); | 2631 context()->Plug(r0); |
| 2608 } | 2632 } |
| 2609 | 2633 |
| 2610 | 2634 |
| 2611 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2635 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 2636 FeedbackVectorICSlot slot) { |
| 2612 DCHECK(expr->IsValidReferenceExpression()); | 2637 DCHECK(expr->IsValidReferenceExpression()); |
| 2613 | 2638 |
| 2614 Property* prop = expr->AsProperty(); | 2639 Property* prop = expr->AsProperty(); |
| 2615 LhsKind assign_type = GetAssignType(prop); | 2640 LhsKind assign_type = Property::GetAssignType(prop); |
| 2616 | 2641 |
| 2617 switch (assign_type) { | 2642 switch (assign_type) { |
| 2618 case VARIABLE: { | 2643 case VARIABLE: { |
| 2619 Variable* var = expr->AsVariableProxy()->var(); | 2644 Variable* var = expr->AsVariableProxy()->var(); |
| 2620 EffectContext context(this); | 2645 EffectContext context(this); |
| 2621 EmitVariableAssignment(var, Token::ASSIGN); | 2646 EmitVariableAssignment(var, Token::ASSIGN, slot); |
| 2622 break; | 2647 break; |
| 2623 } | 2648 } |
| 2624 case NAMED_PROPERTY: { | 2649 case NAMED_PROPERTY: { |
| 2625 __ push(r0); // Preserve value. | 2650 __ push(r0); // Preserve value. |
| 2626 VisitForAccumulatorValue(prop->obj()); | 2651 VisitForAccumulatorValue(prop->obj()); |
| 2627 __ Move(StoreDescriptor::ReceiverRegister(), r0); | 2652 __ Move(StoreDescriptor::ReceiverRegister(), r0); |
| 2628 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2653 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2629 __ mov(StoreDescriptor::NameRegister(), | 2654 __ mov(StoreDescriptor::NameRegister(), |
| 2630 Operand(prop->key()->AsLiteral()->value())); | 2655 Operand(prop->key()->AsLiteral()->value())); |
| 2656 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2631 CallStoreIC(); | 2657 CallStoreIC(); |
| 2632 break; | 2658 break; |
| 2633 } | 2659 } |
| 2634 case NAMED_SUPER_PROPERTY: { | 2660 case NAMED_SUPER_PROPERTY: { |
| 2635 __ Push(r0); | 2661 __ Push(r0); |
| 2636 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 2662 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 2637 EmitLoadHomeObject(prop->obj()->AsSuperReference()); | 2663 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 2638 // stack: value, this; r0: home_object | 2664 // stack: value, this; r0: home_object |
| 2639 Register scratch = r2; | 2665 Register scratch = r2; |
| 2640 Register scratch2 = r3; | 2666 Register scratch2 = r3; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2667 EmitKeyedSuperPropertyStore(prop); | 2693 EmitKeyedSuperPropertyStore(prop); |
| 2668 break; | 2694 break; |
| 2669 } | 2695 } |
| 2670 case KEYED_PROPERTY: { | 2696 case KEYED_PROPERTY: { |
| 2671 __ push(r0); // Preserve value. | 2697 __ push(r0); // Preserve value. |
| 2672 VisitForStackValue(prop->obj()); | 2698 VisitForStackValue(prop->obj()); |
| 2673 VisitForAccumulatorValue(prop->key()); | 2699 VisitForAccumulatorValue(prop->key()); |
| 2674 __ Move(StoreDescriptor::NameRegister(), r0); | 2700 __ Move(StoreDescriptor::NameRegister(), r0); |
| 2675 __ Pop(StoreDescriptor::ValueRegister(), | 2701 __ Pop(StoreDescriptor::ValueRegister(), |
| 2676 StoreDescriptor::ReceiverRegister()); | 2702 StoreDescriptor::ReceiverRegister()); |
| 2703 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2677 Handle<Code> ic = | 2704 Handle<Code> ic = |
| 2678 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2705 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2679 CallIC(ic); | 2706 CallIC(ic); |
| 2680 break; | 2707 break; |
| 2681 } | 2708 } |
| 2682 } | 2709 } |
| 2683 context()->Plug(r0); | 2710 context()->Plug(r0); |
| 2684 } | 2711 } |
| 2685 | 2712 |
| 2686 | 2713 |
| 2687 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2714 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 2688 Variable* var, MemOperand location) { | 2715 Variable* var, MemOperand location) { |
| 2689 __ str(result_register(), location); | 2716 __ str(result_register(), location); |
| 2690 if (var->IsContextSlot()) { | 2717 if (var->IsContextSlot()) { |
| 2691 // RecordWrite may destroy all its register arguments. | 2718 // RecordWrite may destroy all its register arguments. |
| 2692 __ mov(r3, result_register()); | 2719 __ mov(r3, result_register()); |
| 2693 int offset = Context::SlotOffset(var->index()); | 2720 int offset = Context::SlotOffset(var->index()); |
| 2694 __ RecordWriteContextSlot( | 2721 __ RecordWriteContextSlot( |
| 2695 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); | 2722 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); |
| 2696 } | 2723 } |
| 2697 } | 2724 } |
| 2698 | 2725 |
| 2699 | 2726 |
| 2700 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { | 2727 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2728 FeedbackVectorICSlot slot) { |
| 2701 if (var->IsUnallocated()) { | 2729 if (var->IsUnallocated()) { |
| 2702 // Global var, const, or let. | 2730 // Global var, const, or let. |
| 2703 __ mov(StoreDescriptor::NameRegister(), Operand(var->name())); | 2731 __ mov(StoreDescriptor::NameRegister(), Operand(var->name())); |
| 2704 __ ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2732 __ ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2733 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2705 CallStoreIC(); | 2734 CallStoreIC(); |
| 2706 | 2735 |
| 2707 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2736 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2708 // Non-initializing assignment to let variable needs a write barrier. | 2737 // Non-initializing assignment to let variable needs a write barrier. |
| 2709 DCHECK(!var->IsLookupSlot()); | 2738 DCHECK(!var->IsLookupSlot()); |
| 2710 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2739 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2711 Label assign; | 2740 Label assign; |
| 2712 MemOperand location = VarOperand(var, r1); | 2741 MemOperand location = VarOperand(var, r1); |
| 2713 __ ldr(r3, location); | 2742 __ ldr(r3, location); |
| 2714 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); | 2743 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2791 // Assignment to a property, using a named store IC. | 2820 // Assignment to a property, using a named store IC. |
| 2792 Property* prop = expr->target()->AsProperty(); | 2821 Property* prop = expr->target()->AsProperty(); |
| 2793 DCHECK(prop != NULL); | 2822 DCHECK(prop != NULL); |
| 2794 DCHECK(prop->key()->IsLiteral()); | 2823 DCHECK(prop->key()->IsLiteral()); |
| 2795 | 2824 |
| 2796 // Record source code position before IC call. | 2825 // Record source code position before IC call. |
| 2797 SetSourcePosition(expr->position()); | 2826 SetSourcePosition(expr->position()); |
| 2798 __ mov(StoreDescriptor::NameRegister(), | 2827 __ mov(StoreDescriptor::NameRegister(), |
| 2799 Operand(prop->key()->AsLiteral()->value())); | 2828 Operand(prop->key()->AsLiteral()->value())); |
| 2800 __ pop(StoreDescriptor::ReceiverRegister()); | 2829 __ pop(StoreDescriptor::ReceiverRegister()); |
| 2801 CallStoreIC(expr->AssignmentFeedbackId()); | 2830 if (FLAG_vector_stores) { |
| 2831 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2832 CallStoreIC(); |
| 2833 } else { |
| 2834 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2835 } |
| 2802 | 2836 |
| 2803 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2837 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2804 context()->Plug(r0); | 2838 context()->Plug(r0); |
| 2805 } | 2839 } |
| 2806 | 2840 |
| 2807 | 2841 |
| 2808 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2842 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2809 // Assignment to named property of super. | 2843 // Assignment to named property of super. |
| 2810 // r0 : value | 2844 // r0 : value |
| 2811 // stack : receiver ('this'), home_object | 2845 // stack : receiver ('this'), home_object |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2838 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2872 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2839 // Assignment to a property, using a keyed store IC. | 2873 // Assignment to a property, using a keyed store IC. |
| 2840 | 2874 |
| 2841 // Record source code position before IC call. | 2875 // Record source code position before IC call. |
| 2842 SetSourcePosition(expr->position()); | 2876 SetSourcePosition(expr->position()); |
| 2843 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); | 2877 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); |
| 2844 DCHECK(StoreDescriptor::ValueRegister().is(r0)); | 2878 DCHECK(StoreDescriptor::ValueRegister().is(r0)); |
| 2845 | 2879 |
| 2846 Handle<Code> ic = | 2880 Handle<Code> ic = |
| 2847 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2881 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2848 CallIC(ic, expr->AssignmentFeedbackId()); | 2882 if (FLAG_vector_stores) { |
| 2883 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2884 CallIC(ic); |
| 2885 } else { |
| 2886 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2887 } |
| 2849 | 2888 |
| 2850 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2889 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2851 context()->Plug(r0); | 2890 context()->Plug(r0); |
| 2852 } | 2891 } |
| 2853 | 2892 |
| 2854 | 2893 |
| 2855 void FullCodeGenerator::VisitProperty(Property* expr) { | 2894 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2856 Comment cmnt(masm_, "[ Property"); | 2895 Comment cmnt(masm_, "[ Property"); |
| 2857 Expression* key = expr->key(); | 2896 Expression* key = expr->key(); |
| 2858 | 2897 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3087 | 3126 |
| 3088 | 3127 |
| 3089 void FullCodeGenerator::EmitLoadSuperConstructor() { | 3128 void FullCodeGenerator::EmitLoadSuperConstructor() { |
| 3090 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 3129 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3091 __ Push(r0); | 3130 __ Push(r0); |
| 3092 __ CallRuntime(Runtime::kGetPrototype, 1); | 3131 __ CallRuntime(Runtime::kGetPrototype, 1); |
| 3093 } | 3132 } |
| 3094 | 3133 |
| 3095 | 3134 |
| 3096 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3135 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 3097 SuperReference* super_ref) { | 3136 SuperReference* super_ref, FeedbackVectorICSlot slot) { |
| 3098 Variable* this_var = super_ref->this_var()->var(); | 3137 Variable* this_var = super_ref->this_var()->var(); |
| 3099 GetVar(r1, this_var); | 3138 GetVar(r1, this_var); |
| 3100 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); | 3139 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); |
| 3101 Label uninitialized_this; | 3140 Label uninitialized_this; |
| 3102 __ b(eq, &uninitialized_this); | 3141 __ b(eq, &uninitialized_this); |
| 3103 __ mov(r0, Operand(this_var->name())); | 3142 __ mov(r0, Operand(this_var->name())); |
| 3104 __ Push(r0); | 3143 __ Push(r0); |
| 3105 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3144 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 3106 __ bind(&uninitialized_this); | 3145 __ bind(&uninitialized_this); |
| 3107 | 3146 |
| 3108 EmitVariableAssignment(this_var, Token::INIT_CONST); | 3147 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
| 3109 } | 3148 } |
| 3110 | 3149 |
| 3111 | 3150 |
| 3112 void FullCodeGenerator::VisitCall(Call* expr) { | 3151 void FullCodeGenerator::VisitCall(Call* expr) { |
| 3113 #ifdef DEBUG | 3152 #ifdef DEBUG |
| 3114 // We want to verify that RecordJSReturnSite gets called on all paths | 3153 // We want to verify that RecordJSReturnSite gets called on all paths |
| 3115 // through this function. Avoid early returns. | 3154 // through this function. Avoid early returns. |
| 3116 expr->return_is_recorded_ = false; | 3155 expr->return_is_recorded_ = false; |
| 3117 #endif | 3156 #endif |
| 3118 | 3157 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3325 __ Move(r2, FeedbackVector()); | 3364 __ Move(r2, FeedbackVector()); |
| 3326 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); | 3365 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); |
| 3327 | 3366 |
| 3328 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3367 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
| 3329 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3368 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3330 | 3369 |
| 3331 __ Drop(1); | 3370 __ Drop(1); |
| 3332 | 3371 |
| 3333 RecordJSReturnSite(expr); | 3372 RecordJSReturnSite(expr); |
| 3334 | 3373 |
| 3335 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); | 3374 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), |
| 3375 expr->CallFeedbackICSlot()); |
| 3336 context()->Plug(r0); | 3376 context()->Plug(r0); |
| 3337 } | 3377 } |
| 3338 | 3378 |
| 3339 | 3379 |
| 3340 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3380 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 3341 ZoneList<Expression*>* args = expr->arguments(); | 3381 ZoneList<Expression*>* args = expr->arguments(); |
| 3342 DCHECK(args->length() == 1); | 3382 DCHECK(args->length() == 1); |
| 3343 | 3383 |
| 3344 VisitForAccumulatorValue(args->at(0)); | 3384 VisitForAccumulatorValue(args->at(0)); |
| 3345 | 3385 |
| (...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4614 // Push NewTarget | 4654 // Push NewTarget |
| 4615 DCHECK(args->at(2)->IsVariableProxy()); | 4655 DCHECK(args->at(2)->IsVariableProxy()); |
| 4616 VisitForStackValue(args->at(2)); | 4656 VisitForStackValue(args->at(2)); |
| 4617 | 4657 |
| 4618 EmitCallJSRuntimeFunction(call); | 4658 EmitCallJSRuntimeFunction(call); |
| 4619 | 4659 |
| 4620 // Restore context register. | 4660 // Restore context register. |
| 4621 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4661 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4622 context()->DropAndPlug(1, r0); | 4662 context()->DropAndPlug(1, r0); |
| 4623 | 4663 |
| 4664 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
| 4624 EmitInitializeThisAfterSuper(super_reference); | 4665 EmitInitializeThisAfterSuper(super_reference); |
| 4625 } | 4666 } |
| 4626 | 4667 |
| 4627 | 4668 |
| 4628 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4669 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4629 // Push the builtins object as the receiver. | 4670 // Push the builtins object as the receiver. |
| 4630 Register receiver = LoadDescriptor::ReceiverRegister(); | 4671 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 4631 __ ldr(receiver, GlobalObjectOperand()); | 4672 __ ldr(receiver, GlobalObjectOperand()); |
| 4632 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); | 4673 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); |
| 4633 __ push(receiver); | 4674 __ push(receiver); |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4816 } | 4857 } |
| 4817 | 4858 |
| 4818 | 4859 |
| 4819 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4860 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4820 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4861 DCHECK(expr->expression()->IsValidReferenceExpression()); |
| 4821 | 4862 |
| 4822 Comment cmnt(masm_, "[ CountOperation"); | 4863 Comment cmnt(masm_, "[ CountOperation"); |
| 4823 SetSourcePosition(expr->position()); | 4864 SetSourcePosition(expr->position()); |
| 4824 | 4865 |
| 4825 Property* prop = expr->expression()->AsProperty(); | 4866 Property* prop = expr->expression()->AsProperty(); |
| 4826 LhsKind assign_type = GetAssignType(prop); | 4867 LhsKind assign_type = Property::GetAssignType(prop); |
| 4827 | 4868 |
| 4828 // Evaluate expression and get value. | 4869 // Evaluate expression and get value. |
| 4829 if (assign_type == VARIABLE) { | 4870 if (assign_type == VARIABLE) { |
| 4830 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4871 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4831 AccumulatorValueContext context(this); | 4872 AccumulatorValueContext context(this); |
| 4832 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4873 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4833 } else { | 4874 } else { |
| 4834 // Reserve space for result of postfix operation. | 4875 // Reserve space for result of postfix operation. |
| 4835 if (expr->is_postfix() && !context()->IsEffect()) { | 4876 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4836 __ mov(ip, Operand(Smi::FromInt(0))); | 4877 __ mov(ip, Operand(Smi::FromInt(0))); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4981 CallIC(code, expr->CountBinOpFeedbackId()); | 5022 CallIC(code, expr->CountBinOpFeedbackId()); |
| 4982 patch_site.EmitPatchInfo(); | 5023 patch_site.EmitPatchInfo(); |
| 4983 __ bind(&done); | 5024 __ bind(&done); |
| 4984 | 5025 |
| 4985 // Store the value returned in r0. | 5026 // Store the value returned in r0. |
| 4986 switch (assign_type) { | 5027 switch (assign_type) { |
| 4987 case VARIABLE: | 5028 case VARIABLE: |
| 4988 if (expr->is_postfix()) { | 5029 if (expr->is_postfix()) { |
| 4989 { EffectContext context(this); | 5030 { EffectContext context(this); |
| 4990 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 5031 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4991 Token::ASSIGN); | 5032 Token::ASSIGN, expr->CountSlot()); |
| 4992 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5033 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4993 context.Plug(r0); | 5034 context.Plug(r0); |
| 4994 } | 5035 } |
| 4995 // For all contexts except EffectConstant We have the result on | 5036 // For all contexts except EffectConstant We have the result on |
| 4996 // top of the stack. | 5037 // top of the stack. |
| 4997 if (!context()->IsEffect()) { | 5038 if (!context()->IsEffect()) { |
| 4998 context()->PlugTOS(); | 5039 context()->PlugTOS(); |
| 4999 } | 5040 } |
| 5000 } else { | 5041 } else { |
| 5001 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 5042 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 5002 Token::ASSIGN); | 5043 Token::ASSIGN, expr->CountSlot()); |
| 5003 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5044 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 5004 context()->Plug(r0); | 5045 context()->Plug(r0); |
| 5005 } | 5046 } |
| 5006 break; | 5047 break; |
| 5007 case NAMED_PROPERTY: { | 5048 case NAMED_PROPERTY: { |
| 5008 __ mov(StoreDescriptor::NameRegister(), | 5049 __ mov(StoreDescriptor::NameRegister(), |
| 5009 Operand(prop->key()->AsLiteral()->value())); | 5050 Operand(prop->key()->AsLiteral()->value())); |
| 5010 __ pop(StoreDescriptor::ReceiverRegister()); | 5051 __ pop(StoreDescriptor::ReceiverRegister()); |
| 5011 CallStoreIC(expr->CountStoreFeedbackId()); | 5052 if (FLAG_vector_stores) { |
| 5053 EmitLoadStoreICSlot(expr->CountSlot()); |
| 5054 CallStoreIC(); |
| 5055 } else { |
| 5056 CallStoreIC(expr->CountStoreFeedbackId()); |
| 5057 } |
| 5012 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5058 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 5013 if (expr->is_postfix()) { | 5059 if (expr->is_postfix()) { |
| 5014 if (!context()->IsEffect()) { | 5060 if (!context()->IsEffect()) { |
| 5015 context()->PlugTOS(); | 5061 context()->PlugTOS(); |
| 5016 } | 5062 } |
| 5017 } else { | 5063 } else { |
| 5018 context()->Plug(r0); | 5064 context()->Plug(r0); |
| 5019 } | 5065 } |
| 5020 break; | 5066 break; |
| 5021 } | 5067 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 5039 } else { | 5085 } else { |
| 5040 context()->Plug(r0); | 5086 context()->Plug(r0); |
| 5041 } | 5087 } |
| 5042 break; | 5088 break; |
| 5043 } | 5089 } |
| 5044 case KEYED_PROPERTY: { | 5090 case KEYED_PROPERTY: { |
| 5045 __ Pop(StoreDescriptor::ReceiverRegister(), | 5091 __ Pop(StoreDescriptor::ReceiverRegister(), |
| 5046 StoreDescriptor::NameRegister()); | 5092 StoreDescriptor::NameRegister()); |
| 5047 Handle<Code> ic = | 5093 Handle<Code> ic = |
| 5048 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 5094 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 5049 CallIC(ic, expr->CountStoreFeedbackId()); | 5095 if (FLAG_vector_stores) { |
| 5096 EmitLoadStoreICSlot(expr->CountSlot()); |
| 5097 CallIC(ic); |
| 5098 } else { |
| 5099 CallIC(ic, expr->CountStoreFeedbackId()); |
| 5100 } |
| 5050 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5101 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 5051 if (expr->is_postfix()) { | 5102 if (expr->is_postfix()) { |
| 5052 if (!context()->IsEffect()) { | 5103 if (!context()->IsEffect()) { |
| 5053 context()->PlugTOS(); | 5104 context()->PlugTOS(); |
| 5054 } | 5105 } |
| 5055 } else { | 5106 } else { |
| 5056 context()->Plug(r0); | 5107 context()->Plug(r0); |
| 5057 } | 5108 } |
| 5058 break; | 5109 break; |
| 5059 } | 5110 } |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5374 void FullCodeGenerator::ClearPendingMessage() { | 5425 void FullCodeGenerator::ClearPendingMessage() { |
| 5375 DCHECK(!result_register().is(r1)); | 5426 DCHECK(!result_register().is(r1)); |
| 5376 ExternalReference pending_message_obj = | 5427 ExternalReference pending_message_obj = |
| 5377 ExternalReference::address_of_pending_message_obj(isolate()); | 5428 ExternalReference::address_of_pending_message_obj(isolate()); |
| 5378 __ LoadRoot(r1, Heap::kTheHoleValueRootIndex); | 5429 __ LoadRoot(r1, Heap::kTheHoleValueRootIndex); |
| 5379 __ mov(ip, Operand(pending_message_obj)); | 5430 __ mov(ip, Operand(pending_message_obj)); |
| 5380 __ str(r1, MemOperand(ip)); | 5431 __ str(r1, MemOperand(ip)); |
| 5381 } | 5432 } |
| 5382 | 5433 |
| 5383 | 5434 |
| 5435 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { |
| 5436 DCHECK(FLAG_vector_stores && !slot.IsInvalid()); |
| 5437 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), |
| 5438 Operand(SmiFromSlot(slot))); |
| 5439 } |
| 5440 |
| 5441 |
| 5384 #undef __ | 5442 #undef __ |
| 5385 | 5443 |
| 5386 | 5444 |
| 5387 static Address GetInterruptImmediateLoadAddress(Address pc) { | 5445 static Address GetInterruptImmediateLoadAddress(Address pc) { |
| 5388 Address load_address = pc - 2 * Assembler::kInstrSize; | 5446 Address load_address = pc - 2 * Assembler::kInstrSize; |
| 5389 if (!FLAG_enable_ool_constant_pool) { | 5447 if (!FLAG_enable_ool_constant_pool) { |
| 5390 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(load_address))); | 5448 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(load_address))); |
| 5391 } else if (Assembler::IsLdrPpRegOffset(Memory::int32_at(load_address))) { | 5449 } else if (Assembler::IsLdrPpRegOffset(Memory::int32_at(load_address))) { |
| 5392 // This is an extended constant pool lookup. | 5450 // This is an extended constant pool lookup. |
| 5393 if (CpuFeatures::IsSupported(ARMv7)) { | 5451 if (CpuFeatures::IsSupported(ARMv7)) { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5519 | 5577 |
| 5520 DCHECK(interrupt_address == | 5578 DCHECK(interrupt_address == |
| 5521 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5579 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 5522 return OSR_AFTER_STACK_CHECK; | 5580 return OSR_AFTER_STACK_CHECK; |
| 5523 } | 5581 } |
| 5524 | 5582 |
| 5525 | 5583 |
| 5526 } } // namespace v8::internal | 5584 } } // namespace v8::internal |
| 5527 | 5585 |
| 5528 #endif // V8_TARGET_ARCH_ARM | 5586 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |