| 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_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 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 1173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 __ test(eax, eax); | 1184 __ test(eax, eax); |
| 1185 __ j(equal, loop_statement.continue_label()); | 1185 __ j(equal, loop_statement.continue_label()); |
| 1186 __ mov(ebx, eax); | 1186 __ mov(ebx, eax); |
| 1187 | 1187 |
| 1188 // Update the 'each' property or variable from the possibly filtered | 1188 // Update the 'each' property or variable from the possibly filtered |
| 1189 // entry in register ebx. | 1189 // entry in register ebx. |
| 1190 __ bind(&update_each); | 1190 __ bind(&update_each); |
| 1191 __ mov(result_register(), ebx); | 1191 __ mov(result_register(), ebx); |
| 1192 // Perform the assignment as if via '='. | 1192 // Perform the assignment as if via '='. |
| 1193 { EffectContext context(this); | 1193 { EffectContext context(this); |
| 1194 EmitAssignment(stmt->each()); | 1194 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
| 1195 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); | 1195 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); |
| 1196 } | 1196 } |
| 1197 | 1197 |
| 1198 // Generate code for the body of the loop. | 1198 // Generate code for the body of the loop. |
| 1199 Visit(stmt->body()); | 1199 Visit(stmt->body()); |
| 1200 | 1200 |
| 1201 // Generate code for going to the next element by incrementing the | 1201 // Generate code for going to the next element by incrementing the |
| 1202 // index (smi) stored on top of the stack. | 1202 // index (smi) stored on top of the stack. |
| 1203 __ bind(loop_statement.continue_label()); | 1203 __ bind(loop_statement.continue_label()); |
| 1204 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); | 1204 __ add(Operand(esp, 0 * kPointerSize), Immediate(Smi::FromInt(1))); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 | 1266 |
| 1267 __ cmp(eax, isolate()->factory()->undefined_value()); | 1267 __ cmp(eax, isolate()->factory()->undefined_value()); |
| 1268 Label done; | 1268 Label done; |
| 1269 __ j(not_equal, &done); | 1269 __ j(not_equal, &done); |
| 1270 __ CallRuntime(Runtime::kThrowNonMethodError, 0); | 1270 __ CallRuntime(Runtime::kThrowNonMethodError, 0); |
| 1271 __ bind(&done); | 1271 __ bind(&done); |
| 1272 } | 1272 } |
| 1273 | 1273 |
| 1274 | 1274 |
| 1275 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1275 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1276 int offset) { | 1276 int offset, |
| 1277 FeedbackVectorICSlot slot) { |
| 1277 if (NeedsHomeObject(initializer)) { | 1278 if (NeedsHomeObject(initializer)) { |
| 1278 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1279 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1279 __ mov(StoreDescriptor::NameRegister(), | 1280 __ mov(StoreDescriptor::NameRegister(), |
| 1280 Immediate(isolate()->factory()->home_object_symbol())); | 1281 Immediate(isolate()->factory()->home_object_symbol())); |
| 1281 __ mov(StoreDescriptor::ValueRegister(), | 1282 __ mov(StoreDescriptor::ValueRegister(), |
| 1282 Operand(esp, offset * kPointerSize)); | 1283 Operand(esp, offset * kPointerSize)); |
| 1284 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1283 CallStoreIC(); | 1285 CallStoreIC(); |
| 1284 } | 1286 } |
| 1285 } | 1287 } |
| 1286 | 1288 |
| 1287 | 1289 |
| 1288 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1290 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1289 TypeofState typeof_state, | 1291 TypeofState typeof_state, |
| 1290 Label* slow) { | 1292 Label* slow) { |
| 1291 Register context = esi; | 1293 Register context = esi; |
| 1292 Register temp = edx; | 1294 Register temp = edx; |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1606 __ CallStub(&stub); | 1608 __ CallStub(&stub); |
| 1607 } | 1609 } |
| 1608 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1610 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1609 | 1611 |
| 1610 // If result_saved is true the result is on top of the stack. If | 1612 // If result_saved is true the result is on top of the stack. If |
| 1611 // result_saved is false the result is in eax. | 1613 // result_saved is false the result is in eax. |
| 1612 bool result_saved = false; | 1614 bool result_saved = false; |
| 1613 | 1615 |
| 1614 AccessorTable accessor_table(zone()); | 1616 AccessorTable accessor_table(zone()); |
| 1615 int property_index = 0; | 1617 int property_index = 0; |
| 1618 // store_slot_index points to the vector ic slot for the next store ic used. |
| 1619 // ObjectLiteral::ComputeFeedbackRequirements controls the allocation of slots |
| 1620 // and must be updated if the number of store ics emitted here changes. |
| 1621 int store_slot_index = 0; |
| 1616 for (; property_index < expr->properties()->length(); property_index++) { | 1622 for (; property_index < expr->properties()->length(); property_index++) { |
| 1617 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1623 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1618 if (property->is_computed_name()) break; | 1624 if (property->is_computed_name()) break; |
| 1619 if (property->IsCompileTimeValue()) continue; | 1625 if (property->IsCompileTimeValue()) continue; |
| 1620 | 1626 |
| 1621 Literal* key = property->key()->AsLiteral(); | 1627 Literal* key = property->key()->AsLiteral(); |
| 1622 Expression* value = property->value(); | 1628 Expression* value = property->value(); |
| 1623 if (!result_saved) { | 1629 if (!result_saved) { |
| 1624 __ push(eax); // Save result on the stack | 1630 __ push(eax); // Save result on the stack |
| 1625 result_saved = true; | 1631 result_saved = true; |
| 1626 } | 1632 } |
| 1627 switch (property->kind()) { | 1633 switch (property->kind()) { |
| 1628 case ObjectLiteral::Property::CONSTANT: | 1634 case ObjectLiteral::Property::CONSTANT: |
| 1629 UNREACHABLE(); | 1635 UNREACHABLE(); |
| 1630 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1636 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1631 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 1637 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1632 // Fall through. | 1638 // Fall through. |
| 1633 case ObjectLiteral::Property::COMPUTED: | 1639 case ObjectLiteral::Property::COMPUTED: |
| 1634 // It is safe to use [[Put]] here because the boilerplate already | 1640 // It is safe to use [[Put]] here because the boilerplate already |
| 1635 // contains computed properties with an uninitialized value. | 1641 // contains computed properties with an uninitialized value. |
| 1636 if (key->value()->IsInternalizedString()) { | 1642 if (key->value()->IsInternalizedString()) { |
| 1637 if (property->emit_store()) { | 1643 if (property->emit_store()) { |
| 1638 VisitForAccumulatorValue(value); | 1644 VisitForAccumulatorValue(value); |
| 1639 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 1645 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
| 1640 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); | 1646 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); |
| 1641 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1647 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1642 CallStoreIC(key->LiteralFeedbackId()); | 1648 if (FLAG_vector_stores) { |
| 1649 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1650 CallStoreIC(); |
| 1651 } else { |
| 1652 CallStoreIC(key->LiteralFeedbackId()); |
| 1653 } |
| 1643 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1654 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1644 | 1655 |
| 1645 if (NeedsHomeObject(value)) { | 1656 if (NeedsHomeObject(value)) { |
| 1646 __ mov(StoreDescriptor::ReceiverRegister(), eax); | 1657 __ mov(StoreDescriptor::ReceiverRegister(), eax); |
| 1647 __ mov(StoreDescriptor::NameRegister(), | 1658 __ mov(StoreDescriptor::NameRegister(), |
| 1648 Immediate(isolate()->factory()->home_object_symbol())); | 1659 Immediate(isolate()->factory()->home_object_symbol())); |
| 1649 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0)); | 1660 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0)); |
| 1661 if (FLAG_vector_stores) { |
| 1662 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1663 } |
| 1650 CallStoreIC(); | 1664 CallStoreIC(); |
| 1651 } | 1665 } |
| 1652 } else { | 1666 } else { |
| 1653 VisitForEffect(value); | 1667 VisitForEffect(value); |
| 1654 } | 1668 } |
| 1655 break; | 1669 break; |
| 1656 } | 1670 } |
| 1657 __ push(Operand(esp, 0)); // Duplicate receiver. | 1671 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1658 VisitForStackValue(key); | 1672 VisitForStackValue(key); |
| 1659 VisitForStackValue(value); | 1673 VisitForStackValue(value); |
| 1660 if (property->emit_store()) { | 1674 if (property->emit_store()) { |
| 1661 EmitSetHomeObjectIfNeeded(value, 2); | 1675 EmitSetHomeObjectIfNeeded( |
| 1676 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1662 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode | 1677 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode |
| 1663 __ CallRuntime(Runtime::kSetProperty, 4); | 1678 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1664 } else { | 1679 } else { |
| 1665 __ Drop(3); | 1680 __ Drop(3); |
| 1666 } | 1681 } |
| 1667 break; | 1682 break; |
| 1668 case ObjectLiteral::Property::PROTOTYPE: | 1683 case ObjectLiteral::Property::PROTOTYPE: |
| 1669 __ push(Operand(esp, 0)); // Duplicate receiver. | 1684 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1670 VisitForStackValue(value); | 1685 VisitForStackValue(value); |
| 1671 DCHECK(property->emit_store()); | 1686 DCHECK(property->emit_store()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1685 } | 1700 } |
| 1686 | 1701 |
| 1687 // Emit code to define accessors, using only a single call to the runtime for | 1702 // Emit code to define accessors, using only a single call to the runtime for |
| 1688 // each pair of corresponding getters and setters. | 1703 // each pair of corresponding getters and setters. |
| 1689 for (AccessorTable::Iterator it = accessor_table.begin(); | 1704 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1690 it != accessor_table.end(); | 1705 it != accessor_table.end(); |
| 1691 ++it) { | 1706 ++it) { |
| 1692 __ push(Operand(esp, 0)); // Duplicate receiver. | 1707 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1693 VisitForStackValue(it->first); | 1708 VisitForStackValue(it->first); |
| 1694 EmitAccessor(it->second->getter); | 1709 EmitAccessor(it->second->getter); |
| 1695 EmitSetHomeObjectIfNeeded(it->second->getter, 2); | 1710 EmitSetHomeObjectIfNeeded( |
| 1711 it->second->getter, 2, |
| 1712 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); |
| 1713 |
| 1696 EmitAccessor(it->second->setter); | 1714 EmitAccessor(it->second->setter); |
| 1697 EmitSetHomeObjectIfNeeded(it->second->setter, 3); | 1715 EmitSetHomeObjectIfNeeded( |
| 1716 it->second->setter, 3, |
| 1717 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); |
| 1718 |
| 1698 __ push(Immediate(Smi::FromInt(NONE))); | 1719 __ push(Immediate(Smi::FromInt(NONE))); |
| 1699 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1720 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1700 } | 1721 } |
| 1701 | 1722 |
| 1702 // Object literals have two parts. The "static" part on the left contains no | 1723 // Object literals have two parts. The "static" part on the left contains no |
| 1703 // computed property names, and so we can compute its map ahead of time; see | 1724 // computed property names, and so we can compute its map ahead of time; see |
| 1704 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1725 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1705 // starts with the first computed property name, and continues with all | 1726 // starts with the first computed property name, and continues with all |
| 1706 // properties to its right. All the code from above initializes the static | 1727 // properties to its right. All the code from above initializes the static |
| 1707 // component of the object literal, and arranges for the map of the result to | 1728 // component of the object literal, and arranges for the map of the result to |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1720 __ push(Operand(esp, 0)); // Duplicate receiver. | 1741 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1721 | 1742 |
| 1722 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1743 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1723 DCHECK(!property->is_computed_name()); | 1744 DCHECK(!property->is_computed_name()); |
| 1724 VisitForStackValue(value); | 1745 VisitForStackValue(value); |
| 1725 DCHECK(property->emit_store()); | 1746 DCHECK(property->emit_store()); |
| 1726 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1747 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1727 } else { | 1748 } else { |
| 1728 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1749 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1729 VisitForStackValue(value); | 1750 VisitForStackValue(value); |
| 1730 EmitSetHomeObjectIfNeeded(value, 2); | 1751 EmitSetHomeObjectIfNeeded( |
| 1752 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1731 | 1753 |
| 1732 switch (property->kind()) { | 1754 switch (property->kind()) { |
| 1733 case ObjectLiteral::Property::CONSTANT: | 1755 case ObjectLiteral::Property::CONSTANT: |
| 1734 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1756 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1735 case ObjectLiteral::Property::COMPUTED: | 1757 case ObjectLiteral::Property::COMPUTED: |
| 1736 if (property->emit_store()) { | 1758 if (property->emit_store()) { |
| 1737 __ push(Immediate(Smi::FromInt(NONE))); | 1759 __ push(Immediate(Smi::FromInt(NONE))); |
| 1738 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1760 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1739 } else { | 1761 } else { |
| 1740 __ Drop(3); | 1762 __ Drop(3); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1762 DCHECK(result_saved); | 1784 DCHECK(result_saved); |
| 1763 __ push(Operand(esp, 0)); | 1785 __ push(Operand(esp, 0)); |
| 1764 __ CallRuntime(Runtime::kToFastProperties, 1); | 1786 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1765 } | 1787 } |
| 1766 | 1788 |
| 1767 if (result_saved) { | 1789 if (result_saved) { |
| 1768 context()->PlugTOS(); | 1790 context()->PlugTOS(); |
| 1769 } else { | 1791 } else { |
| 1770 context()->Plug(eax); | 1792 context()->Plug(eax); |
| 1771 } | 1793 } |
| 1794 |
| 1795 // Verify that compilation exactly consumed the number of store ic slots that |
| 1796 // the ObjectLiteral node had to offer. |
| 1797 DCHECK(!FLAG_vector_stores || store_slot_index == expr->slot_count()); |
| 1772 } | 1798 } |
| 1773 | 1799 |
| 1774 | 1800 |
| 1775 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { | 1801 void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1776 Comment cmnt(masm_, "[ ArrayLiteral"); | 1802 Comment cmnt(masm_, "[ ArrayLiteral"); |
| 1777 | 1803 |
| 1778 expr->BuildConstantElements(isolate()); | 1804 expr->BuildConstantElements(isolate()); |
| 1779 Handle<FixedArray> constant_elements = expr->constant_elements(); | 1805 Handle<FixedArray> constant_elements = expr->constant_elements(); |
| 1780 bool has_constant_fast_elements = | 1806 bool has_constant_fast_elements = |
| 1781 IsFastObjectElementsKind(expr->constant_elements_kind()); | 1807 IsFastObjectElementsKind(expr->constant_elements_kind()); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1882 } | 1908 } |
| 1883 } | 1909 } |
| 1884 | 1910 |
| 1885 | 1911 |
| 1886 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1912 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
| 1887 DCHECK(expr->target()->IsValidReferenceExpression()); | 1913 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1888 | 1914 |
| 1889 Comment cmnt(masm_, "[ Assignment"); | 1915 Comment cmnt(masm_, "[ Assignment"); |
| 1890 | 1916 |
| 1891 Property* property = expr->target()->AsProperty(); | 1917 Property* property = expr->target()->AsProperty(); |
| 1892 LhsKind assign_type = GetAssignType(property); | 1918 LhsKind assign_type = Property::GetAssignType(property); |
| 1893 | 1919 |
| 1894 // Evaluate LHS expression. | 1920 // Evaluate LHS expression. |
| 1895 switch (assign_type) { | 1921 switch (assign_type) { |
| 1896 case VARIABLE: | 1922 case VARIABLE: |
| 1897 // Nothing to do here. | 1923 // Nothing to do here. |
| 1898 break; | 1924 break; |
| 1899 case NAMED_SUPER_PROPERTY: | 1925 case NAMED_SUPER_PROPERTY: |
| 1900 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); | 1926 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); |
| 1901 EmitLoadHomeObject(property->obj()->AsSuperReference()); | 1927 EmitLoadHomeObject(property->obj()->AsSuperReference()); |
| 1902 __ push(result_register()); | 1928 __ push(result_register()); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1989 VisitForAccumulatorValue(expr->value()); | 2015 VisitForAccumulatorValue(expr->value()); |
| 1990 } | 2016 } |
| 1991 | 2017 |
| 1992 // Record source position before possible IC call. | 2018 // Record source position before possible IC call. |
| 1993 SetSourcePosition(expr->position()); | 2019 SetSourcePosition(expr->position()); |
| 1994 | 2020 |
| 1995 // Store the value. | 2021 // Store the value. |
| 1996 switch (assign_type) { | 2022 switch (assign_type) { |
| 1997 case VARIABLE: | 2023 case VARIABLE: |
| 1998 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2024 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 1999 expr->op()); | 2025 expr->op(), expr->AssignmentSlot()); |
| 2000 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2026 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2001 context()->Plug(eax); | 2027 context()->Plug(eax); |
| 2002 break; | 2028 break; |
| 2003 case NAMED_PROPERTY: | 2029 case NAMED_PROPERTY: |
| 2004 EmitNamedPropertyAssignment(expr); | 2030 EmitNamedPropertyAssignment(expr); |
| 2005 break; | 2031 break; |
| 2006 case NAMED_SUPER_PROPERTY: | 2032 case NAMED_SUPER_PROPERTY: |
| 2007 EmitNamedSuperPropertyStore(property); | 2033 EmitNamedSuperPropertyStore(property); |
| 2008 context()->Plug(result_register()); | 2034 context()->Plug(result_register()); |
| 2009 break; | 2035 break; |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2507 __ pop(edx); | 2533 __ pop(edx); |
| 2508 Handle<Code> code = CodeFactory::BinaryOpIC( | 2534 Handle<Code> code = CodeFactory::BinaryOpIC( |
| 2509 isolate(), op, language_mode()).code(); | 2535 isolate(), op, language_mode()).code(); |
| 2510 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2536 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2511 CallIC(code, expr->BinaryOperationFeedbackId()); | 2537 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2512 patch_site.EmitPatchInfo(); | 2538 patch_site.EmitPatchInfo(); |
| 2513 context()->Plug(eax); | 2539 context()->Plug(eax); |
| 2514 } | 2540 } |
| 2515 | 2541 |
| 2516 | 2542 |
| 2517 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2543 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 2544 FeedbackVectorICSlot slot) { |
| 2518 DCHECK(expr->IsValidReferenceExpression()); | 2545 DCHECK(expr->IsValidReferenceExpression()); |
| 2519 | 2546 |
| 2520 Property* prop = expr->AsProperty(); | 2547 Property* prop = expr->AsProperty(); |
| 2521 LhsKind assign_type = GetAssignType(prop); | 2548 LhsKind assign_type = Property::GetAssignType(prop); |
| 2522 | 2549 |
| 2523 switch (assign_type) { | 2550 switch (assign_type) { |
| 2524 case VARIABLE: { | 2551 case VARIABLE: { |
| 2525 Variable* var = expr->AsVariableProxy()->var(); | 2552 Variable* var = expr->AsVariableProxy()->var(); |
| 2526 EffectContext context(this); | 2553 EffectContext context(this); |
| 2527 EmitVariableAssignment(var, Token::ASSIGN); | 2554 EmitVariableAssignment(var, Token::ASSIGN, slot); |
| 2528 break; | 2555 break; |
| 2529 } | 2556 } |
| 2530 case NAMED_PROPERTY: { | 2557 case NAMED_PROPERTY: { |
| 2531 __ push(eax); // Preserve value. | 2558 __ push(eax); // Preserve value. |
| 2532 VisitForAccumulatorValue(prop->obj()); | 2559 VisitForAccumulatorValue(prop->obj()); |
| 2533 __ Move(StoreDescriptor::ReceiverRegister(), eax); | 2560 __ Move(StoreDescriptor::ReceiverRegister(), eax); |
| 2534 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2561 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2535 __ mov(StoreDescriptor::NameRegister(), | 2562 __ mov(StoreDescriptor::NameRegister(), |
| 2536 prop->key()->AsLiteral()->value()); | 2563 prop->key()->AsLiteral()->value()); |
| 2564 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2537 CallStoreIC(); | 2565 CallStoreIC(); |
| 2538 break; | 2566 break; |
| 2539 } | 2567 } |
| 2540 case NAMED_SUPER_PROPERTY: { | 2568 case NAMED_SUPER_PROPERTY: { |
| 2541 __ push(eax); | 2569 __ push(eax); |
| 2542 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 2570 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 2543 EmitLoadHomeObject(prop->obj()->AsSuperReference()); | 2571 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 2544 // stack: value, this; eax: home_object | 2572 // stack: value, this; eax: home_object |
| 2545 Register scratch = ecx; | 2573 Register scratch = ecx; |
| 2546 Register scratch2 = edx; | 2574 Register scratch2 = edx; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2573 EmitKeyedSuperPropertyStore(prop); | 2601 EmitKeyedSuperPropertyStore(prop); |
| 2574 break; | 2602 break; |
| 2575 } | 2603 } |
| 2576 case KEYED_PROPERTY: { | 2604 case KEYED_PROPERTY: { |
| 2577 __ push(eax); // Preserve value. | 2605 __ push(eax); // Preserve value. |
| 2578 VisitForStackValue(prop->obj()); | 2606 VisitForStackValue(prop->obj()); |
| 2579 VisitForAccumulatorValue(prop->key()); | 2607 VisitForAccumulatorValue(prop->key()); |
| 2580 __ Move(StoreDescriptor::NameRegister(), eax); | 2608 __ Move(StoreDescriptor::NameRegister(), eax); |
| 2581 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. | 2609 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. |
| 2582 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2610 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2611 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2583 Handle<Code> ic = | 2612 Handle<Code> ic = |
| 2584 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2613 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2585 CallIC(ic); | 2614 CallIC(ic); |
| 2586 break; | 2615 break; |
| 2587 } | 2616 } |
| 2588 } | 2617 } |
| 2589 context()->Plug(eax); | 2618 context()->Plug(eax); |
| 2590 } | 2619 } |
| 2591 | 2620 |
| 2592 | 2621 |
| 2593 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2622 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 2594 Variable* var, MemOperand location) { | 2623 Variable* var, MemOperand location) { |
| 2595 __ mov(location, eax); | 2624 __ mov(location, eax); |
| 2596 if (var->IsContextSlot()) { | 2625 if (var->IsContextSlot()) { |
| 2597 __ mov(edx, eax); | 2626 __ mov(edx, eax); |
| 2598 int offset = Context::SlotOffset(var->index()); | 2627 int offset = Context::SlotOffset(var->index()); |
| 2599 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); | 2628 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); |
| 2600 } | 2629 } |
| 2601 } | 2630 } |
| 2602 | 2631 |
| 2603 | 2632 |
| 2604 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2633 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2605 Token::Value op) { | 2634 FeedbackVectorICSlot slot) { |
| 2606 if (var->IsUnallocated()) { | 2635 if (var->IsUnallocated()) { |
| 2607 // Global var, const, or let. | 2636 // Global var, const, or let. |
| 2608 __ mov(StoreDescriptor::NameRegister(), var->name()); | 2637 __ mov(StoreDescriptor::NameRegister(), var->name()); |
| 2609 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2638 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2639 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2610 CallStoreIC(); | 2640 CallStoreIC(); |
| 2611 | 2641 |
| 2612 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2642 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2613 // Non-initializing assignment to let variable needs a write barrier. | 2643 // Non-initializing assignment to let variable needs a write barrier. |
| 2614 DCHECK(!var->IsLookupSlot()); | 2644 DCHECK(!var->IsLookupSlot()); |
| 2615 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2645 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2616 Label assign; | 2646 Label assign; |
| 2617 MemOperand location = VarOperand(var, ecx); | 2647 MemOperand location = VarOperand(var, ecx); |
| 2618 __ mov(edx, location); | 2648 __ mov(edx, location); |
| 2619 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2649 __ cmp(edx, isolate()->factory()->the_hole_value()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2695 // esp[0] : receiver | 2725 // esp[0] : receiver |
| 2696 | 2726 |
| 2697 Property* prop = expr->target()->AsProperty(); | 2727 Property* prop = expr->target()->AsProperty(); |
| 2698 DCHECK(prop != NULL); | 2728 DCHECK(prop != NULL); |
| 2699 DCHECK(prop->key()->IsLiteral()); | 2729 DCHECK(prop->key()->IsLiteral()); |
| 2700 | 2730 |
| 2701 // Record source code position before IC call. | 2731 // Record source code position before IC call. |
| 2702 SetSourcePosition(expr->position()); | 2732 SetSourcePosition(expr->position()); |
| 2703 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2733 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
| 2704 __ pop(StoreDescriptor::ReceiverRegister()); | 2734 __ pop(StoreDescriptor::ReceiverRegister()); |
| 2705 CallStoreIC(expr->AssignmentFeedbackId()); | 2735 if (FLAG_vector_stores) { |
| 2736 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2737 CallStoreIC(); |
| 2738 } else { |
| 2739 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2740 } |
| 2706 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2741 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2707 context()->Plug(eax); | 2742 context()->Plug(eax); |
| 2708 } | 2743 } |
| 2709 | 2744 |
| 2710 | 2745 |
| 2711 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2746 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2712 // Assignment to named property of super. | 2747 // Assignment to named property of super. |
| 2713 // eax : value | 2748 // eax : value |
| 2714 // stack : receiver ('this'), home_object | 2749 // stack : receiver ('this'), home_object |
| 2715 DCHECK(prop != NULL); | 2750 DCHECK(prop != NULL); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2743 // esp[0] : key | 2778 // esp[0] : key |
| 2744 // esp[kPointerSize] : receiver | 2779 // esp[kPointerSize] : receiver |
| 2745 | 2780 |
| 2746 __ pop(StoreDescriptor::NameRegister()); // Key. | 2781 __ pop(StoreDescriptor::NameRegister()); // Key. |
| 2747 __ pop(StoreDescriptor::ReceiverRegister()); | 2782 __ pop(StoreDescriptor::ReceiverRegister()); |
| 2748 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2783 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
| 2749 // Record source code position before IC call. | 2784 // Record source code position before IC call. |
| 2750 SetSourcePosition(expr->position()); | 2785 SetSourcePosition(expr->position()); |
| 2751 Handle<Code> ic = | 2786 Handle<Code> ic = |
| 2752 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2787 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2753 CallIC(ic, expr->AssignmentFeedbackId()); | 2788 if (FLAG_vector_stores) { |
| 2789 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2790 CallIC(ic); |
| 2791 } else { |
| 2792 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2793 } |
| 2754 | 2794 |
| 2755 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2795 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2756 context()->Plug(eax); | 2796 context()->Plug(eax); |
| 2757 } | 2797 } |
| 2758 | 2798 |
| 2759 | 2799 |
| 2760 void FullCodeGenerator::VisitProperty(Property* expr) { | 2800 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2761 Comment cmnt(masm_, "[ Property"); | 2801 Comment cmnt(masm_, "[ Property"); |
| 2762 Expression* key = expr->key(); | 2802 Expression* key = expr->key(); |
| 2763 | 2803 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2976 } | 3016 } |
| 2977 | 3017 |
| 2978 | 3018 |
| 2979 void FullCodeGenerator::EmitLoadSuperConstructor() { | 3019 void FullCodeGenerator::EmitLoadSuperConstructor() { |
| 2980 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3020 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2981 __ CallRuntime(Runtime::kGetPrototype, 1); | 3021 __ CallRuntime(Runtime::kGetPrototype, 1); |
| 2982 } | 3022 } |
| 2983 | 3023 |
| 2984 | 3024 |
| 2985 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3025 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 2986 SuperReference* super_ref) { | 3026 SuperReference* super_ref, FeedbackVectorICSlot slot) { |
| 2987 Variable* this_var = super_ref->this_var()->var(); | 3027 Variable* this_var = super_ref->this_var()->var(); |
| 2988 GetVar(ecx, this_var); | 3028 GetVar(ecx, this_var); |
| 2989 __ cmp(ecx, isolate()->factory()->the_hole_value()); | 3029 __ cmp(ecx, isolate()->factory()->the_hole_value()); |
| 2990 Label uninitialized_this; | 3030 Label uninitialized_this; |
| 2991 __ j(equal, &uninitialized_this); | 3031 __ j(equal, &uninitialized_this); |
| 2992 __ push(Immediate(this_var->name())); | 3032 __ push(Immediate(this_var->name())); |
| 2993 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3033 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2994 __ bind(&uninitialized_this); | 3034 __ bind(&uninitialized_this); |
| 2995 | 3035 |
| 2996 EmitVariableAssignment(this_var, Token::INIT_CONST); | 3036 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
| 2997 } | 3037 } |
| 2998 | 3038 |
| 2999 | 3039 |
| 3000 void FullCodeGenerator::VisitCall(Call* expr) { | 3040 void FullCodeGenerator::VisitCall(Call* expr) { |
| 3001 #ifdef DEBUG | 3041 #ifdef DEBUG |
| 3002 // We want to verify that RecordJSReturnSite gets called on all paths | 3042 // We want to verify that RecordJSReturnSite gets called on all paths |
| 3003 // through this function. Avoid early returns. | 3043 // through this function. Avoid early returns. |
| 3004 expr->return_is_recorded_ = false; | 3044 expr->return_is_recorded_ = false; |
| 3005 #endif | 3045 #endif |
| 3006 | 3046 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3204 __ LoadHeapObject(ebx, FeedbackVector()); | 3244 __ LoadHeapObject(ebx, FeedbackVector()); |
| 3205 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); | 3245 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); |
| 3206 | 3246 |
| 3207 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3247 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
| 3208 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3248 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3209 | 3249 |
| 3210 __ Drop(1); | 3250 __ Drop(1); |
| 3211 | 3251 |
| 3212 RecordJSReturnSite(expr); | 3252 RecordJSReturnSite(expr); |
| 3213 | 3253 |
| 3214 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); | 3254 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), |
| 3255 expr->CallFeedbackICSlot()); |
| 3215 context()->Plug(eax); | 3256 context()->Plug(eax); |
| 3216 } | 3257 } |
| 3217 | 3258 |
| 3218 | 3259 |
| 3219 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3260 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 3220 ZoneList<Expression*>* args = expr->arguments(); | 3261 ZoneList<Expression*>* args = expr->arguments(); |
| 3221 DCHECK(args->length() == 1); | 3262 DCHECK(args->length() == 1); |
| 3222 | 3263 |
| 3223 VisitForAccumulatorValue(args->at(0)); | 3264 VisitForAccumulatorValue(args->at(0)); |
| 3224 | 3265 |
| (...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4538 // Push NewTarget | 4579 // Push NewTarget |
| 4539 DCHECK(args->at(2)->IsVariableProxy()); | 4580 DCHECK(args->at(2)->IsVariableProxy()); |
| 4540 VisitForStackValue(args->at(2)); | 4581 VisitForStackValue(args->at(2)); |
| 4541 | 4582 |
| 4542 EmitCallJSRuntimeFunction(call); | 4583 EmitCallJSRuntimeFunction(call); |
| 4543 | 4584 |
| 4544 // Restore context register. | 4585 // Restore context register. |
| 4545 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4586 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 4546 context()->DropAndPlug(1, eax); | 4587 context()->DropAndPlug(1, eax); |
| 4547 | 4588 |
| 4589 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
| 4548 EmitInitializeThisAfterSuper(super_reference); | 4590 EmitInitializeThisAfterSuper(super_reference); |
| 4549 } | 4591 } |
| 4550 | 4592 |
| 4551 | 4593 |
| 4552 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4594 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4553 // Push the builtins object as receiver. | 4595 // Push the builtins object as receiver. |
| 4554 __ mov(eax, GlobalObjectOperand()); | 4596 __ mov(eax, GlobalObjectOperand()); |
| 4555 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); | 4597 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); |
| 4556 | 4598 |
| 4557 // Load the function from the receiver. | 4599 // Load the function from the receiver. |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4741 } | 4783 } |
| 4742 | 4784 |
| 4743 | 4785 |
| 4744 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4786 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4745 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4787 DCHECK(expr->expression()->IsValidReferenceExpression()); |
| 4746 | 4788 |
| 4747 Comment cmnt(masm_, "[ CountOperation"); | 4789 Comment cmnt(masm_, "[ CountOperation"); |
| 4748 SetSourcePosition(expr->position()); | 4790 SetSourcePosition(expr->position()); |
| 4749 | 4791 |
| 4750 Property* prop = expr->expression()->AsProperty(); | 4792 Property* prop = expr->expression()->AsProperty(); |
| 4751 LhsKind assign_type = GetAssignType(prop); | 4793 LhsKind assign_type = Property::GetAssignType(prop); |
| 4752 | 4794 |
| 4753 // Evaluate expression and get value. | 4795 // Evaluate expression and get value. |
| 4754 if (assign_type == VARIABLE) { | 4796 if (assign_type == VARIABLE) { |
| 4755 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4797 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4756 AccumulatorValueContext context(this); | 4798 AccumulatorValueContext context(this); |
| 4757 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4799 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4758 } else { | 4800 } else { |
| 4759 // Reserve space for result of postfix operation. | 4801 // Reserve space for result of postfix operation. |
| 4760 if (expr->is_postfix() && !context()->IsEffect()) { | 4802 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4761 __ push(Immediate(Smi::FromInt(0))); | 4803 __ push(Immediate(Smi::FromInt(0))); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4907 patch_site.EmitPatchInfo(); | 4949 patch_site.EmitPatchInfo(); |
| 4908 __ bind(&done); | 4950 __ bind(&done); |
| 4909 | 4951 |
| 4910 // Store the value returned in eax. | 4952 // Store the value returned in eax. |
| 4911 switch (assign_type) { | 4953 switch (assign_type) { |
| 4912 case VARIABLE: | 4954 case VARIABLE: |
| 4913 if (expr->is_postfix()) { | 4955 if (expr->is_postfix()) { |
| 4914 // Perform the assignment as if via '='. | 4956 // Perform the assignment as if via '='. |
| 4915 { EffectContext context(this); | 4957 { EffectContext context(this); |
| 4916 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4958 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4917 Token::ASSIGN); | 4959 Token::ASSIGN, expr->CountSlot()); |
| 4918 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4960 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4919 context.Plug(eax); | 4961 context.Plug(eax); |
| 4920 } | 4962 } |
| 4921 // For all contexts except EffectContext We have the result on | 4963 // For all contexts except EffectContext We have the result on |
| 4922 // top of the stack. | 4964 // top of the stack. |
| 4923 if (!context()->IsEffect()) { | 4965 if (!context()->IsEffect()) { |
| 4924 context()->PlugTOS(); | 4966 context()->PlugTOS(); |
| 4925 } | 4967 } |
| 4926 } else { | 4968 } else { |
| 4927 // Perform the assignment as if via '='. | 4969 // Perform the assignment as if via '='. |
| 4928 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4970 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4929 Token::ASSIGN); | 4971 Token::ASSIGN, expr->CountSlot()); |
| 4930 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4972 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4931 context()->Plug(eax); | 4973 context()->Plug(eax); |
| 4932 } | 4974 } |
| 4933 break; | 4975 break; |
| 4934 case NAMED_PROPERTY: { | 4976 case NAMED_PROPERTY: { |
| 4935 __ mov(StoreDescriptor::NameRegister(), | 4977 __ mov(StoreDescriptor::NameRegister(), |
| 4936 prop->key()->AsLiteral()->value()); | 4978 prop->key()->AsLiteral()->value()); |
| 4937 __ pop(StoreDescriptor::ReceiverRegister()); | 4979 __ pop(StoreDescriptor::ReceiverRegister()); |
| 4938 CallStoreIC(expr->CountStoreFeedbackId()); | 4980 if (FLAG_vector_stores) { |
| 4981 EmitLoadStoreICSlot(expr->CountSlot()); |
| 4982 CallStoreIC(); |
| 4983 } else { |
| 4984 CallStoreIC(expr->CountStoreFeedbackId()); |
| 4985 } |
| 4939 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4986 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4940 if (expr->is_postfix()) { | 4987 if (expr->is_postfix()) { |
| 4941 if (!context()->IsEffect()) { | 4988 if (!context()->IsEffect()) { |
| 4942 context()->PlugTOS(); | 4989 context()->PlugTOS(); |
| 4943 } | 4990 } |
| 4944 } else { | 4991 } else { |
| 4945 context()->Plug(eax); | 4992 context()->Plug(eax); |
| 4946 } | 4993 } |
| 4947 break; | 4994 break; |
| 4948 } | 4995 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4966 } else { | 5013 } else { |
| 4967 context()->Plug(eax); | 5014 context()->Plug(eax); |
| 4968 } | 5015 } |
| 4969 break; | 5016 break; |
| 4970 } | 5017 } |
| 4971 case KEYED_PROPERTY: { | 5018 case KEYED_PROPERTY: { |
| 4972 __ pop(StoreDescriptor::NameRegister()); | 5019 __ pop(StoreDescriptor::NameRegister()); |
| 4973 __ pop(StoreDescriptor::ReceiverRegister()); | 5020 __ pop(StoreDescriptor::ReceiverRegister()); |
| 4974 Handle<Code> ic = | 5021 Handle<Code> ic = |
| 4975 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 5022 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 4976 CallIC(ic, expr->CountStoreFeedbackId()); | 5023 if (FLAG_vector_stores) { |
| 5024 EmitLoadStoreICSlot(expr->CountSlot()); |
| 5025 CallIC(ic); |
| 5026 } else { |
| 5027 CallIC(ic, expr->CountStoreFeedbackId()); |
| 5028 } |
| 4977 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5029 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4978 if (expr->is_postfix()) { | 5030 if (expr->is_postfix()) { |
| 4979 // Result is on the stack | 5031 // Result is on the stack |
| 4980 if (!context()->IsEffect()) { | 5032 if (!context()->IsEffect()) { |
| 4981 context()->PlugTOS(); | 5033 context()->PlugTOS(); |
| 4982 } | 5034 } |
| 4983 } else { | 5035 } else { |
| 4984 context()->Plug(eax); | 5036 context()->Plug(eax); |
| 4985 } | 5037 } |
| 4986 break; | 5038 break; |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5300 | 5352 |
| 5301 void FullCodeGenerator::ClearPendingMessage() { | 5353 void FullCodeGenerator::ClearPendingMessage() { |
| 5302 DCHECK(!result_register().is(edx)); | 5354 DCHECK(!result_register().is(edx)); |
| 5303 ExternalReference pending_message_obj = | 5355 ExternalReference pending_message_obj = |
| 5304 ExternalReference::address_of_pending_message_obj(isolate()); | 5356 ExternalReference::address_of_pending_message_obj(isolate()); |
| 5305 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 5357 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
| 5306 __ mov(Operand::StaticVariable(pending_message_obj), edx); | 5358 __ mov(Operand::StaticVariable(pending_message_obj), edx); |
| 5307 } | 5359 } |
| 5308 | 5360 |
| 5309 | 5361 |
| 5362 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { |
| 5363 DCHECK(FLAG_vector_stores && !slot.IsInvalid()); |
| 5364 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), |
| 5365 Immediate(SmiFromSlot(slot))); |
| 5366 } |
| 5367 |
| 5368 |
| 5310 #undef __ | 5369 #undef __ |
| 5311 | 5370 |
| 5312 | 5371 |
| 5313 static const byte kJnsInstruction = 0x79; | 5372 static const byte kJnsInstruction = 0x79; |
| 5314 static const byte kJnsOffset = 0x11; | 5373 static const byte kJnsOffset = 0x11; |
| 5315 static const byte kNopByteOne = 0x66; | 5374 static const byte kNopByteOne = 0x66; |
| 5316 static const byte kNopByteTwo = 0x90; | 5375 static const byte kNopByteTwo = 0x90; |
| 5317 #ifdef DEBUG | 5376 #ifdef DEBUG |
| 5318 static const byte kCallInstruction = 0xe8; | 5377 static const byte kCallInstruction = 0xe8; |
| 5319 #endif | 5378 #endif |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5383 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5442 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 5384 Assembler::target_address_at(call_target_address, | 5443 Assembler::target_address_at(call_target_address, |
| 5385 unoptimized_code)); | 5444 unoptimized_code)); |
| 5386 return OSR_AFTER_STACK_CHECK; | 5445 return OSR_AFTER_STACK_CHECK; |
| 5387 } | 5446 } |
| 5388 | 5447 |
| 5389 | 5448 |
| 5390 } } // namespace v8::internal | 5449 } } // namespace v8::internal |
| 5391 | 5450 |
| 5392 #endif // V8_TARGET_ARCH_IA32 | 5451 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |