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