| 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_X64 | 7 #if V8_TARGET_ARCH_X64 |
| 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 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1218 __ Cmp(rax, Smi::FromInt(0)); | 1218 __ Cmp(rax, Smi::FromInt(0)); |
| 1219 __ j(equal, loop_statement.continue_label()); | 1219 __ j(equal, loop_statement.continue_label()); |
| 1220 __ movp(rbx, rax); | 1220 __ movp(rbx, rax); |
| 1221 | 1221 |
| 1222 // Update the 'each' property or variable from the possibly filtered | 1222 // Update the 'each' property or variable from the possibly filtered |
| 1223 // entry in register rbx. | 1223 // entry in register rbx. |
| 1224 __ bind(&update_each); | 1224 __ bind(&update_each); |
| 1225 __ movp(result_register(), rbx); | 1225 __ movp(result_register(), rbx); |
| 1226 // Perform the assignment as if via '='. | 1226 // Perform the assignment as if via '='. |
| 1227 { EffectContext context(this); | 1227 { EffectContext context(this); |
| 1228 EmitAssignment(stmt->each()); | 1228 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot()); |
| 1229 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); | 1229 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); |
| 1230 } | 1230 } |
| 1231 | 1231 |
| 1232 // Generate code for the body of the loop. | 1232 // Generate code for the body of the loop. |
| 1233 Visit(stmt->body()); | 1233 Visit(stmt->body()); |
| 1234 | 1234 |
| 1235 // Generate code for going to the next element by incrementing the | 1235 // Generate code for going to the next element by incrementing the |
| 1236 // index (smi) stored on top of the stack. | 1236 // index (smi) stored on top of the stack. |
| 1237 __ bind(loop_statement.continue_label()); | 1237 __ bind(loop_statement.continue_label()); |
| 1238 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); | 1238 __ SmiAddConstant(Operand(rsp, 0 * kPointerSize), Smi::FromInt(1)); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 | 1300 |
| 1301 __ Cmp(rax, isolate()->factory()->undefined_value()); | 1301 __ Cmp(rax, isolate()->factory()->undefined_value()); |
| 1302 Label done; | 1302 Label done; |
| 1303 __ j(not_equal, &done); | 1303 __ j(not_equal, &done); |
| 1304 __ CallRuntime(Runtime::kThrowNonMethodError, 0); | 1304 __ CallRuntime(Runtime::kThrowNonMethodError, 0); |
| 1305 __ bind(&done); | 1305 __ bind(&done); |
| 1306 } | 1306 } |
| 1307 | 1307 |
| 1308 | 1308 |
| 1309 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, | 1309 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, |
| 1310 int offset) { | 1310 int offset, |
| 1311 FeedbackVectorICSlot slot) { |
| 1311 if (NeedsHomeObject(initializer)) { | 1312 if (NeedsHomeObject(initializer)) { |
| 1312 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 1313 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1313 __ Move(StoreDescriptor::NameRegister(), | 1314 __ Move(StoreDescriptor::NameRegister(), |
| 1314 isolate()->factory()->home_object_symbol()); | 1315 isolate()->factory()->home_object_symbol()); |
| 1315 __ movp(StoreDescriptor::ValueRegister(), | 1316 __ movp(StoreDescriptor::ValueRegister(), |
| 1316 Operand(rsp, offset * kPointerSize)); | 1317 Operand(rsp, offset * kPointerSize)); |
| 1318 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 1317 CallStoreIC(); | 1319 CallStoreIC(); |
| 1318 } | 1320 } |
| 1319 } | 1321 } |
| 1320 | 1322 |
| 1321 | 1323 |
| 1322 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1324 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
| 1323 TypeofState typeof_state, | 1325 TypeofState typeof_state, |
| 1324 Label* slow) { | 1326 Label* slow) { |
| 1325 Register context = rsi; | 1327 Register context = rsi; |
| 1326 Register temp = rdx; | 1328 Register temp = rdx; |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1638 __ CallStub(&stub); | 1640 __ CallStub(&stub); |
| 1639 } | 1641 } |
| 1640 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); | 1642 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); |
| 1641 | 1643 |
| 1642 // If result_saved is true the result is on top of the stack. If | 1644 // If result_saved is true the result is on top of the stack. If |
| 1643 // result_saved is false the result is in rax. | 1645 // result_saved is false the result is in rax. |
| 1644 bool result_saved = false; | 1646 bool result_saved = false; |
| 1645 | 1647 |
| 1646 AccessorTable accessor_table(zone()); | 1648 AccessorTable accessor_table(zone()); |
| 1647 int property_index = 0; | 1649 int property_index = 0; |
| 1650 int store_slot_index = 0; |
| 1648 for (; property_index < expr->properties()->length(); property_index++) { | 1651 for (; property_index < expr->properties()->length(); property_index++) { |
| 1649 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1652 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1650 if (property->is_computed_name()) break; | 1653 if (property->is_computed_name()) break; |
| 1651 if (property->IsCompileTimeValue()) continue; | 1654 if (property->IsCompileTimeValue()) continue; |
| 1652 | 1655 |
| 1653 Literal* key = property->key()->AsLiteral(); | 1656 Literal* key = property->key()->AsLiteral(); |
| 1654 Expression* value = property->value(); | 1657 Expression* value = property->value(); |
| 1655 if (!result_saved) { | 1658 if (!result_saved) { |
| 1656 __ Push(rax); // Save result on the stack | 1659 __ Push(rax); // Save result on the stack |
| 1657 result_saved = true; | 1660 result_saved = true; |
| 1658 } | 1661 } |
| 1659 switch (property->kind()) { | 1662 switch (property->kind()) { |
| 1660 case ObjectLiteral::Property::CONSTANT: | 1663 case ObjectLiteral::Property::CONSTANT: |
| 1661 UNREACHABLE(); | 1664 UNREACHABLE(); |
| 1662 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1665 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1663 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 1666 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1664 // Fall through. | 1667 // Fall through. |
| 1665 case ObjectLiteral::Property::COMPUTED: | 1668 case ObjectLiteral::Property::COMPUTED: |
| 1666 // It is safe to use [[Put]] here because the boilerplate already | 1669 // It is safe to use [[Put]] here because the boilerplate already |
| 1667 // contains computed properties with an uninitialized value. | 1670 // contains computed properties with an uninitialized value. |
| 1668 if (key->value()->IsInternalizedString()) { | 1671 if (key->value()->IsInternalizedString()) { |
| 1669 if (property->emit_store()) { | 1672 if (property->emit_store()) { |
| 1670 VisitForAccumulatorValue(value); | 1673 VisitForAccumulatorValue(value); |
| 1671 DCHECK(StoreDescriptor::ValueRegister().is(rax)); | 1674 DCHECK(StoreDescriptor::ValueRegister().is(rax)); |
| 1672 __ Move(StoreDescriptor::NameRegister(), key->value()); | 1675 __ Move(StoreDescriptor::NameRegister(), key->value()); |
| 1673 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 1676 __ movp(StoreDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1674 CallStoreIC(key->LiteralFeedbackId()); | 1677 if (FLAG_vector_stores) { |
| 1678 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1679 CallStoreIC(); |
| 1680 } else { |
| 1681 CallStoreIC(key->LiteralFeedbackId()); |
| 1682 } |
| 1675 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1683 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1676 | 1684 |
| 1677 if (NeedsHomeObject(value)) { | 1685 if (NeedsHomeObject(value)) { |
| 1678 __ movp(StoreDescriptor::ReceiverRegister(), rax); | 1686 __ movp(StoreDescriptor::ReceiverRegister(), rax); |
| 1679 __ Move(StoreDescriptor::NameRegister(), | 1687 __ Move(StoreDescriptor::NameRegister(), |
| 1680 isolate()->factory()->home_object_symbol()); | 1688 isolate()->factory()->home_object_symbol()); |
| 1681 __ movp(StoreDescriptor::ValueRegister(), Operand(rsp, 0)); | 1689 __ movp(StoreDescriptor::ValueRegister(), Operand(rsp, 0)); |
| 1690 if (FLAG_vector_stores) { |
| 1691 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1692 } |
| 1682 CallStoreIC(); | 1693 CallStoreIC(); |
| 1683 } | 1694 } |
| 1684 } else { | 1695 } else { |
| 1685 VisitForEffect(value); | 1696 VisitForEffect(value); |
| 1686 } | 1697 } |
| 1687 break; | 1698 break; |
| 1688 } | 1699 } |
| 1689 __ Push(Operand(rsp, 0)); // Duplicate receiver. | 1700 __ Push(Operand(rsp, 0)); // Duplicate receiver. |
| 1690 VisitForStackValue(key); | 1701 VisitForStackValue(key); |
| 1691 VisitForStackValue(value); | 1702 VisitForStackValue(value); |
| 1692 if (property->emit_store()) { | 1703 if (property->emit_store()) { |
| 1693 EmitSetHomeObjectIfNeeded(value, 2); | 1704 EmitSetHomeObjectIfNeeded( |
| 1705 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1694 __ Push(Smi::FromInt(SLOPPY)); // Language mode | 1706 __ Push(Smi::FromInt(SLOPPY)); // Language mode |
| 1695 __ CallRuntime(Runtime::kSetProperty, 4); | 1707 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1696 } else { | 1708 } else { |
| 1697 __ Drop(3); | 1709 __ Drop(3); |
| 1698 } | 1710 } |
| 1699 break; | 1711 break; |
| 1700 case ObjectLiteral::Property::PROTOTYPE: | 1712 case ObjectLiteral::Property::PROTOTYPE: |
| 1701 __ Push(Operand(rsp, 0)); // Duplicate receiver. | 1713 __ Push(Operand(rsp, 0)); // Duplicate receiver. |
| 1702 VisitForStackValue(value); | 1714 VisitForStackValue(value); |
| 1703 DCHECK(property->emit_store()); | 1715 DCHECK(property->emit_store()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1717 } | 1729 } |
| 1718 | 1730 |
| 1719 // Emit code to define accessors, using only a single call to the runtime for | 1731 // Emit code to define accessors, using only a single call to the runtime for |
| 1720 // each pair of corresponding getters and setters. | 1732 // each pair of corresponding getters and setters. |
| 1721 for (AccessorTable::Iterator it = accessor_table.begin(); | 1733 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1722 it != accessor_table.end(); | 1734 it != accessor_table.end(); |
| 1723 ++it) { | 1735 ++it) { |
| 1724 __ Push(Operand(rsp, 0)); // Duplicate receiver. | 1736 __ Push(Operand(rsp, 0)); // Duplicate receiver. |
| 1725 VisitForStackValue(it->first); | 1737 VisitForStackValue(it->first); |
| 1726 EmitAccessor(it->second->getter); | 1738 EmitAccessor(it->second->getter); |
| 1727 EmitSetHomeObjectIfNeeded(it->second->getter, 2); | 1739 EmitSetHomeObjectIfNeeded( |
| 1740 it->second->getter, 2, |
| 1741 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); |
| 1728 EmitAccessor(it->second->setter); | 1742 EmitAccessor(it->second->setter); |
| 1729 EmitSetHomeObjectIfNeeded(it->second->setter, 3); | 1743 EmitSetHomeObjectIfNeeded( |
| 1744 it->second->setter, 3, |
| 1745 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); |
| 1730 __ Push(Smi::FromInt(NONE)); | 1746 __ Push(Smi::FromInt(NONE)); |
| 1731 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1747 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1732 } | 1748 } |
| 1733 | 1749 |
| 1734 // Object literals have two parts. The "static" part on the left contains no | 1750 // Object literals have two parts. The "static" part on the left contains no |
| 1735 // computed property names, and so we can compute its map ahead of time; see | 1751 // computed property names, and so we can compute its map ahead of time; see |
| 1736 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1752 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1737 // starts with the first computed property name, and continues with all | 1753 // starts with the first computed property name, and continues with all |
| 1738 // properties to its right. All the code from above initializes the static | 1754 // properties to its right. All the code from above initializes the static |
| 1739 // component of the object literal, and arranges for the map of the result to | 1755 // component of the object literal, and arranges for the map of the result to |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1752 __ Push(Operand(rsp, 0)); // Duplicate receiver. | 1768 __ Push(Operand(rsp, 0)); // Duplicate receiver. |
| 1753 | 1769 |
| 1754 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1770 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1755 DCHECK(!property->is_computed_name()); | 1771 DCHECK(!property->is_computed_name()); |
| 1756 VisitForStackValue(value); | 1772 VisitForStackValue(value); |
| 1757 DCHECK(property->emit_store()); | 1773 DCHECK(property->emit_store()); |
| 1758 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1774 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1759 } else { | 1775 } else { |
| 1760 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1776 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1761 VisitForStackValue(value); | 1777 VisitForStackValue(value); |
| 1762 EmitSetHomeObjectIfNeeded(value, 2); | 1778 EmitSetHomeObjectIfNeeded( |
| 1779 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1763 | 1780 |
| 1764 switch (property->kind()) { | 1781 switch (property->kind()) { |
| 1765 case ObjectLiteral::Property::CONSTANT: | 1782 case ObjectLiteral::Property::CONSTANT: |
| 1766 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1783 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1767 case ObjectLiteral::Property::COMPUTED: | 1784 case ObjectLiteral::Property::COMPUTED: |
| 1768 if (property->emit_store()) { | 1785 if (property->emit_store()) { |
| 1769 __ Push(Smi::FromInt(NONE)); | 1786 __ Push(Smi::FromInt(NONE)); |
| 1770 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1787 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1771 } else { | 1788 } else { |
| 1772 __ Drop(3); | 1789 __ Drop(3); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1914 } | 1931 } |
| 1915 } | 1932 } |
| 1916 | 1933 |
| 1917 | 1934 |
| 1918 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1935 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
| 1919 DCHECK(expr->target()->IsValidReferenceExpression()); | 1936 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1920 | 1937 |
| 1921 Comment cmnt(masm_, "[ Assignment"); | 1938 Comment cmnt(masm_, "[ Assignment"); |
| 1922 | 1939 |
| 1923 Property* property = expr->target()->AsProperty(); | 1940 Property* property = expr->target()->AsProperty(); |
| 1924 LhsKind assign_type = GetAssignType(property); | 1941 LhsKind assign_type = Property::GetAssignType(property); |
| 1925 | 1942 |
| 1926 // Evaluate LHS expression. | 1943 // Evaluate LHS expression. |
| 1927 switch (assign_type) { | 1944 switch (assign_type) { |
| 1928 case VARIABLE: | 1945 case VARIABLE: |
| 1929 // Nothing to do here. | 1946 // Nothing to do here. |
| 1930 break; | 1947 break; |
| 1931 case NAMED_PROPERTY: | 1948 case NAMED_PROPERTY: |
| 1932 if (expr->is_compound()) { | 1949 if (expr->is_compound()) { |
| 1933 // We need the receiver both on the stack and in the register. | 1950 // We need the receiver both on the stack and in the register. |
| 1934 VisitForStackValue(property->obj()); | 1951 VisitForStackValue(property->obj()); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2020 VisitForAccumulatorValue(expr->value()); | 2037 VisitForAccumulatorValue(expr->value()); |
| 2021 } | 2038 } |
| 2022 | 2039 |
| 2023 // Record source position before possible IC call. | 2040 // Record source position before possible IC call. |
| 2024 SetSourcePosition(expr->position()); | 2041 SetSourcePosition(expr->position()); |
| 2025 | 2042 |
| 2026 // Store the value. | 2043 // Store the value. |
| 2027 switch (assign_type) { | 2044 switch (assign_type) { |
| 2028 case VARIABLE: | 2045 case VARIABLE: |
| 2029 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2046 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 2030 expr->op()); | 2047 expr->op(), expr->AssignmentSlot()); |
| 2031 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2048 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2032 context()->Plug(rax); | 2049 context()->Plug(rax); |
| 2033 break; | 2050 break; |
| 2034 case NAMED_PROPERTY: | 2051 case NAMED_PROPERTY: |
| 2035 EmitNamedPropertyAssignment(expr); | 2052 EmitNamedPropertyAssignment(expr); |
| 2036 break; | 2053 break; |
| 2037 case NAMED_SUPER_PROPERTY: | 2054 case NAMED_SUPER_PROPERTY: |
| 2038 EmitNamedSuperPropertyStore(property); | 2055 EmitNamedSuperPropertyStore(property); |
| 2039 context()->Plug(rax); | 2056 context()->Plug(rax); |
| 2040 break; | 2057 break; |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2507 __ Pop(rdx); | 2524 __ Pop(rdx); |
| 2508 Handle<Code> code = CodeFactory::BinaryOpIC( | 2525 Handle<Code> code = CodeFactory::BinaryOpIC( |
| 2509 isolate(), op, language_mode()).code(); | 2526 isolate(), op, language_mode()).code(); |
| 2510 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2527 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2511 CallIC(code, expr->BinaryOperationFeedbackId()); | 2528 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2512 patch_site.EmitPatchInfo(); | 2529 patch_site.EmitPatchInfo(); |
| 2513 context()->Plug(rax); | 2530 context()->Plug(rax); |
| 2514 } | 2531 } |
| 2515 | 2532 |
| 2516 | 2533 |
| 2517 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2534 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 2535 FeedbackVectorICSlot slot) { |
| 2518 DCHECK(expr->IsValidReferenceExpression()); | 2536 DCHECK(expr->IsValidReferenceExpression()); |
| 2519 | 2537 |
| 2520 Property* prop = expr->AsProperty(); | 2538 Property* prop = expr->AsProperty(); |
| 2521 LhsKind assign_type = GetAssignType(prop); | 2539 LhsKind assign_type = Property::GetAssignType(prop); |
| 2522 | 2540 |
| 2523 switch (assign_type) { | 2541 switch (assign_type) { |
| 2524 case VARIABLE: { | 2542 case VARIABLE: { |
| 2525 Variable* var = expr->AsVariableProxy()->var(); | 2543 Variable* var = expr->AsVariableProxy()->var(); |
| 2526 EffectContext context(this); | 2544 EffectContext context(this); |
| 2527 EmitVariableAssignment(var, Token::ASSIGN); | 2545 EmitVariableAssignment(var, Token::ASSIGN, slot); |
| 2528 break; | 2546 break; |
| 2529 } | 2547 } |
| 2530 case NAMED_PROPERTY: { | 2548 case NAMED_PROPERTY: { |
| 2531 __ Push(rax); // Preserve value. | 2549 __ Push(rax); // Preserve value. |
| 2532 VisitForAccumulatorValue(prop->obj()); | 2550 VisitForAccumulatorValue(prop->obj()); |
| 2533 __ Move(StoreDescriptor::ReceiverRegister(), rax); | 2551 __ Move(StoreDescriptor::ReceiverRegister(), rax); |
| 2534 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. | 2552 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2535 __ Move(StoreDescriptor::NameRegister(), | 2553 __ Move(StoreDescriptor::NameRegister(), |
| 2536 prop->key()->AsLiteral()->value()); | 2554 prop->key()->AsLiteral()->value()); |
| 2555 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2537 CallStoreIC(); | 2556 CallStoreIC(); |
| 2538 break; | 2557 break; |
| 2539 } | 2558 } |
| 2540 case NAMED_SUPER_PROPERTY: { | 2559 case NAMED_SUPER_PROPERTY: { |
| 2541 __ Push(rax); | 2560 __ Push(rax); |
| 2542 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 2561 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 2543 EmitLoadHomeObject(prop->obj()->AsSuperReference()); | 2562 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 2544 // stack: value, this; rax: home_object | 2563 // stack: value, this; rax: home_object |
| 2545 Register scratch = rcx; | 2564 Register scratch = rcx; |
| 2546 Register scratch2 = rdx; | 2565 Register scratch2 = rdx; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2573 EmitKeyedSuperPropertyStore(prop); | 2592 EmitKeyedSuperPropertyStore(prop); |
| 2574 break; | 2593 break; |
| 2575 } | 2594 } |
| 2576 case KEYED_PROPERTY: { | 2595 case KEYED_PROPERTY: { |
| 2577 __ Push(rax); // Preserve value. | 2596 __ Push(rax); // Preserve value. |
| 2578 VisitForStackValue(prop->obj()); | 2597 VisitForStackValue(prop->obj()); |
| 2579 VisitForAccumulatorValue(prop->key()); | 2598 VisitForAccumulatorValue(prop->key()); |
| 2580 __ Move(StoreDescriptor::NameRegister(), rax); | 2599 __ Move(StoreDescriptor::NameRegister(), rax); |
| 2581 __ Pop(StoreDescriptor::ReceiverRegister()); | 2600 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 2582 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. | 2601 __ Pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2602 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2583 Handle<Code> ic = | 2603 Handle<Code> ic = |
| 2584 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2604 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2585 CallIC(ic); | 2605 CallIC(ic); |
| 2586 break; | 2606 break; |
| 2587 } | 2607 } |
| 2588 } | 2608 } |
| 2589 context()->Plug(rax); | 2609 context()->Plug(rax); |
| 2590 } | 2610 } |
| 2591 | 2611 |
| 2592 | 2612 |
| 2593 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2613 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 2594 Variable* var, MemOperand location) { | 2614 Variable* var, MemOperand location) { |
| 2595 __ movp(location, rax); | 2615 __ movp(location, rax); |
| 2596 if (var->IsContextSlot()) { | 2616 if (var->IsContextSlot()) { |
| 2597 __ movp(rdx, rax); | 2617 __ movp(rdx, rax); |
| 2598 __ RecordWriteContextSlot( | 2618 __ RecordWriteContextSlot( |
| 2599 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); | 2619 rcx, Context::SlotOffset(var->index()), rdx, rbx, kDontSaveFPRegs); |
| 2600 } | 2620 } |
| 2601 } | 2621 } |
| 2602 | 2622 |
| 2603 | 2623 |
| 2604 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2624 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2605 Token::Value op) { | 2625 FeedbackVectorICSlot slot) { |
| 2606 if (var->IsUnallocated()) { | 2626 if (var->IsUnallocated()) { |
| 2607 // Global var, const, or let. | 2627 // Global var, const, or let. |
| 2608 __ Move(StoreDescriptor::NameRegister(), var->name()); | 2628 __ Move(StoreDescriptor::NameRegister(), var->name()); |
| 2609 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2629 __ movp(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2630 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2610 CallStoreIC(); | 2631 CallStoreIC(); |
| 2611 | 2632 |
| 2612 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2633 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2613 // Non-initializing assignment to let variable needs a write barrier. | 2634 // Non-initializing assignment to let variable needs a write barrier. |
| 2614 DCHECK(!var->IsLookupSlot()); | 2635 DCHECK(!var->IsLookupSlot()); |
| 2615 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2636 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2616 Label assign; | 2637 Label assign; |
| 2617 MemOperand location = VarOperand(var, rcx); | 2638 MemOperand location = VarOperand(var, rcx); |
| 2618 __ movp(rdx, location); | 2639 __ movp(rdx, location); |
| 2619 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); | 2640 __ CompareRoot(rdx, Heap::kTheHoleValueRootIndex); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2692 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2713 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2693 // Assignment to a property, using a named store IC. | 2714 // Assignment to a property, using a named store IC. |
| 2694 Property* prop = expr->target()->AsProperty(); | 2715 Property* prop = expr->target()->AsProperty(); |
| 2695 DCHECK(prop != NULL); | 2716 DCHECK(prop != NULL); |
| 2696 DCHECK(prop->key()->IsLiteral()); | 2717 DCHECK(prop->key()->IsLiteral()); |
| 2697 | 2718 |
| 2698 // Record source code position before IC call. | 2719 // Record source code position before IC call. |
| 2699 SetSourcePosition(expr->position()); | 2720 SetSourcePosition(expr->position()); |
| 2700 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2721 __ Move(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
| 2701 __ Pop(StoreDescriptor::ReceiverRegister()); | 2722 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 2702 CallStoreIC(expr->AssignmentFeedbackId()); | 2723 if (FLAG_vector_stores) { |
| 2724 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2725 CallStoreIC(); |
| 2726 } else { |
| 2727 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2728 } |
| 2703 | 2729 |
| 2704 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2730 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2705 context()->Plug(rax); | 2731 context()->Plug(rax); |
| 2706 } | 2732 } |
| 2707 | 2733 |
| 2708 | 2734 |
| 2709 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2735 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2710 // Assignment to named property of super. | 2736 // Assignment to named property of super. |
| 2711 // rax : value | 2737 // rax : value |
| 2712 // stack : receiver ('this'), home_object | 2738 // stack : receiver ('this'), home_object |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2739 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2765 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2740 // Assignment to a property, using a keyed store IC. | 2766 // Assignment to a property, using a keyed store IC. |
| 2741 | 2767 |
| 2742 __ Pop(StoreDescriptor::NameRegister()); // Key. | 2768 __ Pop(StoreDescriptor::NameRegister()); // Key. |
| 2743 __ Pop(StoreDescriptor::ReceiverRegister()); | 2769 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 2744 DCHECK(StoreDescriptor::ValueRegister().is(rax)); | 2770 DCHECK(StoreDescriptor::ValueRegister().is(rax)); |
| 2745 // Record source code position before IC call. | 2771 // Record source code position before IC call. |
| 2746 SetSourcePosition(expr->position()); | 2772 SetSourcePosition(expr->position()); |
| 2747 Handle<Code> ic = | 2773 Handle<Code> ic = |
| 2748 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2774 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2749 CallIC(ic, expr->AssignmentFeedbackId()); | 2775 if (FLAG_vector_stores) { |
| 2776 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2777 CallIC(ic); |
| 2778 } else { |
| 2779 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2780 } |
| 2750 | 2781 |
| 2751 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2782 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2752 context()->Plug(rax); | 2783 context()->Plug(rax); |
| 2753 } | 2784 } |
| 2754 | 2785 |
| 2755 | 2786 |
| 2756 void FullCodeGenerator::VisitProperty(Property* expr) { | 2787 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2757 Comment cmnt(masm_, "[ Property"); | 2788 Comment cmnt(masm_, "[ Property"); |
| 2758 Expression* key = expr->key(); | 2789 Expression* key = expr->key(); |
| 2759 | 2790 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2977 } | 3008 } |
| 2978 | 3009 |
| 2979 | 3010 |
| 2980 void FullCodeGenerator::EmitLoadSuperConstructor() { | 3011 void FullCodeGenerator::EmitLoadSuperConstructor() { |
| 2981 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); | 3012 __ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2982 __ CallRuntime(Runtime::kGetPrototype, 1); | 3013 __ CallRuntime(Runtime::kGetPrototype, 1); |
| 2983 } | 3014 } |
| 2984 | 3015 |
| 2985 | 3016 |
| 2986 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3017 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 2987 SuperReference* super_ref) { | 3018 SuperReference* super_ref, FeedbackVectorICSlot slot) { |
| 2988 Variable* this_var = super_ref->this_var()->var(); | 3019 Variable* this_var = super_ref->this_var()->var(); |
| 2989 GetVar(rcx, this_var); | 3020 GetVar(rcx, this_var); |
| 2990 __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex); | 3021 __ CompareRoot(rcx, Heap::kTheHoleValueRootIndex); |
| 2991 Label uninitialized_this; | 3022 Label uninitialized_this; |
| 2992 __ j(equal, &uninitialized_this); | 3023 __ j(equal, &uninitialized_this); |
| 2993 __ Push(this_var->name()); | 3024 __ Push(this_var->name()); |
| 2994 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3025 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2995 __ bind(&uninitialized_this); | 3026 __ bind(&uninitialized_this); |
| 2996 | 3027 |
| 2997 EmitVariableAssignment(this_var, Token::INIT_CONST); | 3028 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
| 2998 } | 3029 } |
| 2999 | 3030 |
| 3000 | 3031 |
| 3001 void FullCodeGenerator::VisitCall(Call* expr) { | 3032 void FullCodeGenerator::VisitCall(Call* expr) { |
| 3002 #ifdef DEBUG | 3033 #ifdef DEBUG |
| 3003 // We want to verify that RecordJSReturnSite gets called on all paths | 3034 // We want to verify that RecordJSReturnSite gets called on all paths |
| 3004 // through this function. Avoid early returns. | 3035 // through this function. Avoid early returns. |
| 3005 expr->return_is_recorded_ = false; | 3036 expr->return_is_recorded_ = false; |
| 3006 #endif | 3037 #endif |
| 3007 | 3038 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3205 __ Move(rbx, FeedbackVector()); | 3236 __ Move(rbx, FeedbackVector()); |
| 3206 __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot())); | 3237 __ Move(rdx, SmiFromSlot(expr->CallFeedbackSlot())); |
| 3207 | 3238 |
| 3208 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3239 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
| 3209 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3240 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3210 | 3241 |
| 3211 __ Drop(1); | 3242 __ Drop(1); |
| 3212 | 3243 |
| 3213 RecordJSReturnSite(expr); | 3244 RecordJSReturnSite(expr); |
| 3214 | 3245 |
| 3215 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); | 3246 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), |
| 3247 expr->CallFeedbackICSlot()); |
| 3216 context()->Plug(rax); | 3248 context()->Plug(rax); |
| 3217 } | 3249 } |
| 3218 | 3250 |
| 3219 | 3251 |
| 3220 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3252 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 3221 ZoneList<Expression*>* args = expr->arguments(); | 3253 ZoneList<Expression*>* args = expr->arguments(); |
| 3222 DCHECK(args->length() == 1); | 3254 DCHECK(args->length() == 1); |
| 3223 | 3255 |
| 3224 VisitForAccumulatorValue(args->at(0)); | 3256 VisitForAccumulatorValue(args->at(0)); |
| 3225 | 3257 |
| (...skipping 1332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4558 // Push NewTarget | 4590 // Push NewTarget |
| 4559 DCHECK(args->at(2)->IsVariableProxy()); | 4591 DCHECK(args->at(2)->IsVariableProxy()); |
| 4560 VisitForStackValue(args->at(2)); | 4592 VisitForStackValue(args->at(2)); |
| 4561 | 4593 |
| 4562 EmitCallJSRuntimeFunction(call); | 4594 EmitCallJSRuntimeFunction(call); |
| 4563 | 4595 |
| 4564 // Restore context register. | 4596 // Restore context register. |
| 4565 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 4597 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 4566 context()->DropAndPlug(1, rax); | 4598 context()->DropAndPlug(1, rax); |
| 4567 | 4599 |
| 4600 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
| 4568 EmitInitializeThisAfterSuper(super_reference); | 4601 EmitInitializeThisAfterSuper(super_reference); |
| 4569 } | 4602 } |
| 4570 | 4603 |
| 4571 | 4604 |
| 4572 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4605 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4573 // Push the builtins object as receiver. | 4606 // Push the builtins object as receiver. |
| 4574 __ movp(rax, GlobalObjectOperand()); | 4607 __ movp(rax, GlobalObjectOperand()); |
| 4575 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); | 4608 __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); |
| 4576 | 4609 |
| 4577 // Load the function from the receiver. | 4610 // Load the function from the receiver. |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4762 } | 4795 } |
| 4763 | 4796 |
| 4764 | 4797 |
| 4765 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4798 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4766 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4799 DCHECK(expr->expression()->IsValidReferenceExpression()); |
| 4767 | 4800 |
| 4768 Comment cmnt(masm_, "[ CountOperation"); | 4801 Comment cmnt(masm_, "[ CountOperation"); |
| 4769 SetSourcePosition(expr->position()); | 4802 SetSourcePosition(expr->position()); |
| 4770 | 4803 |
| 4771 Property* prop = expr->expression()->AsProperty(); | 4804 Property* prop = expr->expression()->AsProperty(); |
| 4772 LhsKind assign_type = GetAssignType(prop); | 4805 LhsKind assign_type = Property::GetAssignType(prop); |
| 4773 | 4806 |
| 4774 // Evaluate expression and get value. | 4807 // Evaluate expression and get value. |
| 4775 if (assign_type == VARIABLE) { | 4808 if (assign_type == VARIABLE) { |
| 4776 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4809 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4777 AccumulatorValueContext context(this); | 4810 AccumulatorValueContext context(this); |
| 4778 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4811 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4779 } else { | 4812 } else { |
| 4780 // Reserve space for result of postfix operation. | 4813 // Reserve space for result of postfix operation. |
| 4781 if (expr->is_postfix() && !context()->IsEffect()) { | 4814 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4782 __ Push(Smi::FromInt(0)); | 4815 __ Push(Smi::FromInt(0)); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4924 patch_site.EmitPatchInfo(); | 4957 patch_site.EmitPatchInfo(); |
| 4925 __ bind(&done); | 4958 __ bind(&done); |
| 4926 | 4959 |
| 4927 // Store the value returned in rax. | 4960 // Store the value returned in rax. |
| 4928 switch (assign_type) { | 4961 switch (assign_type) { |
| 4929 case VARIABLE: | 4962 case VARIABLE: |
| 4930 if (expr->is_postfix()) { | 4963 if (expr->is_postfix()) { |
| 4931 // Perform the assignment as if via '='. | 4964 // Perform the assignment as if via '='. |
| 4932 { EffectContext context(this); | 4965 { EffectContext context(this); |
| 4933 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4966 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4934 Token::ASSIGN); | 4967 Token::ASSIGN, expr->CountSlot()); |
| 4935 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4968 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4936 context.Plug(rax); | 4969 context.Plug(rax); |
| 4937 } | 4970 } |
| 4938 // For all contexts except kEffect: We have the result on | 4971 // For all contexts except kEffect: We have the result on |
| 4939 // top of the stack. | 4972 // top of the stack. |
| 4940 if (!context()->IsEffect()) { | 4973 if (!context()->IsEffect()) { |
| 4941 context()->PlugTOS(); | 4974 context()->PlugTOS(); |
| 4942 } | 4975 } |
| 4943 } else { | 4976 } else { |
| 4944 // Perform the assignment as if via '='. | 4977 // Perform the assignment as if via '='. |
| 4945 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4978 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4946 Token::ASSIGN); | 4979 Token::ASSIGN, expr->CountSlot()); |
| 4947 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4980 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4948 context()->Plug(rax); | 4981 context()->Plug(rax); |
| 4949 } | 4982 } |
| 4950 break; | 4983 break; |
| 4951 case NAMED_PROPERTY: { | 4984 case NAMED_PROPERTY: { |
| 4952 __ Move(StoreDescriptor::NameRegister(), | 4985 __ Move(StoreDescriptor::NameRegister(), |
| 4953 prop->key()->AsLiteral()->value()); | 4986 prop->key()->AsLiteral()->value()); |
| 4954 __ Pop(StoreDescriptor::ReceiverRegister()); | 4987 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4955 CallStoreIC(expr->CountStoreFeedbackId()); | 4988 if (FLAG_vector_stores) { |
| 4989 EmitLoadStoreICSlot(expr->CountSlot()); |
| 4990 CallStoreIC(); |
| 4991 } else { |
| 4992 CallStoreIC(expr->CountStoreFeedbackId()); |
| 4993 } |
| 4956 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4994 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4957 if (expr->is_postfix()) { | 4995 if (expr->is_postfix()) { |
| 4958 if (!context()->IsEffect()) { | 4996 if (!context()->IsEffect()) { |
| 4959 context()->PlugTOS(); | 4997 context()->PlugTOS(); |
| 4960 } | 4998 } |
| 4961 } else { | 4999 } else { |
| 4962 context()->Plug(rax); | 5000 context()->Plug(rax); |
| 4963 } | 5001 } |
| 4964 break; | 5002 break; |
| 4965 } | 5003 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4983 } else { | 5021 } else { |
| 4984 context()->Plug(rax); | 5022 context()->Plug(rax); |
| 4985 } | 5023 } |
| 4986 break; | 5024 break; |
| 4987 } | 5025 } |
| 4988 case KEYED_PROPERTY: { | 5026 case KEYED_PROPERTY: { |
| 4989 __ Pop(StoreDescriptor::NameRegister()); | 5027 __ Pop(StoreDescriptor::NameRegister()); |
| 4990 __ Pop(StoreDescriptor::ReceiverRegister()); | 5028 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4991 Handle<Code> ic = | 5029 Handle<Code> ic = |
| 4992 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 5030 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 4993 CallIC(ic, expr->CountStoreFeedbackId()); | 5031 if (FLAG_vector_stores) { |
| 5032 EmitLoadStoreICSlot(expr->CountSlot()); |
| 5033 CallIC(ic); |
| 5034 } else { |
| 5035 CallIC(ic, expr->CountStoreFeedbackId()); |
| 5036 } |
| 4994 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5037 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4995 if (expr->is_postfix()) { | 5038 if (expr->is_postfix()) { |
| 4996 if (!context()->IsEffect()) { | 5039 if (!context()->IsEffect()) { |
| 4997 context()->PlugTOS(); | 5040 context()->PlugTOS(); |
| 4998 } | 5041 } |
| 4999 } else { | 5042 } else { |
| 5000 context()->Plug(rax); | 5043 context()->Plug(rax); |
| 5001 } | 5044 } |
| 5002 break; | 5045 break; |
| 5003 } | 5046 } |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5318 | 5361 |
| 5319 void FullCodeGenerator::ClearPendingMessage() { | 5362 void FullCodeGenerator::ClearPendingMessage() { |
| 5320 DCHECK(!result_register().is(rdx)); | 5363 DCHECK(!result_register().is(rdx)); |
| 5321 ExternalReference pending_message_obj = | 5364 ExternalReference pending_message_obj = |
| 5322 ExternalReference::address_of_pending_message_obj(isolate()); | 5365 ExternalReference::address_of_pending_message_obj(isolate()); |
| 5323 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex); | 5366 __ LoadRoot(rdx, Heap::kTheHoleValueRootIndex); |
| 5324 __ Store(pending_message_obj, rdx); | 5367 __ Store(pending_message_obj, rdx); |
| 5325 } | 5368 } |
| 5326 | 5369 |
| 5327 | 5370 |
| 5371 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { |
| 5372 DCHECK(FLAG_vector_stores && !slot.IsInvalid()); |
| 5373 __ Move(VectorStoreICTrampolineDescriptor::SlotRegister(), SmiFromSlot(slot)); |
| 5374 } |
| 5375 |
| 5376 |
| 5328 #undef __ | 5377 #undef __ |
| 5329 | 5378 |
| 5330 | 5379 |
| 5331 static const byte kJnsInstruction = 0x79; | 5380 static const byte kJnsInstruction = 0x79; |
| 5332 static const byte kNopByteOne = 0x66; | 5381 static const byte kNopByteOne = 0x66; |
| 5333 static const byte kNopByteTwo = 0x90; | 5382 static const byte kNopByteTwo = 0x90; |
| 5334 #ifdef DEBUG | 5383 #ifdef DEBUG |
| 5335 static const byte kCallInstruction = 0xe8; | 5384 static const byte kCallInstruction = 0xe8; |
| 5336 #endif | 5385 #endif |
| 5337 | 5386 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5401 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5450 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 5402 Assembler::target_address_at(call_target_address, | 5451 Assembler::target_address_at(call_target_address, |
| 5403 unoptimized_code)); | 5452 unoptimized_code)); |
| 5404 return OSR_AFTER_STACK_CHECK; | 5453 return OSR_AFTER_STACK_CHECK; |
| 5405 } | 5454 } |
| 5406 | 5455 |
| 5407 | 5456 |
| 5408 } } // namespace v8::internal | 5457 } } // namespace v8::internal |
| 5409 | 5458 |
| 5410 #endif // V8_TARGET_ARCH_X64 | 5459 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |