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