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 |