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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
8 | 8 |
9 // Note on Mips implementation: | 9 // Note on Mips implementation: |
10 // | 10 // |
(...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1245 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); | 1245 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); |
1246 __ mov(a3, result_register()); | 1246 __ mov(a3, result_register()); |
1247 __ Branch(loop_statement.continue_label(), eq, a3, Operand(zero_reg)); | 1247 __ Branch(loop_statement.continue_label(), eq, a3, Operand(zero_reg)); |
1248 | 1248 |
1249 // Update the 'each' property or variable from the possibly filtered | 1249 // Update the 'each' property or variable from the possibly filtered |
1250 // entry in register a3. | 1250 // entry in register a3. |
1251 __ bind(&update_each); | 1251 __ bind(&update_each); |
1252 __ mov(result_register(), a3); | 1252 __ mov(result_register(), a3); |
1253 // Perform the assignment as if via '='. | 1253 // Perform the assignment as if via '='. |
1254 { EffectContext context(this); | 1254 { EffectContext context(this); |
1255 EmitAssignment(stmt->each()); | 1255 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
1256 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); | 1256 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); |
1257 } | 1257 } |
1258 | 1258 |
1259 // Generate code for the body of the loop. | 1259 // Generate code for the body of the loop. |
1260 Visit(stmt->body()); | 1260 Visit(stmt->body()); |
1261 | 1261 |
1262 // Generate code for the going to the next element by incrementing | 1262 // Generate code for the going to the next element by incrementing |
1263 // the index (smi) stored on top of the stack. | 1263 // the index (smi) stored on top of the stack. |
1264 __ bind(loop_statement.continue_label()); | 1264 __ bind(loop_statement.continue_label()); |
1265 __ pop(a0); | 1265 __ pop(a0); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1327 CallLoadIC(NOT_CONTEXTUAL); | 1327 CallLoadIC(NOT_CONTEXTUAL); |
1328 | 1328 |
1329 Label done; | 1329 Label done; |
1330 __ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value())); | 1330 __ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value())); |
1331 __ CallRuntime(Runtime::kThrowNonMethodError, 0); | 1331 __ CallRuntime(Runtime::kThrowNonMethodError, 0); |
1332 __ bind(&done); | 1332 __ bind(&done); |
1333 } | 1333 } |
1334 | 1334 |
1335 | 1335 |
1336 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1336 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
1337 int offset) { | 1337 int offset, |
| 1338 FeedbackVectorICSlot slot) { |
1338 if (NeedsHomeObject(initializer)) { | 1339 if (NeedsHomeObject(initializer)) { |
1339 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1340 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
1340 __ li(StoreDescriptor::NameRegister(), | 1341 __ li(StoreDescriptor::NameRegister(), |
1341 Operand(isolate()->factory()->home_object_symbol())); | 1342 Operand(isolate()->factory()->home_object_symbol())); |
1342 __ lw(StoreDescriptor::ValueRegister(), | 1343 __ lw(StoreDescriptor::ValueRegister(), |
1343 MemOperand(sp, offset * kPointerSize)); | 1344 MemOperand(sp, offset * kPointerSize)); |
| 1345 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
1344 CallStoreIC(); | 1346 CallStoreIC(); |
1345 } | 1347 } |
1346 } | 1348 } |
1347 | 1349 |
1348 | 1350 |
1349 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1351 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1350 TypeofState typeof_state, | 1352 TypeofState typeof_state, |
1351 Label* slow) { | 1353 Label* slow) { |
1352 Register current = cp; | 1354 Register current = cp; |
1353 Register next = a1; | 1355 Register next = a1; |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1656 __ CallStub(&stub); | 1658 __ CallStub(&stub); |
1657 } | 1659 } |
1658 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1660 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
1659 | 1661 |
1660 // If result_saved is true the result is on top of the stack. If | 1662 // If result_saved is true the result is on top of the stack. If |
1661 // result_saved is false the result is in v0. | 1663 // result_saved is false the result is in v0. |
1662 bool result_saved = false; | 1664 bool result_saved = false; |
1663 | 1665 |
1664 AccessorTable accessor_table(zone()); | 1666 AccessorTable accessor_table(zone()); |
1665 int property_index = 0; | 1667 int property_index = 0; |
| 1668 // store_slot_index points to the vector ic slot for the next store ic used. |
| 1669 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots |
| 1670 // and must be updated if the number of store ics emitted here changes. |
| 1671 int store_slot_index = 0; |
1666 for (; property_index < expr->properties()->length(); property_index++) { | 1672 for (; property_index < expr->properties()->length(); property_index++) { |
1667 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1673 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
1668 if (property->is_computed_name()) break; | 1674 if (property->is_computed_name()) break; |
1669 if (property->IsCompileTimeValue()) continue; | 1675 if (property->IsCompileTimeValue()) continue; |
1670 | 1676 |
1671 Literal* key = property->key()->AsLiteral(); | 1677 Literal* key = property->key()->AsLiteral(); |
1672 Expression* value = property->value(); | 1678 Expression* value = property->value(); |
1673 if (!result_saved) { | 1679 if (!result_saved) { |
1674 __ push(v0); // Save result on stack. | 1680 __ push(v0); // Save result on stack. |
1675 result_saved = true; | 1681 result_saved = true; |
1676 } | 1682 } |
1677 switch (property->kind()) { | 1683 switch (property->kind()) { |
1678 case ObjectLiteral::Property::CONSTANT: | 1684 case ObjectLiteral::Property::CONSTANT: |
1679 UNREACHABLE(); | 1685 UNREACHABLE(); |
1680 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1686 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1681 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1687 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
1682 // Fall through. | 1688 // Fall through. |
1683 case ObjectLiteral::Property::COMPUTED: | 1689 case ObjectLiteral::Property::COMPUTED: |
1684 // It is safe to use [[Put]] here because the boilerplate already | 1690 // It is safe to use [[Put]] here because the boilerplate already |
1685 // contains computed properties with an uninitialized value. | 1691 // contains computed properties with an uninitialized value. |
1686 if (key->value()->IsInternalizedString()) { | 1692 if (key->value()->IsInternalizedString()) { |
1687 if (property->emit_store()) { | 1693 if (property->emit_store()) { |
1688 VisitForAccumulatorValue(value); | 1694 VisitForAccumulatorValue(value); |
1689 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 1695 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
1690 DCHECK(StoreDescriptor::ValueRegister().is(a0)); | 1696 DCHECK(StoreDescriptor::ValueRegister().is(a0)); |
1691 __ li(StoreDescriptor::NameRegister(), Operand(key->value())); | 1697 __ li(StoreDescriptor::NameRegister(), Operand(key->value())); |
1692 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1698 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
1693 CallStoreIC(key->LiteralFeedbackId()); | 1699 if (FLAG_vector_stores) { |
| 1700 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1701 CallStoreIC(); |
| 1702 } else { |
| 1703 CallStoreIC(key->LiteralFeedbackId()); |
| 1704 } |
1694 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1705 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1695 | 1706 |
1696 if (NeedsHomeObject(value)) { | 1707 if (NeedsHomeObject(value)) { |
1697 __ Move(StoreDescriptor::ReceiverRegister(), v0); | 1708 __ Move(StoreDescriptor::ReceiverRegister(), v0); |
1698 __ li(StoreDescriptor::NameRegister(), | 1709 __ li(StoreDescriptor::NameRegister(), |
1699 Operand(isolate()->factory()->home_object_symbol())); | 1710 Operand(isolate()->factory()->home_object_symbol())); |
1700 __ lw(StoreDescriptor::ValueRegister(), MemOperand(sp)); | 1711 __ lw(StoreDescriptor::ValueRegister(), MemOperand(sp)); |
| 1712 if (FLAG_vector_stores) { |
| 1713 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1714 } |
1701 CallStoreIC(); | 1715 CallStoreIC(); |
1702 } | 1716 } |
1703 } else { | 1717 } else { |
1704 VisitForEffect(value); | 1718 VisitForEffect(value); |
1705 } | 1719 } |
1706 break; | 1720 break; |
1707 } | 1721 } |
1708 // Duplicate receiver on stack. | 1722 // Duplicate receiver on stack. |
1709 __ lw(a0, MemOperand(sp)); | 1723 __ lw(a0, MemOperand(sp)); |
1710 __ push(a0); | 1724 __ push(a0); |
1711 VisitForStackValue(key); | 1725 VisitForStackValue(key); |
1712 VisitForStackValue(value); | 1726 VisitForStackValue(value); |
1713 if (property->emit_store()) { | 1727 if (property->emit_store()) { |
1714 EmitSetHomeObjectIfNeeded(value, 2); | 1728 EmitSetHomeObjectIfNeeded( |
| 1729 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
1715 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. | 1730 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. |
1716 __ push(a0); | 1731 __ push(a0); |
1717 __ CallRuntime(Runtime::kSetProperty, 4); | 1732 __ CallRuntime(Runtime::kSetProperty, 4); |
1718 } else { | 1733 } else { |
1719 __ Drop(3); | 1734 __ Drop(3); |
1720 } | 1735 } |
1721 break; | 1736 break; |
1722 case ObjectLiteral::Property::PROTOTYPE: | 1737 case ObjectLiteral::Property::PROTOTYPE: |
1723 // Duplicate receiver on stack. | 1738 // Duplicate receiver on stack. |
1724 __ lw(a0, MemOperand(sp)); | 1739 __ lw(a0, MemOperand(sp)); |
(...skipping 17 matching lines...) Expand all Loading... |
1742 | 1757 |
1743 // Emit code to define accessors, using only a single call to the runtime for | 1758 // Emit code to define accessors, using only a single call to the runtime for |
1744 // each pair of corresponding getters and setters. | 1759 // each pair of corresponding getters and setters. |
1745 for (AccessorTable::Iterator it = accessor_table.begin(); | 1760 for (AccessorTable::Iterator it = accessor_table.begin(); |
1746 it != accessor_table.end(); | 1761 it != accessor_table.end(); |
1747 ++it) { | 1762 ++it) { |
1748 __ lw(a0, MemOperand(sp)); // Duplicate receiver. | 1763 __ lw(a0, MemOperand(sp)); // Duplicate receiver. |
1749 __ push(a0); | 1764 __ push(a0); |
1750 VisitForStackValue(it->first); | 1765 VisitForStackValue(it->first); |
1751 EmitAccessor(it->second->getter); | 1766 EmitAccessor(it->second->getter); |
1752 EmitSetHomeObjectIfNeeded(it->second->getter, 2); | 1767 EmitSetHomeObjectIfNeeded( |
| 1768 it->second->getter, 2, |
| 1769 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); |
1753 EmitAccessor(it->second->setter); | 1770 EmitAccessor(it->second->setter); |
1754 EmitSetHomeObjectIfNeeded(it->second->setter, 3); | 1771 EmitSetHomeObjectIfNeeded( |
| 1772 it->second->setter, 3, |
| 1773 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); |
1755 __ li(a0, Operand(Smi::FromInt(NONE))); | 1774 __ li(a0, Operand(Smi::FromInt(NONE))); |
1756 __ push(a0); | 1775 __ push(a0); |
1757 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1776 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
1758 } | 1777 } |
1759 | 1778 |
1760 // Object literals have two parts. The "static" part on the left contains no | 1779 // Object literals have two parts. The "static" part on the left contains no |
1761 // computed property names, and so we can compute its map ahead of time; see | 1780 // computed property names, and so we can compute its map ahead of time; see |
1762 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1781 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
1763 // starts with the first computed property name, and continues with all | 1782 // starts with the first computed property name, and continues with all |
1764 // properties to its right. All the code from above initializes the static | 1783 // properties to its right. All the code from above initializes the static |
(...skipping 14 matching lines...) Expand all Loading... |
1779 __ push(a0); | 1798 __ push(a0); |
1780 | 1799 |
1781 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1800 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
1782 DCHECK(!property->is_computed_name()); | 1801 DCHECK(!property->is_computed_name()); |
1783 VisitForStackValue(value); | 1802 VisitForStackValue(value); |
1784 DCHECK(property->emit_store()); | 1803 DCHECK(property->emit_store()); |
1785 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1804 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
1786 } else { | 1805 } else { |
1787 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1806 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
1788 VisitForStackValue(value); | 1807 VisitForStackValue(value); |
1789 EmitSetHomeObjectIfNeeded(value, 2); | 1808 EmitSetHomeObjectIfNeeded( |
| 1809 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
1790 | 1810 |
1791 switch (property->kind()) { | 1811 switch (property->kind()) { |
1792 case ObjectLiteral::Property::CONSTANT: | 1812 case ObjectLiteral::Property::CONSTANT: |
1793 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1813 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1794 case ObjectLiteral::Property::COMPUTED: | 1814 case ObjectLiteral::Property::COMPUTED: |
1795 if (property->emit_store()) { | 1815 if (property->emit_store()) { |
1796 __ li(a0, Operand(Smi::FromInt(NONE))); | 1816 __ li(a0, Operand(Smi::FromInt(NONE))); |
1797 __ push(a0); | 1817 __ push(a0); |
1798 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1818 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
1799 } else { | 1819 } else { |
(...skipping 25 matching lines...) Expand all Loading... |
1825 __ lw(a0, MemOperand(sp)); | 1845 __ lw(a0, MemOperand(sp)); |
1826 __ push(a0); | 1846 __ push(a0); |
1827 __ CallRuntime(Runtime::kToFastProperties, 1); | 1847 __ CallRuntime(Runtime::kToFastProperties, 1); |
1828 } | 1848 } |
1829 | 1849 |
1830 if (result_saved) { | 1850 if (result_saved) { |
1831 context()->PlugTOS(); | 1851 context()->PlugTOS(); |
1832 } else { | 1852 } else { |
1833 context()->Plug(v0); | 1853 context()->Plug(v0); |
1834 } | 1854 } |
| 1855 |
| 1856 // Verify that compilation exactly consumed the number of store ic slots that |
| 1857 // the ObjectLiteral node had to offer. |
| 1858 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); |
1835 } | 1859 } |
1836 | 1860 |
1837 | 1861 |
1838 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1862 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
1839 Comment cmnt(masm_, "[ ArrayLiteral"); | 1863 Comment cmnt(masm_, "[ ArrayLiteral"); |
1840 | 1864 |
1841 expr->BuildConstantElements(isolate()); | 1865 expr->BuildConstantElements(isolate()); |
1842 | 1866 |
1843 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1867 Handle<FixedArray> constant_elements = expr->constant_elements(); |
1844 bool has_fast_elements = | 1868 bool has_fast_elements = |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1941 } | 1965 } |
1942 } | 1966 } |
1943 | 1967 |
1944 | 1968 |
1945 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1969 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
1946 DCHECK(expr->target()->IsValidReferenceExpression()); | 1970 DCHECK(expr->target()->IsValidReferenceExpression()); |
1947 | 1971 |
1948 Comment cmnt(masm_, "[ Assignment"); | 1972 Comment cmnt(masm_, "[ Assignment"); |
1949 | 1973 |
1950 Property* property = expr->target()->AsProperty(); | 1974 Property* property = expr->target()->AsProperty(); |
1951 LhsKind assign_type = GetAssignType(property); | 1975 LhsKind assign_type = Property::GetAssignType(property); |
1952 | 1976 |
1953 // Evaluate LHS expression. | 1977 // Evaluate LHS expression. |
1954 switch (assign_type) { | 1978 switch (assign_type) { |
1955 case VARIABLE: | 1979 case VARIABLE: |
1956 // Nothing to do here. | 1980 // Nothing to do here. |
1957 break; | 1981 break; |
1958 case NAMED_PROPERTY: | 1982 case NAMED_PROPERTY: |
1959 if (expr->is_compound()) { | 1983 if (expr->is_compound()) { |
1960 // We need the receiver both on the stack and in the register. | 1984 // We need the receiver both on the stack and in the register. |
1961 VisitForStackValue(property->obj()); | 1985 VisitForStackValue(property->obj()); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2052 VisitForAccumulatorValue(expr->value()); | 2076 VisitForAccumulatorValue(expr->value()); |
2053 } | 2077 } |
2054 | 2078 |
2055 // Record source position before possible IC call. | 2079 // Record source position before possible IC call. |
2056 SetSourcePosition(expr->position()); | 2080 SetSourcePosition(expr->position()); |
2057 | 2081 |
2058 // Store the value. | 2082 // Store the value. |
2059 switch (assign_type) { | 2083 switch (assign_type) { |
2060 case VARIABLE: | 2084 case VARIABLE: |
2061 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2085 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
2062 expr->op()); | 2086 expr->op(), expr->AssignmentSlot()); |
2063 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2087 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2064 context()->Plug(v0); | 2088 context()->Plug(v0); |
2065 break; | 2089 break; |
2066 case NAMED_PROPERTY: | 2090 case NAMED_PROPERTY: |
2067 EmitNamedPropertyAssignment(expr); | 2091 EmitNamedPropertyAssignment(expr); |
2068 break; | 2092 break; |
2069 case NAMED_SUPER_PROPERTY: | 2093 case NAMED_SUPER_PROPERTY: |
2070 EmitNamedSuperPropertyStore(property); | 2094 EmitNamedSuperPropertyStore(property); |
2071 context()->Plug(v0); | 2095 context()->Plug(v0); |
2072 break; | 2096 break; |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2577 __ pop(a1); | 2601 __ pop(a1); |
2578 Handle<Code> code = CodeFactory::BinaryOpIC( | 2602 Handle<Code> code = CodeFactory::BinaryOpIC( |
2579 isolate(), op, language_mode()).code(); | 2603 isolate(), op, language_mode()).code(); |
2580 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2604 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
2581 CallIC(code, expr->BinaryOperationFeedbackId()); | 2605 CallIC(code, expr->BinaryOperationFeedbackId()); |
2582 patch_site.EmitPatchInfo(); | 2606 patch_site.EmitPatchInfo(); |
2583 context()->Plug(v0); | 2607 context()->Plug(v0); |
2584 } | 2608 } |
2585 | 2609 |
2586 | 2610 |
2587 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2611 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 2612 FeedbackVectorICSlot slot) { |
2588 DCHECK(expr->IsValidReferenceExpression()); | 2613 DCHECK(expr->IsValidReferenceExpression()); |
2589 | 2614 |
2590 Property* prop = expr->AsProperty(); | 2615 Property* prop = expr->AsProperty(); |
2591 LhsKind assign_type = GetAssignType(prop); | 2616 LhsKind assign_type = Property::GetAssignType(prop); |
2592 | 2617 |
2593 switch (assign_type) { | 2618 switch (assign_type) { |
2594 case VARIABLE: { | 2619 case VARIABLE: { |
2595 Variable* var = expr->AsVariableProxy()->var(); | 2620 Variable* var = expr->AsVariableProxy()->var(); |
2596 EffectContext context(this); | 2621 EffectContext context(this); |
2597 EmitVariableAssignment(var, Token::ASSIGN); | 2622 EmitVariableAssignment(var, Token::ASSIGN, slot); |
2598 break; | 2623 break; |
2599 } | 2624 } |
2600 case NAMED_PROPERTY: { | 2625 case NAMED_PROPERTY: { |
2601 __ push(result_register()); // Preserve value. | 2626 __ push(result_register()); // Preserve value. |
2602 VisitForAccumulatorValue(prop->obj()); | 2627 VisitForAccumulatorValue(prop->obj()); |
2603 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); | 2628 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); |
2604 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2629 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
2605 __ li(StoreDescriptor::NameRegister(), | 2630 __ li(StoreDescriptor::NameRegister(), |
2606 Operand(prop->key()->AsLiteral()->value())); | 2631 Operand(prop->key()->AsLiteral()->value())); |
| 2632 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
2607 CallStoreIC(); | 2633 CallStoreIC(); |
2608 break; | 2634 break; |
2609 } | 2635 } |
2610 case NAMED_SUPER_PROPERTY: { | 2636 case NAMED_SUPER_PROPERTY: { |
2611 __ Push(v0); | 2637 __ Push(v0); |
2612 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 2638 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
2613 EmitLoadHomeObject(prop->obj()->AsSuperReference()); | 2639 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
2614 // stack: value, this; v0: home_object | 2640 // stack: value, this; v0: home_object |
2615 Register scratch = a2; | 2641 Register scratch = a2; |
2616 Register scratch2 = a3; | 2642 Register scratch2 = a3; |
(...skipping 26 matching lines...) Expand all Loading... |
2643 EmitKeyedSuperPropertyStore(prop); | 2669 EmitKeyedSuperPropertyStore(prop); |
2644 break; | 2670 break; |
2645 } | 2671 } |
2646 case KEYED_PROPERTY: { | 2672 case KEYED_PROPERTY: { |
2647 __ push(result_register()); // Preserve value. | 2673 __ push(result_register()); // Preserve value. |
2648 VisitForStackValue(prop->obj()); | 2674 VisitForStackValue(prop->obj()); |
2649 VisitForAccumulatorValue(prop->key()); | 2675 VisitForAccumulatorValue(prop->key()); |
2650 __ mov(StoreDescriptor::NameRegister(), result_register()); | 2676 __ mov(StoreDescriptor::NameRegister(), result_register()); |
2651 __ Pop(StoreDescriptor::ValueRegister(), | 2677 __ Pop(StoreDescriptor::ValueRegister(), |
2652 StoreDescriptor::ReceiverRegister()); | 2678 StoreDescriptor::ReceiverRegister()); |
| 2679 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
2653 Handle<Code> ic = | 2680 Handle<Code> ic = |
2654 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2681 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2655 CallIC(ic); | 2682 CallIC(ic); |
2656 break; | 2683 break; |
2657 } | 2684 } |
2658 } | 2685 } |
2659 context()->Plug(v0); | 2686 context()->Plug(v0); |
2660 } | 2687 } |
2661 | 2688 |
2662 | 2689 |
2663 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2690 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
2664 Variable* var, MemOperand location) { | 2691 Variable* var, MemOperand location) { |
2665 __ sw(result_register(), location); | 2692 __ sw(result_register(), location); |
2666 if (var->IsContextSlot()) { | 2693 if (var->IsContextSlot()) { |
2667 // RecordWrite may destroy all its register arguments. | 2694 // RecordWrite may destroy all its register arguments. |
2668 __ Move(a3, result_register()); | 2695 __ Move(a3, result_register()); |
2669 int offset = Context::SlotOffset(var->index()); | 2696 int offset = Context::SlotOffset(var->index()); |
2670 __ RecordWriteContextSlot( | 2697 __ RecordWriteContextSlot( |
2671 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); | 2698 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); |
2672 } | 2699 } |
2673 } | 2700 } |
2674 | 2701 |
2675 | 2702 |
2676 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { | 2703 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2704 FeedbackVectorICSlot slot) { |
2677 if (var->IsUnallocated()) { | 2705 if (var->IsUnallocated()) { |
2678 // Global var, const, or let. | 2706 // Global var, const, or let. |
2679 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2707 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
2680 __ li(StoreDescriptor::NameRegister(), Operand(var->name())); | 2708 __ li(StoreDescriptor::NameRegister(), Operand(var->name())); |
2681 __ lw(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2709 __ lw(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2710 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
2682 CallStoreIC(); | 2711 CallStoreIC(); |
2683 | 2712 |
2684 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2713 } else if (var->mode() == LET && op != Token::INIT_LET) { |
2685 // Non-initializing assignment to let variable needs a write barrier. | 2714 // Non-initializing assignment to let variable needs a write barrier. |
2686 DCHECK(!var->IsLookupSlot()); | 2715 DCHECK(!var->IsLookupSlot()); |
2687 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2716 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
2688 Label assign; | 2717 Label assign; |
2689 MemOperand location = VarOperand(var, a1); | 2718 MemOperand location = VarOperand(var, a1); |
2690 __ lw(a3, location); | 2719 __ lw(a3, location); |
2691 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); | 2720 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2766 Property* prop = expr->target()->AsProperty(); | 2795 Property* prop = expr->target()->AsProperty(); |
2767 DCHECK(prop != NULL); | 2796 DCHECK(prop != NULL); |
2768 DCHECK(prop->key()->IsLiteral()); | 2797 DCHECK(prop->key()->IsLiteral()); |
2769 | 2798 |
2770 // Record source code position before IC call. | 2799 // Record source code position before IC call. |
2771 SetSourcePosition(expr->position()); | 2800 SetSourcePosition(expr->position()); |
2772 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2801 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
2773 __ li(StoreDescriptor::NameRegister(), | 2802 __ li(StoreDescriptor::NameRegister(), |
2774 Operand(prop->key()->AsLiteral()->value())); | 2803 Operand(prop->key()->AsLiteral()->value())); |
2775 __ pop(StoreDescriptor::ReceiverRegister()); | 2804 __ pop(StoreDescriptor::ReceiverRegister()); |
2776 CallStoreIC(expr->AssignmentFeedbackId()); | 2805 if (FLAG_vector_stores) { |
| 2806 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2807 CallStoreIC(); |
| 2808 } else { |
| 2809 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2810 } |
2777 | 2811 |
2778 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2812 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2779 context()->Plug(v0); | 2813 context()->Plug(v0); |
2780 } | 2814 } |
2781 | 2815 |
2782 | 2816 |
2783 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2817 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
2784 // Assignment to named property of super. | 2818 // Assignment to named property of super. |
2785 // v0 : value | 2819 // v0 : value |
2786 // stack : receiver ('this'), home_object | 2820 // stack : receiver ('this'), home_object |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2819 // The arguments are: | 2853 // The arguments are: |
2820 // - a0 is the value, | 2854 // - a0 is the value, |
2821 // - a1 is the key, | 2855 // - a1 is the key, |
2822 // - a2 is the receiver. | 2856 // - a2 is the receiver. |
2823 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2857 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
2824 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); | 2858 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); |
2825 DCHECK(StoreDescriptor::ValueRegister().is(a0)); | 2859 DCHECK(StoreDescriptor::ValueRegister().is(a0)); |
2826 | 2860 |
2827 Handle<Code> ic = | 2861 Handle<Code> ic = |
2828 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2862 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
2829 CallIC(ic, expr->AssignmentFeedbackId()); | 2863 if (FLAG_vector_stores) { |
| 2864 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2865 CallIC(ic); |
| 2866 } else { |
| 2867 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2868 } |
2830 | 2869 |
2831 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2870 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2832 context()->Plug(v0); | 2871 context()->Plug(v0); |
2833 } | 2872 } |
2834 | 2873 |
2835 | 2874 |
2836 void FullCodeGenerator::VisitProperty(Property* expr) { | 2875 void FullCodeGenerator::VisitProperty(Property* expr) { |
2837 Comment cmnt(masm_, "[ Property"); | 2876 Comment cmnt(masm_, "[ Property"); |
2838 Expression* key = expr->key(); | 2877 Expression* key = expr->key(); |
2839 | 2878 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3059 | 3098 |
3060 | 3099 |
3061 void FullCodeGenerator::EmitLoadSuperConstructor() { | 3100 void FullCodeGenerator::EmitLoadSuperConstructor() { |
3062 __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 3101 __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
3063 __ Push(a0); | 3102 __ Push(a0); |
3064 __ CallRuntime(Runtime::kGetPrototype, 1); | 3103 __ CallRuntime(Runtime::kGetPrototype, 1); |
3065 } | 3104 } |
3066 | 3105 |
3067 | 3106 |
3068 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3107 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
3069 SuperReference* super_ref) { | 3108 SuperReference* super_ref, FeedbackVectorICSlot slot) { |
3070 Variable* this_var = super_ref->this_var()->var(); | 3109 Variable* this_var = super_ref->this_var()->var(); |
3071 GetVar(a1, this_var); | 3110 GetVar(a1, this_var); |
3072 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 3111 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
3073 Label uninitialized_this; | 3112 Label uninitialized_this; |
3074 __ Branch(&uninitialized_this, eq, a1, Operand(at)); | 3113 __ Branch(&uninitialized_this, eq, a1, Operand(at)); |
3075 __ li(a0, Operand(this_var->name())); | 3114 __ li(a0, Operand(this_var->name())); |
3076 __ Push(a0); | 3115 __ Push(a0); |
3077 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3116 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
3078 __ bind(&uninitialized_this); | 3117 __ bind(&uninitialized_this); |
3079 | 3118 |
3080 EmitVariableAssignment(this_var, Token::INIT_CONST); | 3119 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
3081 } | 3120 } |
3082 | 3121 |
3083 | 3122 |
3084 void FullCodeGenerator::VisitCall(Call* expr) { | 3123 void FullCodeGenerator::VisitCall(Call* expr) { |
3085 #ifdef DEBUG | 3124 #ifdef DEBUG |
3086 // We want to verify that RecordJSReturnSite gets called on all paths | 3125 // We want to verify that RecordJSReturnSite gets called on all paths |
3087 // through this function. Avoid early returns. | 3126 // through this function. Avoid early returns. |
3088 expr->return_is_recorded_ = false; | 3127 expr->return_is_recorded_ = false; |
3089 #endif | 3128 #endif |
3090 | 3129 |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3295 __ li(a2, FeedbackVector()); | 3334 __ li(a2, FeedbackVector()); |
3296 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); | 3335 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); |
3297 | 3336 |
3298 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3337 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
3299 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3338 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
3300 | 3339 |
3301 __ Drop(1); | 3340 __ Drop(1); |
3302 | 3341 |
3303 RecordJSReturnSite(expr); | 3342 RecordJSReturnSite(expr); |
3304 | 3343 |
3305 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); | 3344 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), |
| 3345 expr->CallFeedbackICSlot()); |
3306 context()->Plug(v0); | 3346 context()->Plug(v0); |
3307 } | 3347 } |
3308 | 3348 |
3309 | 3349 |
3310 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3350 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
3311 ZoneList<Expression*>* args = expr->arguments(); | 3351 ZoneList<Expression*>* args = expr->arguments(); |
3312 DCHECK(args->length() == 1); | 3352 DCHECK(args->length() == 1); |
3313 | 3353 |
3314 VisitForAccumulatorValue(args->at(0)); | 3354 VisitForAccumulatorValue(args->at(0)); |
3315 | 3355 |
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4618 // Push NewTarget | 4658 // Push NewTarget |
4619 DCHECK(args->at(2)->IsVariableProxy()); | 4659 DCHECK(args->at(2)->IsVariableProxy()); |
4620 VisitForStackValue(args->at(2)); | 4660 VisitForStackValue(args->at(2)); |
4621 | 4661 |
4622 EmitCallJSRuntimeFunction(call); | 4662 EmitCallJSRuntimeFunction(call); |
4623 | 4663 |
4624 // Restore context register. | 4664 // Restore context register. |
4625 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4665 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
4626 context()->DropAndPlug(1, v0); | 4666 context()->DropAndPlug(1, v0); |
4627 | 4667 |
| 4668 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
4628 EmitInitializeThisAfterSuper(super_reference); | 4669 EmitInitializeThisAfterSuper(super_reference); |
4629 } | 4670 } |
4630 | 4671 |
4631 | 4672 |
4632 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4673 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
4633 // Push the builtins object as the receiver. | 4674 // Push the builtins object as the receiver. |
4634 Register receiver = LoadDescriptor::ReceiverRegister(); | 4675 Register receiver = LoadDescriptor::ReceiverRegister(); |
4635 __ lw(receiver, GlobalObjectOperand()); | 4676 __ lw(receiver, GlobalObjectOperand()); |
4636 __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); | 4677 __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); |
4637 __ push(receiver); | 4678 __ push(receiver); |
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4820 } | 4861 } |
4821 | 4862 |
4822 | 4863 |
4823 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4864 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
4824 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4865 DCHECK(expr->expression()->IsValidReferenceExpression()); |
4825 | 4866 |
4826 Comment cmnt(masm_, "[ CountOperation"); | 4867 Comment cmnt(masm_, "[ CountOperation"); |
4827 SetSourcePosition(expr->position()); | 4868 SetSourcePosition(expr->position()); |
4828 | 4869 |
4829 Property* prop = expr->expression()->AsProperty(); | 4870 Property* prop = expr->expression()->AsProperty(); |
4830 LhsKind assign_type = GetAssignType(prop); | 4871 LhsKind assign_type = Property::GetAssignType(prop); |
4831 | 4872 |
4832 // Evaluate expression and get value. | 4873 // Evaluate expression and get value. |
4833 if (assign_type == VARIABLE) { | 4874 if (assign_type == VARIABLE) { |
4834 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4875 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
4835 AccumulatorValueContext context(this); | 4876 AccumulatorValueContext context(this); |
4836 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4877 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4837 } else { | 4878 } else { |
4838 // Reserve space for result of postfix operation. | 4879 // Reserve space for result of postfix operation. |
4839 if (expr->is_postfix() && !context()->IsEffect()) { | 4880 if (expr->is_postfix() && !context()->IsEffect()) { |
4840 __ li(at, Operand(Smi::FromInt(0))); | 4881 __ li(at, Operand(Smi::FromInt(0))); |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4985 CallIC(code, expr->CountBinOpFeedbackId()); | 5026 CallIC(code, expr->CountBinOpFeedbackId()); |
4986 patch_site.EmitPatchInfo(); | 5027 patch_site.EmitPatchInfo(); |
4987 __ bind(&done); | 5028 __ bind(&done); |
4988 | 5029 |
4989 // Store the value returned in v0. | 5030 // Store the value returned in v0. |
4990 switch (assign_type) { | 5031 switch (assign_type) { |
4991 case VARIABLE: | 5032 case VARIABLE: |
4992 if (expr->is_postfix()) { | 5033 if (expr->is_postfix()) { |
4993 { EffectContext context(this); | 5034 { EffectContext context(this); |
4994 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 5035 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
4995 Token::ASSIGN); | 5036 Token::ASSIGN, expr->CountSlot()); |
4996 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5037 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4997 context.Plug(v0); | 5038 context.Plug(v0); |
4998 } | 5039 } |
4999 // For all contexts except EffectConstant we have the result on | 5040 // For all contexts except EffectConstant we have the result on |
5000 // top of the stack. | 5041 // top of the stack. |
5001 if (!context()->IsEffect()) { | 5042 if (!context()->IsEffect()) { |
5002 context()->PlugTOS(); | 5043 context()->PlugTOS(); |
5003 } | 5044 } |
5004 } else { | 5045 } else { |
5005 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 5046 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
5006 Token::ASSIGN); | 5047 Token::ASSIGN, expr->CountSlot()); |
5007 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5048 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
5008 context()->Plug(v0); | 5049 context()->Plug(v0); |
5009 } | 5050 } |
5010 break; | 5051 break; |
5011 case NAMED_PROPERTY: { | 5052 case NAMED_PROPERTY: { |
5012 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 5053 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
5013 __ li(StoreDescriptor::NameRegister(), | 5054 __ li(StoreDescriptor::NameRegister(), |
5014 Operand(prop->key()->AsLiteral()->value())); | 5055 Operand(prop->key()->AsLiteral()->value())); |
5015 __ pop(StoreDescriptor::ReceiverRegister()); | 5056 __ pop(StoreDescriptor::ReceiverRegister()); |
5016 CallStoreIC(expr->CountStoreFeedbackId()); | 5057 if (FLAG_vector_stores) { |
| 5058 EmitLoadStoreICSlot(expr->CountSlot()); |
| 5059 CallStoreIC(); |
| 5060 } else { |
| 5061 CallStoreIC(expr->CountStoreFeedbackId()); |
| 5062 } |
5017 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5063 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
5018 if (expr->is_postfix()) { | 5064 if (expr->is_postfix()) { |
5019 if (!context()->IsEffect()) { | 5065 if (!context()->IsEffect()) { |
5020 context()->PlugTOS(); | 5066 context()->PlugTOS(); |
5021 } | 5067 } |
5022 } else { | 5068 } else { |
5023 context()->Plug(v0); | 5069 context()->Plug(v0); |
5024 } | 5070 } |
5025 break; | 5071 break; |
5026 } | 5072 } |
(...skipping 18 matching lines...) Expand all Loading... |
5045 context()->Plug(v0); | 5091 context()->Plug(v0); |
5046 } | 5092 } |
5047 break; | 5093 break; |
5048 } | 5094 } |
5049 case KEYED_PROPERTY: { | 5095 case KEYED_PROPERTY: { |
5050 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 5096 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
5051 __ Pop(StoreDescriptor::ReceiverRegister(), | 5097 __ Pop(StoreDescriptor::ReceiverRegister(), |
5052 StoreDescriptor::NameRegister()); | 5098 StoreDescriptor::NameRegister()); |
5053 Handle<Code> ic = | 5099 Handle<Code> ic = |
5054 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 5100 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
5055 CallIC(ic, expr->CountStoreFeedbackId()); | 5101 if (FLAG_vector_stores) { |
| 5102 EmitLoadStoreICSlot(expr->CountSlot()); |
| 5103 CallIC(ic); |
| 5104 } else { |
| 5105 CallIC(ic, expr->CountStoreFeedbackId()); |
| 5106 } |
5056 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5107 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
5057 if (expr->is_postfix()) { | 5108 if (expr->is_postfix()) { |
5058 if (!context()->IsEffect()) { | 5109 if (!context()->IsEffect()) { |
5059 context()->PlugTOS(); | 5110 context()->PlugTOS(); |
5060 } | 5111 } |
5061 } else { | 5112 } else { |
5062 context()->Plug(v0); | 5113 context()->Plug(v0); |
5063 } | 5114 } |
5064 break; | 5115 break; |
5065 } | 5116 } |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5377 void FullCodeGenerator::ClearPendingMessage() { | 5428 void FullCodeGenerator::ClearPendingMessage() { |
5378 DCHECK(!result_register().is(a1)); | 5429 DCHECK(!result_register().is(a1)); |
5379 ExternalReference pending_message_obj = | 5430 ExternalReference pending_message_obj = |
5380 ExternalReference::address_of_pending_message_obj(isolate()); | 5431 ExternalReference::address_of_pending_message_obj(isolate()); |
5381 __ LoadRoot(a1, Heap::kTheHoleValueRootIndex); | 5432 __ LoadRoot(a1, Heap::kTheHoleValueRootIndex); |
5382 __ li(at, Operand(pending_message_obj)); | 5433 __ li(at, Operand(pending_message_obj)); |
5383 __ sw(a1, MemOperand(at)); | 5434 __ sw(a1, MemOperand(at)); |
5384 } | 5435 } |
5385 | 5436 |
5386 | 5437 |
| 5438 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { |
| 5439 DCHECK(FLAG_vector_stores && !slot.IsInvalid()); |
| 5440 __ li(VectorStoreICTrampolineDescriptor::SlotRegister(), |
| 5441 Operand(SmiFromSlot(slot))); |
| 5442 } |
| 5443 |
| 5444 |
5387 #undef __ | 5445 #undef __ |
5388 | 5446 |
5389 | 5447 |
5390 void BackEdgeTable::PatchAt(Code* unoptimized_code, | 5448 void BackEdgeTable::PatchAt(Code* unoptimized_code, |
5391 Address pc, | 5449 Address pc, |
5392 BackEdgeState target_state, | 5450 BackEdgeState target_state, |
5393 Code* replacement_code) { | 5451 Code* replacement_code) { |
5394 static const int kInstrSize = Assembler::kInstrSize; | 5452 static const int kInstrSize = Assembler::kInstrSize; |
5395 Address branch_address = pc - 6 * kInstrSize; | 5453 Address branch_address = pc - 6 * kInstrSize; |
5396 CodePatcher patcher(branch_address, 1); | 5454 CodePatcher patcher(branch_address, 1); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5459 Assembler::target_address_at(pc_immediate_load_address)) == | 5517 Assembler::target_address_at(pc_immediate_load_address)) == |
5460 reinterpret_cast<uint32_t>( | 5518 reinterpret_cast<uint32_t>( |
5461 isolate->builtins()->OsrAfterStackCheck()->entry())); | 5519 isolate->builtins()->OsrAfterStackCheck()->entry())); |
5462 return OSR_AFTER_STACK_CHECK; | 5520 return OSR_AFTER_STACK_CHECK; |
5463 } | 5521 } |
5464 | 5522 |
5465 | 5523 |
5466 } } // namespace v8::internal | 5524 } } // namespace v8::internal |
5467 | 5525 |
5468 #endif // V8_TARGET_ARCH_MIPS | 5526 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |