| 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 int store_slot_index = 0; |
| 1616 for (; property_index < expr->properties()->length(); property_index++) { | 1619 for (; property_index < expr->properties()->length(); property_index++) { |
| 1617 ObjectLiteral::Property* property = expr->properties()->at(property_index); | 1620 ObjectLiteral::Property* property = expr->properties()->at(property_index); |
| 1618 if (property->is_computed_name()) break; | 1621 if (property->is_computed_name()) break; |
| 1619 if (property->IsCompileTimeValue()) continue; | 1622 if (property->IsCompileTimeValue()) continue; |
| 1620 | 1623 |
| 1621 Literal* key = property->key()->AsLiteral(); | 1624 Literal* key = property->key()->AsLiteral(); |
| 1622 Expression* value = property->value(); | 1625 Expression* value = property->value(); |
| 1623 if (!result_saved) { | 1626 if (!result_saved) { |
| 1624 __ push(eax); // Save result on the stack | 1627 __ push(eax); // Save result on the stack |
| 1625 result_saved = true; | 1628 result_saved = true; |
| 1626 } | 1629 } |
| 1627 switch (property->kind()) { | 1630 switch (property->kind()) { |
| 1628 case ObjectLiteral::Property::CONSTANT: | 1631 case ObjectLiteral::Property::CONSTANT: |
| 1629 UNREACHABLE(); | 1632 UNREACHABLE(); |
| 1630 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1633 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1631 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); | 1634 DCHECK(!CompileTimeValue::IsCompileTimeValue(value)); |
| 1632 // Fall through. | 1635 // Fall through. |
| 1633 case ObjectLiteral::Property::COMPUTED: | 1636 case ObjectLiteral::Property::COMPUTED: |
| 1634 // It is safe to use [[Put]] here because the boilerplate already | 1637 // It is safe to use [[Put]] here because the boilerplate already |
| 1635 // contains computed properties with an uninitialized value. | 1638 // contains computed properties with an uninitialized value. |
| 1636 if (key->value()->IsInternalizedString()) { | 1639 if (key->value()->IsInternalizedString()) { |
| 1637 if (property->emit_store()) { | 1640 if (property->emit_store()) { |
| 1638 VisitForAccumulatorValue(value); | 1641 VisitForAccumulatorValue(value); |
| 1639 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 1642 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
| 1640 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); | 1643 __ mov(StoreDescriptor::NameRegister(), Immediate(key->value())); |
| 1641 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); | 1644 __ mov(StoreDescriptor::ReceiverRegister(), Operand(esp, 0)); |
| 1642 CallStoreIC(key->LiteralFeedbackId()); | 1645 if (FLAG_vector_stores) { |
| 1646 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1647 CallStoreIC(); |
| 1648 } else { |
| 1649 CallStoreIC(key->LiteralFeedbackId()); |
| 1650 } |
| 1643 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1651 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1644 | 1652 |
| 1645 if (NeedsHomeObject(value)) { | 1653 if (NeedsHomeObject(value)) { |
| 1646 __ mov(StoreDescriptor::ReceiverRegister(), eax); | 1654 __ mov(StoreDescriptor::ReceiverRegister(), eax); |
| 1647 __ mov(StoreDescriptor::NameRegister(), | 1655 __ mov(StoreDescriptor::NameRegister(), |
| 1648 Immediate(isolate()->factory()->home_object_symbol())); | 1656 Immediate(isolate()->factory()->home_object_symbol())); |
| 1649 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0)); | 1657 __ mov(StoreDescriptor::ValueRegister(), Operand(esp, 0)); |
| 1658 if (FLAG_vector_stores) { |
| 1659 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++)); |
| 1660 } |
| 1650 CallStoreIC(); | 1661 CallStoreIC(); |
| 1651 } | 1662 } |
| 1652 } else { | 1663 } else { |
| 1653 VisitForEffect(value); | 1664 VisitForEffect(value); |
| 1654 } | 1665 } |
| 1655 break; | 1666 break; |
| 1656 } | 1667 } |
| 1657 __ push(Operand(esp, 0)); // Duplicate receiver. | 1668 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1658 VisitForStackValue(key); | 1669 VisitForStackValue(key); |
| 1659 VisitForStackValue(value); | 1670 VisitForStackValue(value); |
| 1660 if (property->emit_store()) { | 1671 if (property->emit_store()) { |
| 1661 EmitSetHomeObjectIfNeeded(value, 2); | 1672 EmitSetHomeObjectIfNeeded( |
| 1673 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1662 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode | 1674 __ push(Immediate(Smi::FromInt(SLOPPY))); // Language mode |
| 1663 __ CallRuntime(Runtime::kSetProperty, 4); | 1675 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1664 } else { | 1676 } else { |
| 1665 __ Drop(3); | 1677 __ Drop(3); |
| 1666 } | 1678 } |
| 1667 break; | 1679 break; |
| 1668 case ObjectLiteral::Property::PROTOTYPE: | 1680 case ObjectLiteral::Property::PROTOTYPE: |
| 1669 __ push(Operand(esp, 0)); // Duplicate receiver. | 1681 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1670 VisitForStackValue(value); | 1682 VisitForStackValue(value); |
| 1671 DCHECK(property->emit_store()); | 1683 DCHECK(property->emit_store()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1685 } | 1697 } |
| 1686 | 1698 |
| 1687 // Emit code to define accessors, using only a single call to the runtime for | 1699 // Emit code to define accessors, using only a single call to the runtime for |
| 1688 // each pair of corresponding getters and setters. | 1700 // each pair of corresponding getters and setters. |
| 1689 for (AccessorTable::Iterator it = accessor_table.begin(); | 1701 for (AccessorTable::Iterator it = accessor_table.begin(); |
| 1690 it != accessor_table.end(); | 1702 it != accessor_table.end(); |
| 1691 ++it) { | 1703 ++it) { |
| 1692 __ push(Operand(esp, 0)); // Duplicate receiver. | 1704 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1693 VisitForStackValue(it->first); | 1705 VisitForStackValue(it->first); |
| 1694 EmitAccessor(it->second->getter); | 1706 EmitAccessor(it->second->getter); |
| 1695 EmitSetHomeObjectIfNeeded(it->second->getter, 2); | 1707 EmitSetHomeObjectIfNeeded( |
| 1708 it->second->getter, 2, |
| 1709 expr->SlotForHomeObject(it->second->getter, &store_slot_index)); |
| 1710 |
| 1696 EmitAccessor(it->second->setter); | 1711 EmitAccessor(it->second->setter); |
| 1697 EmitSetHomeObjectIfNeeded(it->second->setter, 3); | 1712 EmitSetHomeObjectIfNeeded( |
| 1713 it->second->setter, 3, |
| 1714 expr->SlotForHomeObject(it->second->setter, &store_slot_index)); |
| 1715 |
| 1698 __ push(Immediate(Smi::FromInt(NONE))); | 1716 __ push(Immediate(Smi::FromInt(NONE))); |
| 1699 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); | 1717 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); |
| 1700 } | 1718 } |
| 1701 | 1719 |
| 1702 // Object literals have two parts. The "static" part on the left contains no | 1720 // 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 | 1721 // computed property names, and so we can compute its map ahead of time; see |
| 1704 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part | 1722 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part |
| 1705 // starts with the first computed property name, and continues with all | 1723 // starts with the first computed property name, and continues with all |
| 1706 // properties to its right. All the code from above initializes the static | 1724 // 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 | 1725 // 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. | 1738 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 1721 | 1739 |
| 1722 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { | 1740 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { |
| 1723 DCHECK(!property->is_computed_name()); | 1741 DCHECK(!property->is_computed_name()); |
| 1724 VisitForStackValue(value); | 1742 VisitForStackValue(value); |
| 1725 DCHECK(property->emit_store()); | 1743 DCHECK(property->emit_store()); |
| 1726 __ CallRuntime(Runtime::kInternalSetPrototype, 2); | 1744 __ CallRuntime(Runtime::kInternalSetPrototype, 2); |
| 1727 } else { | 1745 } else { |
| 1728 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); | 1746 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); |
| 1729 VisitForStackValue(value); | 1747 VisitForStackValue(value); |
| 1730 EmitSetHomeObjectIfNeeded(value, 2); | 1748 EmitSetHomeObjectIfNeeded( |
| 1749 value, 2, expr->SlotForHomeObject(value, &store_slot_index)); |
| 1731 | 1750 |
| 1732 switch (property->kind()) { | 1751 switch (property->kind()) { |
| 1733 case ObjectLiteral::Property::CONSTANT: | 1752 case ObjectLiteral::Property::CONSTANT: |
| 1734 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1753 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1735 case ObjectLiteral::Property::COMPUTED: | 1754 case ObjectLiteral::Property::COMPUTED: |
| 1736 if (property->emit_store()) { | 1755 if (property->emit_store()) { |
| 1737 __ push(Immediate(Smi::FromInt(NONE))); | 1756 __ push(Immediate(Smi::FromInt(NONE))); |
| 1738 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); | 1757 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); |
| 1739 } else { | 1758 } else { |
| 1740 __ Drop(3); | 1759 __ Drop(3); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1882 } | 1901 } |
| 1883 } | 1902 } |
| 1884 | 1903 |
| 1885 | 1904 |
| 1886 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1905 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
| 1887 DCHECK(expr->target()->IsValidReferenceExpression()); | 1906 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1888 | 1907 |
| 1889 Comment cmnt(masm_, "[ Assignment"); | 1908 Comment cmnt(masm_, "[ Assignment"); |
| 1890 | 1909 |
| 1891 Property* property = expr->target()->AsProperty(); | 1910 Property* property = expr->target()->AsProperty(); |
| 1892 LhsKind assign_type = GetAssignType(property); | 1911 LhsKind assign_type = Property::GetAssignType(property); |
| 1893 | 1912 |
| 1894 // Evaluate LHS expression. | 1913 // Evaluate LHS expression. |
| 1895 switch (assign_type) { | 1914 switch (assign_type) { |
| 1896 case VARIABLE: | 1915 case VARIABLE: |
| 1897 // Nothing to do here. | 1916 // Nothing to do here. |
| 1898 break; | 1917 break; |
| 1899 case NAMED_SUPER_PROPERTY: | 1918 case NAMED_SUPER_PROPERTY: |
| 1900 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); | 1919 VisitForStackValue(property->obj()->AsSuperReference()->this_var()); |
| 1901 EmitLoadHomeObject(property->obj()->AsSuperReference()); | 1920 EmitLoadHomeObject(property->obj()->AsSuperReference()); |
| 1902 __ push(result_register()); | 1921 __ push(result_register()); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1989 VisitForAccumulatorValue(expr->value()); | 2008 VisitForAccumulatorValue(expr->value()); |
| 1990 } | 2009 } |
| 1991 | 2010 |
| 1992 // Record source position before possible IC call. | 2011 // Record source position before possible IC call. |
| 1993 SetSourcePosition(expr->position()); | 2012 SetSourcePosition(expr->position()); |
| 1994 | 2013 |
| 1995 // Store the value. | 2014 // Store the value. |
| 1996 switch (assign_type) { | 2015 switch (assign_type) { |
| 1997 case VARIABLE: | 2016 case VARIABLE: |
| 1998 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2017 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 1999 expr->op()); | 2018 expr->op(), expr->AssignmentSlot()); |
| 2000 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2019 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2001 context()->Plug(eax); | 2020 context()->Plug(eax); |
| 2002 break; | 2021 break; |
| 2003 case NAMED_PROPERTY: | 2022 case NAMED_PROPERTY: |
| 2004 EmitNamedPropertyAssignment(expr); | 2023 EmitNamedPropertyAssignment(expr); |
| 2005 break; | 2024 break; |
| 2006 case NAMED_SUPER_PROPERTY: | 2025 case NAMED_SUPER_PROPERTY: |
| 2007 EmitNamedSuperPropertyStore(property); | 2026 EmitNamedSuperPropertyStore(property); |
| 2008 context()->Plug(result_register()); | 2027 context()->Plug(result_register()); |
| 2009 break; | 2028 break; |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2507 __ pop(edx); | 2526 __ pop(edx); |
| 2508 Handle<Code> code = CodeFactory::BinaryOpIC( | 2527 Handle<Code> code = CodeFactory::BinaryOpIC( |
| 2509 isolate(), op, language_mode()).code(); | 2528 isolate(), op, language_mode()).code(); |
| 2510 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 2529 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 2511 CallIC(code, expr->BinaryOperationFeedbackId()); | 2530 CallIC(code, expr->BinaryOperationFeedbackId()); |
| 2512 patch_site.EmitPatchInfo(); | 2531 patch_site.EmitPatchInfo(); |
| 2513 context()->Plug(eax); | 2532 context()->Plug(eax); |
| 2514 } | 2533 } |
| 2515 | 2534 |
| 2516 | 2535 |
| 2517 void FullCodeGenerator::EmitAssignment(Expression* expr) { | 2536 void FullCodeGenerator::EmitAssignment(Expression* expr, |
| 2537 FeedbackVectorICSlot slot) { |
| 2518 DCHECK(expr->IsValidReferenceExpression()); | 2538 DCHECK(expr->IsValidReferenceExpression()); |
| 2519 | 2539 |
| 2520 Property* prop = expr->AsProperty(); | 2540 Property* prop = expr->AsProperty(); |
| 2521 LhsKind assign_type = GetAssignType(prop); | 2541 LhsKind assign_type = Property::GetAssignType(prop); |
| 2522 | 2542 |
| 2523 switch (assign_type) { | 2543 switch (assign_type) { |
| 2524 case VARIABLE: { | 2544 case VARIABLE: { |
| 2525 Variable* var = expr->AsVariableProxy()->var(); | 2545 Variable* var = expr->AsVariableProxy()->var(); |
| 2526 EffectContext context(this); | 2546 EffectContext context(this); |
| 2527 EmitVariableAssignment(var, Token::ASSIGN); | 2547 EmitVariableAssignment(var, Token::ASSIGN, slot); |
| 2528 break; | 2548 break; |
| 2529 } | 2549 } |
| 2530 case NAMED_PROPERTY: { | 2550 case NAMED_PROPERTY: { |
| 2531 __ push(eax); // Preserve value. | 2551 __ push(eax); // Preserve value. |
| 2532 VisitForAccumulatorValue(prop->obj()); | 2552 VisitForAccumulatorValue(prop->obj()); |
| 2533 __ Move(StoreDescriptor::ReceiverRegister(), eax); | 2553 __ Move(StoreDescriptor::ReceiverRegister(), eax); |
| 2534 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2554 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2535 __ mov(StoreDescriptor::NameRegister(), | 2555 __ mov(StoreDescriptor::NameRegister(), |
| 2536 prop->key()->AsLiteral()->value()); | 2556 prop->key()->AsLiteral()->value()); |
| 2557 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2537 CallStoreIC(); | 2558 CallStoreIC(); |
| 2538 break; | 2559 break; |
| 2539 } | 2560 } |
| 2540 case NAMED_SUPER_PROPERTY: { | 2561 case NAMED_SUPER_PROPERTY: { |
| 2541 __ push(eax); | 2562 __ push(eax); |
| 2542 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); | 2563 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); |
| 2543 EmitLoadHomeObject(prop->obj()->AsSuperReference()); | 2564 EmitLoadHomeObject(prop->obj()->AsSuperReference()); |
| 2544 // stack: value, this; eax: home_object | 2565 // stack: value, this; eax: home_object |
| 2545 Register scratch = ecx; | 2566 Register scratch = ecx; |
| 2546 Register scratch2 = edx; | 2567 Register scratch2 = edx; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2573 EmitKeyedSuperPropertyStore(prop); | 2594 EmitKeyedSuperPropertyStore(prop); |
| 2574 break; | 2595 break; |
| 2575 } | 2596 } |
| 2576 case KEYED_PROPERTY: { | 2597 case KEYED_PROPERTY: { |
| 2577 __ push(eax); // Preserve value. | 2598 __ push(eax); // Preserve value. |
| 2578 VisitForStackValue(prop->obj()); | 2599 VisitForStackValue(prop->obj()); |
| 2579 VisitForAccumulatorValue(prop->key()); | 2600 VisitForAccumulatorValue(prop->key()); |
| 2580 __ Move(StoreDescriptor::NameRegister(), eax); | 2601 __ Move(StoreDescriptor::NameRegister(), eax); |
| 2581 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. | 2602 __ pop(StoreDescriptor::ReceiverRegister()); // Receiver. |
| 2582 __ pop(StoreDescriptor::ValueRegister()); // Restore value. | 2603 __ pop(StoreDescriptor::ValueRegister()); // Restore value. |
| 2604 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2583 Handle<Code> ic = | 2605 Handle<Code> ic = |
| 2584 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2606 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2585 CallIC(ic); | 2607 CallIC(ic); |
| 2586 break; | 2608 break; |
| 2587 } | 2609 } |
| 2588 } | 2610 } |
| 2589 context()->Plug(eax); | 2611 context()->Plug(eax); |
| 2590 } | 2612 } |
| 2591 | 2613 |
| 2592 | 2614 |
| 2593 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2615 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 2594 Variable* var, MemOperand location) { | 2616 Variable* var, MemOperand location) { |
| 2595 __ mov(location, eax); | 2617 __ mov(location, eax); |
| 2596 if (var->IsContextSlot()) { | 2618 if (var->IsContextSlot()) { |
| 2597 __ mov(edx, eax); | 2619 __ mov(edx, eax); |
| 2598 int offset = Context::SlotOffset(var->index()); | 2620 int offset = Context::SlotOffset(var->index()); |
| 2599 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); | 2621 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); |
| 2600 } | 2622 } |
| 2601 } | 2623 } |
| 2602 | 2624 |
| 2603 | 2625 |
| 2604 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2626 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op, |
| 2605 Token::Value op) { | 2627 FeedbackVectorICSlot slot) { |
| 2606 if (var->IsUnallocated()) { | 2628 if (var->IsUnallocated()) { |
| 2607 // Global var, const, or let. | 2629 // Global var, const, or let. |
| 2608 __ mov(StoreDescriptor::NameRegister(), var->name()); | 2630 __ mov(StoreDescriptor::NameRegister(), var->name()); |
| 2609 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 2631 __ mov(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 2632 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot); |
| 2610 CallStoreIC(); | 2633 CallStoreIC(); |
| 2611 | 2634 |
| 2612 } else if (var->mode() == LET && op != Token::INIT_LET) { | 2635 } else if (var->mode() == LET && op != Token::INIT_LET) { |
| 2613 // Non-initializing assignment to let variable needs a write barrier. | 2636 // Non-initializing assignment to let variable needs a write barrier. |
| 2614 DCHECK(!var->IsLookupSlot()); | 2637 DCHECK(!var->IsLookupSlot()); |
| 2615 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2638 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2616 Label assign; | 2639 Label assign; |
| 2617 MemOperand location = VarOperand(var, ecx); | 2640 MemOperand location = VarOperand(var, ecx); |
| 2618 __ mov(edx, location); | 2641 __ mov(edx, location); |
| 2619 __ cmp(edx, isolate()->factory()->the_hole_value()); | 2642 __ cmp(edx, isolate()->factory()->the_hole_value()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2695 // esp[0] : receiver | 2718 // esp[0] : receiver |
| 2696 | 2719 |
| 2697 Property* prop = expr->target()->AsProperty(); | 2720 Property* prop = expr->target()->AsProperty(); |
| 2698 DCHECK(prop != NULL); | 2721 DCHECK(prop != NULL); |
| 2699 DCHECK(prop->key()->IsLiteral()); | 2722 DCHECK(prop->key()->IsLiteral()); |
| 2700 | 2723 |
| 2701 // Record source code position before IC call. | 2724 // Record source code position before IC call. |
| 2702 SetSourcePosition(expr->position()); | 2725 SetSourcePosition(expr->position()); |
| 2703 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2726 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
| 2704 __ pop(StoreDescriptor::ReceiverRegister()); | 2727 __ pop(StoreDescriptor::ReceiverRegister()); |
| 2705 CallStoreIC(expr->AssignmentFeedbackId()); | 2728 if (FLAG_vector_stores) { |
| 2729 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2730 CallStoreIC(); |
| 2731 } else { |
| 2732 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2733 } |
| 2706 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2734 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2707 context()->Plug(eax); | 2735 context()->Plug(eax); |
| 2708 } | 2736 } |
| 2709 | 2737 |
| 2710 | 2738 |
| 2711 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2739 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2712 // Assignment to named property of super. | 2740 // Assignment to named property of super. |
| 2713 // eax : value | 2741 // eax : value |
| 2714 // stack : receiver ('this'), home_object | 2742 // stack : receiver ('this'), home_object |
| 2715 DCHECK(prop != NULL); | 2743 DCHECK(prop != NULL); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2743 // esp[0] : key | 2771 // esp[0] : key |
| 2744 // esp[kPointerSize] : receiver | 2772 // esp[kPointerSize] : receiver |
| 2745 | 2773 |
| 2746 __ pop(StoreDescriptor::NameRegister()); // Key. | 2774 __ pop(StoreDescriptor::NameRegister()); // Key. |
| 2747 __ pop(StoreDescriptor::ReceiverRegister()); | 2775 __ pop(StoreDescriptor::ReceiverRegister()); |
| 2748 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2776 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
| 2749 // Record source code position before IC call. | 2777 // Record source code position before IC call. |
| 2750 SetSourcePosition(expr->position()); | 2778 SetSourcePosition(expr->position()); |
| 2751 Handle<Code> ic = | 2779 Handle<Code> ic = |
| 2752 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2780 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2753 CallIC(ic, expr->AssignmentFeedbackId()); | 2781 if (FLAG_vector_stores) { |
| 2782 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2783 CallIC(ic); |
| 2784 } else { |
| 2785 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2786 } |
| 2754 | 2787 |
| 2755 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2788 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2756 context()->Plug(eax); | 2789 context()->Plug(eax); |
| 2757 } | 2790 } |
| 2758 | 2791 |
| 2759 | 2792 |
| 2760 void FullCodeGenerator::VisitProperty(Property* expr) { | 2793 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2761 Comment cmnt(masm_, "[ Property"); | 2794 Comment cmnt(masm_, "[ Property"); |
| 2762 Expression* key = expr->key(); | 2795 Expression* key = expr->key(); |
| 2763 | 2796 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2976 } | 3009 } |
| 2977 | 3010 |
| 2978 | 3011 |
| 2979 void FullCodeGenerator::EmitLoadSuperConstructor() { | 3012 void FullCodeGenerator::EmitLoadSuperConstructor() { |
| 2980 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 3013 __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2981 __ CallRuntime(Runtime::kGetPrototype, 1); | 3014 __ CallRuntime(Runtime::kGetPrototype, 1); |
| 2982 } | 3015 } |
| 2983 | 3016 |
| 2984 | 3017 |
| 2985 void FullCodeGenerator::EmitInitializeThisAfterSuper( | 3018 void FullCodeGenerator::EmitInitializeThisAfterSuper( |
| 2986 SuperReference* super_ref) { | 3019 SuperReference* super_ref, FeedbackVectorICSlot slot) { |
| 2987 Variable* this_var = super_ref->this_var()->var(); | 3020 Variable* this_var = super_ref->this_var()->var(); |
| 2988 GetVar(ecx, this_var); | 3021 GetVar(ecx, this_var); |
| 2989 __ cmp(ecx, isolate()->factory()->the_hole_value()); | 3022 __ cmp(ecx, isolate()->factory()->the_hole_value()); |
| 2990 Label uninitialized_this; | 3023 Label uninitialized_this; |
| 2991 __ j(equal, &uninitialized_this); | 3024 __ j(equal, &uninitialized_this); |
| 2992 __ push(Immediate(this_var->name())); | 3025 __ push(Immediate(this_var->name())); |
| 2993 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 3026 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2994 __ bind(&uninitialized_this); | 3027 __ bind(&uninitialized_this); |
| 2995 | 3028 |
| 2996 EmitVariableAssignment(this_var, Token::INIT_CONST); | 3029 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
| 2997 } | 3030 } |
| 2998 | 3031 |
| 2999 | 3032 |
| 3000 void FullCodeGenerator::VisitCall(Call* expr) { | 3033 void FullCodeGenerator::VisitCall(Call* expr) { |
| 3001 #ifdef DEBUG | 3034 #ifdef DEBUG |
| 3002 // We want to verify that RecordJSReturnSite gets called on all paths | 3035 // We want to verify that RecordJSReturnSite gets called on all paths |
| 3003 // through this function. Avoid early returns. | 3036 // through this function. Avoid early returns. |
| 3004 expr->return_is_recorded_ = false; | 3037 expr->return_is_recorded_ = false; |
| 3005 #endif | 3038 #endif |
| 3006 | 3039 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3204 __ LoadHeapObject(ebx, FeedbackVector()); | 3237 __ LoadHeapObject(ebx, FeedbackVector()); |
| 3205 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); | 3238 __ mov(edx, Immediate(SmiFromSlot(expr->CallFeedbackSlot()))); |
| 3206 | 3239 |
| 3207 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); | 3240 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); |
| 3208 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); | 3241 __ call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); |
| 3209 | 3242 |
| 3210 __ Drop(1); | 3243 __ Drop(1); |
| 3211 | 3244 |
| 3212 RecordJSReturnSite(expr); | 3245 RecordJSReturnSite(expr); |
| 3213 | 3246 |
| 3214 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); | 3247 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(), |
| 3248 expr->CallFeedbackICSlot()); |
| 3215 context()->Plug(eax); | 3249 context()->Plug(eax); |
| 3216 } | 3250 } |
| 3217 | 3251 |
| 3218 | 3252 |
| 3219 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { | 3253 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { |
| 3220 ZoneList<Expression*>* args = expr->arguments(); | 3254 ZoneList<Expression*>* args = expr->arguments(); |
| 3221 DCHECK(args->length() == 1); | 3255 DCHECK(args->length() == 1); |
| 3222 | 3256 |
| 3223 VisitForAccumulatorValue(args->at(0)); | 3257 VisitForAccumulatorValue(args->at(0)); |
| 3224 | 3258 |
| (...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4538 // Push NewTarget | 4572 // Push NewTarget |
| 4539 DCHECK(args->at(2)->IsVariableProxy()); | 4573 DCHECK(args->at(2)->IsVariableProxy()); |
| 4540 VisitForStackValue(args->at(2)); | 4574 VisitForStackValue(args->at(2)); |
| 4541 | 4575 |
| 4542 EmitCallJSRuntimeFunction(call); | 4576 EmitCallJSRuntimeFunction(call); |
| 4543 | 4577 |
| 4544 // Restore context register. | 4578 // Restore context register. |
| 4545 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 4579 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 4546 context()->DropAndPlug(1, eax); | 4580 context()->DropAndPlug(1, eax); |
| 4547 | 4581 |
| 4582 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id. |
| 4548 EmitInitializeThisAfterSuper(super_reference); | 4583 EmitInitializeThisAfterSuper(super_reference); |
| 4549 } | 4584 } |
| 4550 | 4585 |
| 4551 | 4586 |
| 4552 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { | 4587 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { |
| 4553 // Push the builtins object as receiver. | 4588 // Push the builtins object as receiver. |
| 4554 __ mov(eax, GlobalObjectOperand()); | 4589 __ mov(eax, GlobalObjectOperand()); |
| 4555 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); | 4590 __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); |
| 4556 | 4591 |
| 4557 // Load the function from the receiver. | 4592 // Load the function from the receiver. |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4741 } | 4776 } |
| 4742 | 4777 |
| 4743 | 4778 |
| 4744 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4779 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4745 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4780 DCHECK(expr->expression()->IsValidReferenceExpression()); |
| 4746 | 4781 |
| 4747 Comment cmnt(masm_, "[ CountOperation"); | 4782 Comment cmnt(masm_, "[ CountOperation"); |
| 4748 SetSourcePosition(expr->position()); | 4783 SetSourcePosition(expr->position()); |
| 4749 | 4784 |
| 4750 Property* prop = expr->expression()->AsProperty(); | 4785 Property* prop = expr->expression()->AsProperty(); |
| 4751 LhsKind assign_type = GetAssignType(prop); | 4786 LhsKind assign_type = Property::GetAssignType(prop); |
| 4752 | 4787 |
| 4753 // Evaluate expression and get value. | 4788 // Evaluate expression and get value. |
| 4754 if (assign_type == VARIABLE) { | 4789 if (assign_type == VARIABLE) { |
| 4755 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4790 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4756 AccumulatorValueContext context(this); | 4791 AccumulatorValueContext context(this); |
| 4757 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4792 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4758 } else { | 4793 } else { |
| 4759 // Reserve space for result of postfix operation. | 4794 // Reserve space for result of postfix operation. |
| 4760 if (expr->is_postfix() && !context()->IsEffect()) { | 4795 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4761 __ push(Immediate(Smi::FromInt(0))); | 4796 __ push(Immediate(Smi::FromInt(0))); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4907 patch_site.EmitPatchInfo(); | 4942 patch_site.EmitPatchInfo(); |
| 4908 __ bind(&done); | 4943 __ bind(&done); |
| 4909 | 4944 |
| 4910 // Store the value returned in eax. | 4945 // Store the value returned in eax. |
| 4911 switch (assign_type) { | 4946 switch (assign_type) { |
| 4912 case VARIABLE: | 4947 case VARIABLE: |
| 4913 if (expr->is_postfix()) { | 4948 if (expr->is_postfix()) { |
| 4914 // Perform the assignment as if via '='. | 4949 // Perform the assignment as if via '='. |
| 4915 { EffectContext context(this); | 4950 { EffectContext context(this); |
| 4916 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4951 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4917 Token::ASSIGN); | 4952 Token::ASSIGN, expr->CountSlot()); |
| 4918 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4953 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4919 context.Plug(eax); | 4954 context.Plug(eax); |
| 4920 } | 4955 } |
| 4921 // For all contexts except EffectContext We have the result on | 4956 // For all contexts except EffectContext We have the result on |
| 4922 // top of the stack. | 4957 // top of the stack. |
| 4923 if (!context()->IsEffect()) { | 4958 if (!context()->IsEffect()) { |
| 4924 context()->PlugTOS(); | 4959 context()->PlugTOS(); |
| 4925 } | 4960 } |
| 4926 } else { | 4961 } else { |
| 4927 // Perform the assignment as if via '='. | 4962 // Perform the assignment as if via '='. |
| 4928 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4963 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 4929 Token::ASSIGN); | 4964 Token::ASSIGN, expr->CountSlot()); |
| 4930 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4965 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4931 context()->Plug(eax); | 4966 context()->Plug(eax); |
| 4932 } | 4967 } |
| 4933 break; | 4968 break; |
| 4934 case NAMED_PROPERTY: { | 4969 case NAMED_PROPERTY: { |
| 4935 __ mov(StoreDescriptor::NameRegister(), | 4970 __ mov(StoreDescriptor::NameRegister(), |
| 4936 prop->key()->AsLiteral()->value()); | 4971 prop->key()->AsLiteral()->value()); |
| 4937 __ pop(StoreDescriptor::ReceiverRegister()); | 4972 __ pop(StoreDescriptor::ReceiverRegister()); |
| 4938 CallStoreIC(expr->CountStoreFeedbackId()); | 4973 if (FLAG_vector_stores) { |
| 4974 EmitLoadStoreICSlot(expr->CountSlot()); |
| 4975 CallStoreIC(); |
| 4976 } else { |
| 4977 CallStoreIC(expr->CountStoreFeedbackId()); |
| 4978 } |
| 4939 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4979 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4940 if (expr->is_postfix()) { | 4980 if (expr->is_postfix()) { |
| 4941 if (!context()->IsEffect()) { | 4981 if (!context()->IsEffect()) { |
| 4942 context()->PlugTOS(); | 4982 context()->PlugTOS(); |
| 4943 } | 4983 } |
| 4944 } else { | 4984 } else { |
| 4945 context()->Plug(eax); | 4985 context()->Plug(eax); |
| 4946 } | 4986 } |
| 4947 break; | 4987 break; |
| 4948 } | 4988 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 4966 } else { | 5006 } else { |
| 4967 context()->Plug(eax); | 5007 context()->Plug(eax); |
| 4968 } | 5008 } |
| 4969 break; | 5009 break; |
| 4970 } | 5010 } |
| 4971 case KEYED_PROPERTY: { | 5011 case KEYED_PROPERTY: { |
| 4972 __ pop(StoreDescriptor::NameRegister()); | 5012 __ pop(StoreDescriptor::NameRegister()); |
| 4973 __ pop(StoreDescriptor::ReceiverRegister()); | 5013 __ pop(StoreDescriptor::ReceiverRegister()); |
| 4974 Handle<Code> ic = | 5014 Handle<Code> ic = |
| 4975 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 5015 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 4976 CallIC(ic, expr->CountStoreFeedbackId()); | 5016 if (FLAG_vector_stores) { |
| 5017 EmitLoadStoreICSlot(expr->CountSlot()); |
| 5018 CallIC(ic); |
| 5019 } else { |
| 5020 CallIC(ic, expr->CountStoreFeedbackId()); |
| 5021 } |
| 4977 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 5022 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4978 if (expr->is_postfix()) { | 5023 if (expr->is_postfix()) { |
| 4979 // Result is on the stack | 5024 // Result is on the stack |
| 4980 if (!context()->IsEffect()) { | 5025 if (!context()->IsEffect()) { |
| 4981 context()->PlugTOS(); | 5026 context()->PlugTOS(); |
| 4982 } | 5027 } |
| 4983 } else { | 5028 } else { |
| 4984 context()->Plug(eax); | 5029 context()->Plug(eax); |
| 4985 } | 5030 } |
| 4986 break; | 5031 break; |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5300 | 5345 |
| 5301 void FullCodeGenerator::ClearPendingMessage() { | 5346 void FullCodeGenerator::ClearPendingMessage() { |
| 5302 DCHECK(!result_register().is(edx)); | 5347 DCHECK(!result_register().is(edx)); |
| 5303 ExternalReference pending_message_obj = | 5348 ExternalReference pending_message_obj = |
| 5304 ExternalReference::address_of_pending_message_obj(isolate()); | 5349 ExternalReference::address_of_pending_message_obj(isolate()); |
| 5305 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); | 5350 __ mov(edx, Immediate(isolate()->factory()->the_hole_value())); |
| 5306 __ mov(Operand::StaticVariable(pending_message_obj), edx); | 5351 __ mov(Operand::StaticVariable(pending_message_obj), edx); |
| 5307 } | 5352 } |
| 5308 | 5353 |
| 5309 | 5354 |
| 5355 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) { |
| 5356 DCHECK(FLAG_vector_stores && !slot.IsInvalid()); |
| 5357 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(), |
| 5358 Immediate(SmiFromSlot(slot))); |
| 5359 } |
| 5360 |
| 5361 |
| 5310 #undef __ | 5362 #undef __ |
| 5311 | 5363 |
| 5312 | 5364 |
| 5313 static const byte kJnsInstruction = 0x79; | 5365 static const byte kJnsInstruction = 0x79; |
| 5314 static const byte kJnsOffset = 0x11; | 5366 static const byte kJnsOffset = 0x11; |
| 5315 static const byte kNopByteOne = 0x66; | 5367 static const byte kNopByteOne = 0x66; |
| 5316 static const byte kNopByteTwo = 0x90; | 5368 static const byte kNopByteTwo = 0x90; |
| 5317 #ifdef DEBUG | 5369 #ifdef DEBUG |
| 5318 static const byte kCallInstruction = 0xe8; | 5370 static const byte kCallInstruction = 0xe8; |
| 5319 #endif | 5371 #endif |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5383 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), | 5435 DCHECK_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), |
| 5384 Assembler::target_address_at(call_target_address, | 5436 Assembler::target_address_at(call_target_address, |
| 5385 unoptimized_code)); | 5437 unoptimized_code)); |
| 5386 return OSR_AFTER_STACK_CHECK; | 5438 return OSR_AFTER_STACK_CHECK; |
| 5387 } | 5439 } |
| 5388 | 5440 |
| 5389 | 5441 |
| 5390 } } // namespace v8::internal | 5442 } } // namespace v8::internal |
| 5391 | 5443 |
| 5392 #endif // V8_TARGET_ARCH_IA32 | 5444 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |