| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_PPC | 7 #if V8_TARGET_ARCH_PPC |
| 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 1209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1220 __ cmpi(r6, Operand::Zero()); | 1220 __ cmpi(r6, Operand::Zero()); |
| 1221 __ beq(loop_statement.continue_label()); | 1221 __ beq(loop_statement.continue_label()); |
| 1222 | 1222 |
| 1223 // Update the 'each' property or variable from the possibly filtered | 1223 // Update the 'each' property or variable from the possibly filtered |
| 1224 // entry in register r6. | 1224 // entry in register r6. |
| 1225 __ bind(&update_each); | 1225 __ bind(&update_each); |
| 1226 __ mr(result_register(), r6); | 1226 __ mr(result_register(), r6); |
| 1227 // Perform the assignment as if via '='. | 1227 // Perform the assignment as if via '='. |
| 1228 { | 1228 { |
| 1229 EffectContext context(this); | 1229 EffectContext context(this); |
| 1230 EmitAssignment(stmt->each()); | 1230 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
| 1231 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); | 1231 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); |
| 1232 } | 1232 } |
| 1233 | 1233 |
| 1234 // Generate code for the body of the loop. | 1234 // Generate code for the body of the loop. |
| 1235 Visit(stmt->body()); | 1235 Visit(stmt->body()); |
| 1236 | 1236 |
| 1237 // Generate code for the going to the next element by incrementing | 1237 // Generate code for the going to the next element by incrementing |
| 1238 // the index (smi) stored on top of the stack. | 1238 // the index (smi) stored on top of the stack. |
| 1239 __ bind(loop_statement.continue_label()); | 1239 __ bind(loop_statement.continue_label()); |
| 1240 __ pop(r3); | 1240 __ pop(r3); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 | 1300 |
| 1301 __ Cmpi(r3, Operand(isolate()->factory()->undefined_value()), r0); | 1301 __ Cmpi(r3, Operand(isolate()->factory()->undefined_value()), r0); |
| 1302 Label done; | 1302 Label done; |
| 1303 __ bne(&done); | 1303 __ bne(&done); |
| 1304 __ CallRuntime(Runtime::kThrowNonMethodError, 0); | 1304 __ CallRuntime(Runtime::kThrowNonMethodError, 0); |
| 1305 __ bind(&done); | 1305 __ bind(&done); |
| 1306 } | 1306 } |
| 1307 | 1307 |
| 1308 | 1308 |
| 1309 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1309 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1310 int offset) { | 1310 int offset, |
| 1311 FeedbackVectorICSlot slot) { |
| 1311 if (NeedsHomeObject(initializer)) { | 1312 if (NeedsHomeObject(initializer)) { |
| 1312 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1313 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
| 1313 __ mov(StoreDescriptor::NameRegister(), | 1314 __ mov(StoreDescriptor::NameRegister(), |
| 1314 Operand(isolate()->factory()->home_object_symbol())); | 1315 Operand(isolate()->factory()->home_object_symbol())); |
| 1315 __ LoadP(StoreDescriptor::ValueRegister(), | 1316 __ LoadP(StoreDescriptor::ValueRegister(), |
| 1316 MemOperand(sp, offset * kPointerSize)); | 1317 MemOperand(sp, offset * kPointerSize)); |
| 1318 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1317 CallStoreIC(); | 1319 CallStoreIC(); |
| 1318 } | 1320 } |
| 1319 } | 1321 } |
| 1320 | 1322 |
| 1321 | 1323 |
| 1322 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1324 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1323 TypeofState typeof_state, | 1325 TypeofState typeof_state, |
| 1324 Label* slow) { | 1326 Label* slow) { |
| 1325 Register current = cp; | 1327 Register current = cp; |
| 1326 Register next = r4; | 1328 Register next = r4; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1629 __ CallStub(&stub); | 1631 __ CallStub(&stub); |
| 1630 } | 1632 } |
| 1631 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1633 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1632 | 1634 |
| 1633 // If result_saved is true the result is on top of the stack. If | 1635 // If result_saved is true the result is on top of the stack. If |
| 1634 // result_saved is false the result is in r3. | 1636 // result_saved is false the result is in r3. |
| 1635 bool result_saved = false; | 1637 bool result_saved = false; |
| 1636 | 1638 |
| 1637 AccessorTable accessor_table(zone()); | 1639 AccessorTable accessor_table(zone()); |
| 1638 int property_index = 0; | 1640 int property_index = 0; |
| 1641 // store_slot_index points to the vector ic slot for the next store ic used. |
| 1642 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots |
| 1643 // and must be updated if the number of store ics emitted here changes. |
| 1644 int store_slot_index = 0; |
| 1639 for (; property_index < expr->properties()->length(); property_index++) { | 1645 for (; property_index < expr->properties()->length(); property_index++) { |
| 1640 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1646 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1641 if (property->is_computed_name()) break; | 1647 if (property->is_computed_name()) break; |
| 1642 if (property->IsCompileTimeValue()) continue; | 1648 if (property->IsCompileTimeValue()) continue; |
| 1643 | 1649 |
| 1644 Literal* key = property->key()->AsLiteral(); | 1650 Literal* key = property->key()->AsLiteral(); |
| 1645 Expression* value = property->value(); | 1651 Expression* value = property->value(); |
| 1646 if (!result_saved) { | 1652 if (!result_saved) { |
| 1647 __ push(r3); // Save result on stack | 1653 __ push(r3); // Save result on stack |
| 1648 result_saved = true; | 1654 result_saved = true; |
| 1649 } | 1655 } |
| 1650 switch (property->kind()) { | 1656 switch (property->kind()) { |
| 1651 case ObjectLiteral::Property::CONSTANT: | 1657 case ObjectLiteral::Property::CONSTANT: |
| 1652 UNREACHABLE(); | 1658 UNREACHABLE(); |
| 1653 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1659 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1654 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1660 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1655 // Fall through. | 1661 // Fall through. |
| 1656 case ObjectLiteral::Property::COMPUTED: | 1662 case ObjectLiteral::Property::COMPUTED: |
| 1657 // It is safe to use [[Put]] here because the boilerplate already | 1663 // It is safe to use [[Put]] here because the boilerplate already |
| 1658 // contains computed properties with an uninitialized value. | 1664 // contains computed properties with an uninitialized value. |
| 1659 if (key->value()->IsInternalizedString()) { | 1665 if (key->value()->IsInternalizedString()) { |
| 1660 if (property->emit_store()) { | 1666 if (property->emit_store()) { |
| 1661 VisitForAccumulatorValue(value); | 1667 VisitForAccumulatorValue(value); |
| 1662 DCHECK(StoreDescriptor::ValueRegister().is(r3)); | 1668 DCHECK(StoreDescriptor::ValueRegister().is(r3)); |
| 1663 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); | 1669 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); |
| 1664 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); | 1670 __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); |
| 1665 CallStoreIC(key->LiteralFeedbackId()); | 1671 if (FLAG_vector_stores) { |
| 1672 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1673 CallStoreIC(); |
| 1674 } else { |
| 1675 CallStoreIC(key->LiteralFeedbackId()); |
| 1676 } |
| 1666 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1677 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1667 | 1678 |
| 1668 if (NeedsHomeObject(value)) { | 1679 if (NeedsHomeObject(value)) { |
| 1669 __ Move(StoreDescriptor::ReceiverRegister(), r3); | 1680 __ Move(StoreDescriptor::ReceiverRegister(), r3); |
| 1670 __ mov(StoreDescriptor::NameRegister(), | 1681 __ mov(StoreDescriptor::NameRegister(), |
| 1671 Operand(isolate()->factory()->home_object_symbol())); | 1682 Operand(isolate()->factory()->home_object_symbol())); |
| 1672 __ LoadP(StoreDescriptor::ValueRegister(), MemOperand(sp)); | 1683 __ LoadP(StoreDescriptor::ValueRegister(), MemOperand(sp)); |
| 1684 if (FLAG_vector_stores) { |
| 1685 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1686 } |
| 1673 CallStoreIC(); | 1687 CallStoreIC(); |
| 1674 } | 1688 } |
| 1675 } else { | 1689 } else { |
| 1676 VisitForEffect(value); | 1690 VisitForEffect(value); |
| 1677 } | 1691 } |
| 1678 break; | 1692 break; |
| 1679 } | 1693 } |
| 1680 // Duplicate receiver on stack. | 1694 // Duplicate receiver on stack. |
| 1681 __ LoadP(r3, MemOperand(sp)); | 1695 __ LoadP(r3, MemOperand(sp)); |
| 1682 __ push(r3); | 1696 __ push(r3); |
| 1683 VisitForStackValue(key); | 1697 VisitForStackValue(key); |
| 1684 VisitForStackValue(value); | 1698 VisitForStackValue(value); |
| 1685 if (property->emit_store()) { | 1699 if (property->emit_store()) { |
| 1686 EmitSetHomeObjectIfNeeded(value, 2); | 1700 EmitSetHomeObjectIfNeeded( |
| 1701 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1687 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes | 1702 __ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes |
| 1688 __ push(r3); | 1703 __ push(r3); |
| 1689 __ CallRuntime(Runtime::kSetProperty, 4); | 1704 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1690 } else { | 1705 } else { |
| 1691 __ Drop(3); | 1706 __ Drop(3); |
| 1692 } | 1707 } |
| 1693 break; | 1708 break; |
| 1694 case ObjectLiteral::Property::PROTOTYPE: | 1709 case ObjectLiteral::Property::PROTOTYPE: |
| 1695 // Duplicate receiver on stack. | 1710 // Duplicate receiver on stack. |
| 1696 __ LoadP(r3, MemOperand(sp)); | 1711 __ LoadP(r3, MemOperand(sp)); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1713 } | 1728 } |
| 1714 | 1729 |
| 1715 // Emit code to define accessors, using only a single call to the runtime for | 1730 // Emit code to define accessors, using only a single call to the runtime for |
| 1716 // each pair of corresponding getters and setters. | 1731 // each pair of corresponding getters and setters. |
| 1717 for (AccessorTable::Iterator it = accessor_table.begin(); | 1732 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1718 it != accessor_table.end(); ++it) { | 1733 it != accessor_table.end(); ++it) { |
| 1719 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. | 1734 __ LoadP(r3, MemOperand(sp)); // Duplicate receiver. |
| 1720 __ push(r3); | 1735 __ push(r3); |
| 1721 VisitForStackValue(it->first); | 1736 VisitForStackValue(it->first); |
| 1722 EmitAccessor(it->second->getter); | 1737 EmitAccessor(it->second->getter); |
| 1723 EmitSetHomeObjectIfNeeded(it->second->getter, 2); | 1738 EmitSetHomeObjectIfNeeded( |
| 1739 it->second->getter, 2, |
| 1740 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); |
| 1724 EmitAccessor(it->second->setter); | 1741 EmitAccessor(it->second->setter); |
| 1725 EmitSetHomeObjectIfNeeded(it->second->setter, 3); | 1742 EmitSetHomeObjectIfNeeded( |
| 1743 it->second->setter, 3, |
| 1744 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); |
| 1726 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); | 1745 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); |
| 1727 __ push(r3); | 1746 __ push(r3); |
| 1728 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1747 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1729 } | 1748 } |
| 1730 | 1749 |
| 1731 // Object literals have two parts. The "static" part on the left contains no | 1750 // Object literals have two parts. The "static" part on the left contains no |
| 1732 // computed property names, and so we can compute its map ahead of time; see | 1751 // computed property names, and so we can compute its map ahead of time; see |
| 1733 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1752 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1734 // starts with the first computed property name, and continues with all | 1753 // starts with the first computed property name, and continues with all |
| 1735 // properties to its right. All the code from above initializes the static | 1754 // properties to its right. All the code from above initializes the static |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1750 __ push(r3); | 1769 __ push(r3); |
| 1751 | 1770 |
| 1752 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1771 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1753 DCHECK(!property->is_computed_name()); | 1772 DCHECK(!property->is_computed_name()); |
| 1754 VisitForStackValue(value); | 1773 VisitForStackValue(value); |
| 1755 DCHECK(property->emit_store()); | 1774 DCHECK(property->emit_store()); |
| 1756 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1775 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1757 } else { | 1776 } else { |
| 1758 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1777 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1759 VisitForStackValue(value); | 1778 VisitForStackValue(value); |
| 1760 EmitSetHomeObjectIfNeeded(value, 2); | 1779 EmitSetHomeObjectIfNeeded( |
| 1780 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1761 | 1781 |
| 1762 switch (property->kind()) { | 1782 switch (property->kind()) { |
| 1763 case ObjectLiteral::Property::CONSTANT: | 1783 case ObjectLiteral::Property::CONSTANT: |
| 1764 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1784 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1765 case ObjectLiteral::Property::COMPUTED: | 1785 case ObjectLiteral::Property::COMPUTED: |
| 1766 if (property->emit_store()) { | 1786 if (property->emit_store()) { |
| 1767 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); | 1787 __ LoadSmiLiteral(r3, Smi::FromInt(NONE)); |
| 1768 __ push(r3); | 1788 __ push(r3); |
| 1769 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1789 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1770 } else { | 1790 } else { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1796 __ LoadP(r3, MemOperand(sp)); | 1816 __ LoadP(r3, MemOperand(sp)); |
| 1797 __ push(r3); | 1817 __ push(r3); |
| 1798 __ CallRuntime(Runtime::kToFastProperties, 1); | 1818 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1799 } | 1819 } |
| 1800 | 1820 |
| 1801 if (result_saved) { | 1821 if (result_saved) { |
| 1802 context()->PlugTOS(); | 1822 context()->PlugTOS(); |
| 1803 } else { | 1823 } else { |
| 1804 context()->Plug(r3); | 1824 context()->Plug(r3); |
| 1805 } | 1825 } |
| 1826 |
| 1827 // Verify that compilation exactly consumed the number of store ic slots that |
| 1828 // the ObjectLiteral node had to offer. |
| 1829 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); |
| 1806 } | 1830 } |
| 1807 | 1831 |
| 1808 | 1832 |
| 1809 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1833 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1810 Comment cmnt(masm_, "[ ArrayLiteral"); | 1834 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1811 | 1835 |
| 1812 expr->BuildConstantElements(isolate()); | 1836 expr->BuildConstantElements(isolate()); |
| 1813 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1837 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1814 bool has_fast_elements = | 1838 bool has_fast_elements = |
| 1815 IsFastObjectElementsKind(expr->constant_elements_kind()); | 1839 IsFastObjectElementsKind(expr->constant_elements_kind()); |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1909 } | 1933 } |
| 1910 } | 1934 } |
| 1911 | 1935 |
| 1912 | 1936 |
| 1913 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1937 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
| 1914 DCHECK(expr->target()->IsValidReferenceExpression()); | 1938 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1915 | 1939 |
| 1916 Comment cmnt(masm_, "[ Assignment"); | 1940 Comment cmnt(masm_, "[ Assignment"); |
| 1917 | 1941 |
| 1918 Property* property = expr->target()->AsProperty(); | 1942 Property* property = expr->target()->AsProperty(); |
| 1919 LhsKind assign_type = GetAssignType(property); | 1943 LhsKind assign_type = Property::GetAssignType(property); |
| 1920 | 1944 |
| 1921 // Evaluate LHS expression. | 1945 // Evaluate LHS expression. |
| 1922 switch (assign_type) { | 1946 switch (assign_type) { |
| 1923 case VARIABLE: | 1947 case VARIABLE: |
| 1924 // Nothing to do here. | 1948 // Nothing to do here. |
| 1925 break; | 1949 break; |
| 1926 case NAMED_PROPERTY: | 1950 case NAMED_PROPERTY: |
| 1927 if (expr->is_compound()) { | 1951 if (expr->is_compound()) { |
| 1928 // We need the receiver both on the stack and in the register. | 1952 // We need the receiver both on the stack and in the register. |
| 1929 VisitForStackValue(property->obj()); | 1953 VisitForStackValue(property->obj()); |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2018 VisitForAccumulatorValue(expr->value()); | 2042 VisitForAccumulatorValue(expr->value()); |
| 2019 } | 2043 } |
| 2020 | 2044 |
| 2021 // Record source position before possible IC call. | 2045 // Record source position before possible IC call. |
| 2022 SetSourcePosition(expr->position()); | 2046 SetSourcePosition(expr->position()); |
| 2023 | 2047 |
| 2024 // Store the value. | 2048 // Store the value. |
| 2025 switch (assign_type) { | 2049 switch (assign_type) { |
| 2026 case VARIABLE: | 2050 case VARIABLE: |
| 2027 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2051 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 2028 expr->op()); | 2052 expr->op(), expr->AssignmentSlot()); |
| 2029 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2053 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2030 context()->Plug(r3); | 2054 context()->Plug(r3); |
| 2031 break; | 2055 break; |
| 2032 case NAMED_PROPERTY: | 2056 case NAMED_PROPERTY: |
| 2033 EmitNamedPropertyAssignment(expr); | 2057 EmitNamedPropertyAssignment(expr); |
| 2034 break; | 2058 break; |
| 2035 case NAMED_SUPER_PROPERTY: | 2059 case NAMED_SUPER_PROPERTY: |
| 2036 EmitNamedSuperPropertyStore(property); | 2060 EmitNamedSuperPropertyStore(property); |
| 2037 context()->Plug(r3); | 2061 context()->Plug(r3); |
| 2038 break; | 2062 break; |
| (...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2590 __ pop(r4); | 2614 __ pop(r4); |
| 2591 Handle<Code> code = CodeFactory::BinaryOpIC( | 2615 Handle<Code> code = CodeFactory::BinaryOpIC( |
| 2592 isolate(), op, language_mode()).code(); | 2616 isolate(), op, language_mode()).code(); |
| 2593 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2617 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2594 CallIC(code, expr->BinaryOperationFeedbackId()); | 2618 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2595 patch_site.EmitPatchInfo(); | 2619 patch_site.EmitPatchInfo(); |
| 2596 context()->Plug(r3); | 2620 context()->Plug(r3); |
| 2597 } | 2621 } |
| 2598 | 2622 |
| 2599 | 2623 |
| 2600 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2624 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 2625 FeedbackVectorICSlot slot) { |
| 2601 DCHECK(expr->IsValidReferenceExpression()); | 2626 DCHECK(expr->IsValidReferenceExpression()); |
| 2602 | 2627 |
| 2603 Property* prop = expr->AsProperty(); | 2628 Property* prop = expr->AsProperty(); |
| 2604 LhsKind assign_type = GetAssignType(prop); | 2629 LhsKind assign_type = Property::GetAssignType(prop); |
| 2605 | 2630 |
| 2606 switch (assign_type) { | 2631 switch (assign_type) { |
| 2607 case VARIABLE: { | 2632 case VARIABLE: { |
| 2608 Variable* var = expr->AsVariableProxy()->var(); | 2633 Variable* var = expr->AsVariableProxy()->var(); |
| 2609 EffectContext context(this); | 2634 EffectContext context(this); |
| 2610 EmitVariableAssignment(var, Token::ASSIGN); | 2635 EmitVariableAssignment(var, Token::ASSIGN, slot); |
| 2611 break; | 2636 break; |
| 2612 } | 2637 } |
| 2613 case NAMED_PROPERTY: { | 2638 case NAMED_PROPERTY: { |
| 2614 __ push(r3); // Preserve value. | 2639 __ push(r3); // Preserve value. |
| 2615 VisitForAccumulatorValue(prop->obj()); | 2640 VisitForAccumulatorValue(prop->obj()); |
| 2616 __ Move(StoreDescriptor::ReceiverRegister(), r3); | 2641 __ Move(StoreDescriptor::ReceiverRegister(), r3); |
| 2617 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2642 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2618 __ mov(StoreDescriptor::NameRegister(), | 2643 __ mov(StoreDescriptor::NameRegister(), |
| 2619 Operand(prop->key()->AsLiteral()->value())); | 2644 Operand(prop->key()->AsLiteral()->value())); |
| 2645 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2620 CallStoreIC(); | 2646 CallStoreIC(); |
| 2621 break; | 2647 break; |
| 2622 } | 2648 } |
| 2623 case NAMED_SUPER_PROPERTY: { | 2649 case NAMED_SUPER_PROPERTY: { |
| 2624 __ Push(r3); | 2650 __ Push(r3); |
| 2625 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 2651 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 2626 EmitLoadHomeObject(prop->obj()->AsSuperReference()); | 2652 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 2627 // stack: value, this; r3: home_object | 2653 // stack: value, this; r3: home_object |
| 2628 Register scratch = r5; | 2654 Register scratch = r5; |
| 2629 Register scratch2 = r6; | 2655 Register scratch2 = r6; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2656 EmitKeyedSuperPropertyStore(prop); | 2682 EmitKeyedSuperPropertyStore(prop); |
| 2657 break; | 2683 break; |
| 2658 } | 2684 } |
| 2659 case KEYED_PROPERTY: { | 2685 case KEYED_PROPERTY: { |
| 2660 __ push(r3); // Preserve value. | 2686 __ push(r3); // Preserve value. |
| 2661 VisitForStackValue(prop->obj()); | 2687 VisitForStackValue(prop->obj()); |
| 2662 VisitForAccumulatorValue(prop->key()); | 2688 VisitForAccumulatorValue(prop->key()); |
| 2663 __ Move(StoreDescriptor::NameRegister(), r3); | 2689 __ Move(StoreDescriptor::NameRegister(), r3); |
| 2664 __ Pop(StoreDescriptor::ValueRegister(), | 2690 __ Pop(StoreDescriptor::ValueRegister(), |
| 2665 StoreDescriptor::ReceiverRegister()); | 2691 StoreDescriptor::ReceiverRegister()); |
| 2692 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2666 Handle<Code> ic = | 2693 Handle<Code> ic = |
| 2667 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2694 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2668 CallIC(ic); | 2695 CallIC(ic); |
| 2669 break; | 2696 break; |
| 2670 } | 2697 } |
| 2671 } | 2698 } |
| 2672 context()->Plug(r3); | 2699 context()->Plug(r3); |
| 2673 } | 2700 } |
| 2674 | 2701 |
| 2675 | 2702 |
| 2676 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2703 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 2677 Variable* var, MemOperand location) { | 2704 Variable* var, MemOperand location) { |
| 2678 __ StoreP(result_register(), location, r0); | 2705 __ StoreP(result_register(), location, r0); |
| 2679 if (var->IsContextSlot()) { | 2706 if (var->IsContextSlot()) { |
| 2680 // RecordWrite may destroy all its register arguments. | 2707 // RecordWrite may destroy all its register arguments. |
| 2681 __ mr(r6, result_register()); | 2708 __ mr(r6, result_register()); |
| 2682 int offset = Context::SlotOffset(var->index()); | 2709 int offset = Context::SlotOffset(var->index()); |
| 2683 __ RecordWriteContextSlot(r4, offset, r6, r5, kLRHasBeenSaved, | 2710 __ RecordWriteContextSlot(r4, offset, r6, r5, kLRHasBeenSaved, |
| 2684 kDontSaveFPRegs); | 2711 kDontSaveFPRegs); |
| 2685 } | 2712 } |
| 2686 } | 2713 } |
| 2687 | 2714 |
| 2688 | 2715 |
| 2689 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { | 2716 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2717 FeedbackVectorICSlot slot) { |
| 2690 if (var->IsUnallocated()) { | 2718 if (var->IsUnallocated()) { |
| 2691 // Global var, const, or let. | 2719 // Global var, const, or let. |
| 2692 __ mov(StoreDescriptor::NameRegister(), Operand(var->name())); | 2720 __ mov(StoreDescriptor::NameRegister(), Operand(var->name())); |
| 2693 __ LoadP(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2721 __ LoadP(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2722 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2694 CallStoreIC(); | 2723 CallStoreIC(); |
| 2695 | 2724 |
| 2696 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2725 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2697 // Non-initializing assignment to let variable needs a write barrier. | 2726 // Non-initializing assignment to let variable needs a write barrier. |
| 2698 DCHECK(!var->IsLookupSlot()); | 2727 DCHECK(!var->IsLookupSlot()); |
| 2699 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2728 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2700 Label assign; | 2729 Label assign; |
| 2701 MemOperand location = VarOperand(var, r4); | 2730 MemOperand location = VarOperand(var, r4); |
| 2702 __ LoadP(r6, location); | 2731 __ LoadP(r6, location); |
| 2703 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); | 2732 __ CompareRoot(r6, Heap::kTheHoleValueRootIndex); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2779 // Assignment to a property, using a named store IC. | 2808 // Assignment to a property, using a named store IC. |
| 2780 Property* prop = expr->target()->AsProperty(); | 2809 Property* prop = expr->target()->AsProperty(); |
| 2781 DCHECK(prop != NULL); | 2810 DCHECK(prop != NULL); |
| 2782 DCHECK(prop->key()->IsLiteral()); | 2811 DCHECK(prop->key()->IsLiteral()); |
| 2783 | 2812 |
| 2784 // Record source code position before IC call. | 2813 // Record source code position before IC call. |
| 2785 SetSourcePosition(expr->position()); | 2814 SetSourcePosition(expr->position()); |
| 2786 __ mov(StoreDescriptor::NameRegister(), | 2815 __ mov(StoreDescriptor::NameRegister(), |
| 2787 Operand(prop->key()->AsLiteral()->value())); | 2816 Operand(prop->key()->AsLiteral()->value())); |
| 2788 __ pop(StoreDescriptor::ReceiverRegister()); | 2817 __ pop(StoreDescriptor::ReceiverRegister()); |
| 2789 CallStoreIC(expr->AssignmentFeedbackId()); | 2818 if (FLAG_vector_stores) { |
| 2819 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2820 CallStoreIC(); |
| 2821 } else { |
| 2822 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2823 } |
| 2790 | 2824 |
| 2791 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2825 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2792 context()->Plug(r3); | 2826 context()->Plug(r3); |
| 2793 } | 2827 } |
| 2794 | 2828 |
| 2795 | 2829 |
| 2796 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2830 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2797 // Assignment to named property of super. | 2831 // Assignment to named property of super. |
| 2798 // r3 : value | 2832 // r3 : value |
| 2799 // stack : receiver ('this'), home_object | 2833 // stack : receiver ('this'), home_object |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2826 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2860 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2827 // Assignment to a property, using a keyed store IC. | 2861 // Assignment to a property, using a keyed store IC. |
| 2828 | 2862 |
| 2829 // Record source code position before IC call. | 2863 // Record source code position before IC call. |
| 2830 SetSourcePosition(expr->position()); | 2864 SetSourcePosition(expr->position()); |
| 2831 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); | 2865 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); |
| 2832 DCHECK(StoreDescriptor::ValueRegister().is(r3)); | 2866 DCHECK(StoreDescriptor::ValueRegister().is(r3)); |
| 2833 | 2867 |
| 2834 Handle<Code> ic = | 2868 Handle<Code> ic = |
| 2835 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2869 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2836 CallIC(ic, expr->AssignmentFeedbackId()); | 2870 if (FLAG_vector_stores) { |
| 2871 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2872 CallIC(ic); |
| 2873 } else { |
| 2874 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2875 } |
| 2837 | 2876 |
| 2838 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2877 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2839 context()->Plug(r3); | 2878 context()->Plug(r3); |
| 2840 } | 2879 } |
| 2841 | 2880 |
| 2842 | 2881 |
| 2843 void FullCodeGenerator::VisitProperty(Property* expr) { | 2882 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2844 Comment cmnt(masm_, "[ Property"); | 2883 Comment cmnt(masm_, "[ Property"); |
| 2845 Expression* key = expr->key(); | 2884 Expression* key = expr->key(); |
| 2846 | 2885 |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3068 | 3107 |
| 3069 | 3108 |
| 3070 void FullCodeGenerator::EmitLoadSuperConstructor() { | 3109 void FullCodeGenerator::EmitLoadSuperConstructor() { |
| 3071 __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 3110 __ LoadP(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 3072 __ Push(r3); | 3111 __ Push(r3); |
| 3073 __ CallRuntime(Runtime::kGetPrototype, 1); | 3112 __ CallRuntime(Runtime::kGetPrototype, 1); |
| 3074 } | 3113 } |
| 3075 | 3114 |
| 3076 | 3115 |
| 3077 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3116 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 3078 SuperReference* super_ref) { | 3117 SuperReference* super_ref, FeedbackVectorICSlot slot) { |
| 3079 Variable* this_var = super_ref->this_var()->var(); | 3118 Variable* this_var = super_ref->this_var()->var(); |
| 3080 GetVar(r4, this_var); | 3119 GetVar(r4, this_var); |
| 3081 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); | 3120 __ CompareRoot(r4, Heap::kTheHoleValueRootIndex); |
| 3082 Label uninitialized_this; | 3121 Label uninitialized_this; |
| 3083 __ beq(&uninitialized_this); | 3122 __ beq(&uninitialized_this); |
| 3084 __ mov(r4, Operand(this_var->name())); | 3123 __ mov(r4, Operand(this_var->name())); |
| 3085 __ push(r4); | 3124 __ push(r4); |
| 3086 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3125 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 3087 __ bind(&uninitialized_this); | 3126 __ bind(&uninitialized_this); |
| 3088 | 3127 |
| 3089 EmitVariableAssignment(this_var, Token::INIT_CONST); | 3128 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
| 3090 } | 3129 } |
| 3091 | 3130 |
| 3092 | 3131 |
| 3093 void FullCodeGenerator::VisitCall(Call* expr) { | 3132 void FullCodeGenerator::VisitCall(Call* expr) { |
| 3094 #ifdef DEBUG | 3133 #ifdef DEBUG |
| 3095 // We want to verify that RecordJSReturnSite gets called on all paths | 3134 // We want to verify that RecordJSReturnSite gets called on all paths |
| 3096 // through this function. Avoid early returns. | 3135 // through this function. Avoid early returns. |
| 3097 expr->return_is_recorded_ = false; | 3136 expr->return_is_recorded_ = false; |
| 3098 #endif | 3137 #endif |
| 3099 | 3138 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3309 __ Move(r5, FeedbackVector()); | 3348 __ Move(r5, FeedbackVector()); |
| 3310 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot())); | 3349 __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot())); |
| 3311 | 3350 |
| 3312 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3351 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
| 3313 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3352 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3314 | 3353 |
| 3315 __ Drop(1); | 3354 __ Drop(1); |
| 3316 | 3355 |
| 3317 RecordJSReturnSite(expr); | 3356 RecordJSReturnSite(expr); |
| 3318 | 3357 |
| 3319 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); | 3358 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), |
| 3359 expr->CallFeedbackICSlot()); |
| 3320 context()->Plug(r3); | 3360 context()->Plug(r3); |
| 3321 } | 3361 } |
| 3322 | 3362 |
| 3323 | 3363 |
| 3324 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3364 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 3325 ZoneList<Expression*>* args = expr->arguments(); | 3365 ZoneList<Expression*>* args = expr->arguments(); |
| 3326 DCHECK(args->length() == 1); | 3366 DCHECK(args->length() == 1); |
| 3327 | 3367 |
| 3328 VisitForAccumulatorValue(args->at(0)); | 3368 VisitForAccumulatorValue(args->at(0)); |
| 3329 | 3369 |
| (...skipping 1298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4628 // Push NewTarget | 4668 // Push NewTarget |
| 4629 DCHECK(args->at(2)->IsVariableProxy()); | 4669 DCHECK(args->at(2)->IsVariableProxy()); |
| 4630 VisitForStackValue(args->at(2)); | 4670 VisitForStackValue(args->at(2)); |
| 4631 | 4671 |
| 4632 EmitCallJSRuntimeFunction(call); | 4672 EmitCallJSRuntimeFunction(call); |
| 4633 | 4673 |
| 4634 // Restore context register. | 4674 // Restore context register. |
| 4635 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 4675 __ LoadP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 4636 context()->DropAndPlug(1, r3); | 4676 context()->DropAndPlug(1, r3); |
| 4637 | 4677 |
| 4678 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
| 4638 EmitInitializeThisAfterSuper(super_reference); | 4679 EmitInitializeThisAfterSuper(super_reference); |
| 4639 } | 4680 } |
| 4640 | 4681 |
| 4641 | 4682 |
| 4642 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4683 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4643 // Push the builtins object as the receiver. | 4684 // Push the builtins object as the receiver. |
| 4644 Register receiver = LoadDescriptor::ReceiverRegister(); | 4685 Register receiver = LoadDescriptor::ReceiverRegister(); |
| 4645 __ LoadP(receiver, GlobalObjectOperand()); | 4686 __ LoadP(receiver, GlobalObjectOperand()); |
| 4646 __ LoadP(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); | 4687 __ LoadP(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); |
| 4647 __ push(receiver); | 4688 __ push(receiver); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4826 } | 4867 } |
| 4827 | 4868 |
| 4828 | 4869 |
| 4829 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4870 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4830 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4871 DCHECK(expr->expression()->IsValidReferenceExpression()); |
| 4831 | 4872 |
| 4832 Comment cmnt(masm_, "[ CountOperation"); | 4873 Comment cmnt(masm_, "[ CountOperation"); |
| 4833 SetSourcePosition(expr->position()); | 4874 SetSourcePosition(expr->position()); |
| 4834 | 4875 |
| 4835 Property* prop = expr->expression()->AsProperty(); | 4876 Property* prop = expr->expression()->AsProperty(); |
| 4836 LhsKind assign_type = GetAssignType(prop); | 4877 LhsKind assign_type = Property::GetAssignType(prop); |
| 4837 | 4878 |
| 4838 // Evaluate expression and get value. | 4879 // Evaluate expression and get value. |
| 4839 if (assign_type == VARIABLE) { | 4880 if (assign_type == VARIABLE) { |
| 4840 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4881 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4841 AccumulatorValueContext context(this); | 4882 AccumulatorValueContext context(this); |
| 4842 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4883 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4843 } else { | 4884 } else { |
| 4844 // Reserve space for result of postfix operation. | 4885 // Reserve space for result of postfix operation. |
| 4845 if (expr->is_postfix() && !context()->IsEffect()) { | 4886 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4846 __ LoadSmiLiteral(ip, Smi::FromInt(0)); | 4887 __ LoadSmiLiteral(ip, Smi::FromInt(0)); |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4991 patch_site.EmitPatchInfo(); | 5032 patch_site.EmitPatchInfo(); |
| 4992 __ bind(&done); | 5033 __ bind(&done); |
| 4993 | 5034 |
| 4994 // Store the value returned in r3. | 5035 // Store the value returned in r3. |
| 4995 switch (assign_type) { | 5036 switch (assign_type) { |
| 4996 case VARIABLE: | 5037 case VARIABLE: |
| 4997 if (expr->is_postfix()) { | 5038 if (expr->is_postfix()) { |
| 4998 { | 5039 { |
| 4999 EffectContext context(this); | 5040 EffectContext context(this); |
| 5000 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 5041 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 5001 Token::ASSIGN); | 5042 Token::ASSIGN, expr->CountSlot()); |
| 5002 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5043 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 5003 context.Plug(r3); | 5044 context.Plug(r3); |
| 5004 } | 5045 } |
| 5005 // For all contexts except EffectConstant We have the result on | 5046 // For all contexts except EffectConstant We have the result on |
| 5006 // top of the stack. | 5047 // top of the stack. |
| 5007 if (!context()->IsEffect()) { | 5048 if (!context()->IsEffect()) { |
| 5008 context()->PlugTOS(); | 5049 context()->PlugTOS(); |
| 5009 } | 5050 } |
| 5010 } else { | 5051 } else { |
| 5011 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 5052 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 5012 Token::ASSIGN); | 5053 Token::ASSIGN, expr->CountSlot()); |
| 5013 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5054 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 5014 context()->Plug(r3); | 5055 context()->Plug(r3); |
| 5015 } | 5056 } |
| 5016 break; | 5057 break; |
| 5017 case NAMED_PROPERTY: { | 5058 case NAMED_PROPERTY: { |
| 5018 __ mov(StoreDescriptor::NameRegister(), | 5059 __ mov(StoreDescriptor::NameRegister(), |
| 5019 Operand(prop->key()->AsLiteral()->value())); | 5060 Operand(prop->key()->AsLiteral()->value())); |
| 5020 __ pop(StoreDescriptor::ReceiverRegister()); | 5061 __ pop(StoreDescriptor::ReceiverRegister()); |
| 5021 CallStoreIC(expr->CountStoreFeedbackId()); | 5062 if (FLAG_vector_stores) { |
| 5063 EmitLoadStoreICSlot(expr->CountSlot()); |
| 5064 CallStoreIC(); |
| 5065 } else { |
| 5066 CallStoreIC(expr->CountStoreFeedbackId()); |
| 5067 } |
| 5022 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5068 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 5023 if (expr->is_postfix()) { | 5069 if (expr->is_postfix()) { |
| 5024 if (!context()->IsEffect()) { | 5070 if (!context()->IsEffect()) { |
| 5025 context()->PlugTOS(); | 5071 context()->PlugTOS(); |
| 5026 } | 5072 } |
| 5027 } else { | 5073 } else { |
| 5028 context()->Plug(r3); | 5074 context()->Plug(r3); |
| 5029 } | 5075 } |
| 5030 break; | 5076 break; |
| 5031 } | 5077 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 5049 } else { | 5095 } else { |
| 5050 context()->Plug(r3); | 5096 context()->Plug(r3); |
| 5051 } | 5097 } |
| 5052 break; | 5098 break; |
| 5053 } | 5099 } |
| 5054 case KEYED_PROPERTY: { | 5100 case KEYED_PROPERTY: { |
| 5055 __ Pop(StoreDescriptor::ReceiverRegister(), | 5101 __ Pop(StoreDescriptor::ReceiverRegister(), |
| 5056 StoreDescriptor::NameRegister()); | 5102 StoreDescriptor::NameRegister()); |
| 5057 Handle<Code> ic = | 5103 Handle<Code> ic = |
| 5058 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 5104 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 5059 CallIC(ic, expr->CountStoreFeedbackId()); | 5105 if (FLAG_vector_stores) { |
| 5106 EmitLoadStoreICSlot(expr->CountSlot()); |
| 5107 CallIC(ic); |
| 5108 } else { |
| 5109 CallIC(ic, expr->CountStoreFeedbackId()); |
| 5110 } |
| 5060 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5111 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 5061 if (expr->is_postfix()) { | 5112 if (expr->is_postfix()) { |
| 5062 if (!context()->IsEffect()) { | 5113 if (!context()->IsEffect()) { |
| 5063 context()->PlugTOS(); | 5114 context()->PlugTOS(); |
| 5064 } | 5115 } |
| 5065 } else { | 5116 } else { |
| 5066 context()->Plug(r3); | 5117 context()->Plug(r3); |
| 5067 } | 5118 } |
| 5068 break; | 5119 break; |
| 5069 } | 5120 } |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5387 void FullCodeGenerator::ClearPendingMessage() { | 5438 void FullCodeGenerator::ClearPendingMessage() { |
| 5388 DCHECK(!result_register().is(r4)); | 5439 DCHECK(!result_register().is(r4)); |
| 5389 ExternalReference pending_message_obj = | 5440 ExternalReference pending_message_obj = |
| 5390 ExternalReference::address_of_pending_message_obj(isolate()); | 5441 ExternalReference::address_of_pending_message_obj(isolate()); |
| 5391 __ LoadRoot(r4, Heap::kTheHoleValueRootIndex); | 5442 __ LoadRoot(r4, Heap::kTheHoleValueRootIndex); |
| 5392 __ mov(ip, Operand(pending_message_obj)); | 5443 __ mov(ip, Operand(pending_message_obj)); |
| 5393 __ StoreP(r4, MemOperand(ip)); | 5444 __ StoreP(r4, MemOperand(ip)); |
| 5394 } | 5445 } |
| 5395 | 5446 |
| 5396 | 5447 |
| 5448 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { |
| 5449 DCHECK(FLAG_vector_stores && !slot.IsInvalid()); |
| 5450 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), |
| 5451 Operand(SmiFromSlot(slot))); |
| 5452 } |
| 5453 |
| 5454 |
| 5397 #undef __ | 5455 #undef __ |
| 5398 | 5456 |
| 5399 | 5457 |
| 5400 void BackEdgeTable::PatchAt(Code* unoptimized_code, Address pc, | 5458 void BackEdgeTable::PatchAt(Code* unoptimized_code, Address pc, |
| 5401 BackEdgeState target_state, | 5459 BackEdgeState target_state, |
| 5402 Code* replacement_code) { | 5460 Code* replacement_code) { |
| 5403 Address mov_address = Assembler::target_address_from_return_address(pc); | 5461 Address mov_address = Assembler::target_address_from_return_address(pc); |
| 5404 Address cmp_address = mov_address - 2 * Assembler::kInstrSize; | 5462 Address cmp_address = mov_address - 2 * Assembler::kInstrSize; |
| 5405 CodePatcher patcher(cmp_address, 1); | 5463 CodePatcher patcher(cmp_address, 1); |
| 5406 | 5464 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5461 return ON_STACK_REPLACEMENT; | 5519 return ON_STACK_REPLACEMENT; |
| 5462 } | 5520 } |
| 5463 | 5521 |
| 5464 DCHECK(interrupt_address == | 5522 DCHECK(interrupt_address == |
| 5465 isolate->builtins()->OsrAfterStackCheck()->entry()); | 5523 isolate->builtins()->OsrAfterStackCheck()->entry()); |
| 5466 return OSR_AFTER_STACK_CHECK; | 5524 return OSR_AFTER_STACK_CHECK; |
| 5467 } | 5525 } |
| 5468 } | 5526 } |
| 5469 } // namespace v8::internal | 5527 } // namespace v8::internal |
| 5470 #endif // V8_TARGET_ARCH_PPC | 5528 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |