Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 1161623002: VectorICs: allocating slots for store ics in ast nodes. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Ports. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/arm64/full-codegen-arm64.cc » ('j') | src/ast.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_ARM 7 #if V8_TARGET_ARCH_ARM
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 1246 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1257 PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1258 __ mov(r3, Operand(r0), SetCC); 1258 __ mov(r3, Operand(r0), SetCC);
1259 __ b(eq, loop_statement.continue_label()); 1259 __ b(eq, loop_statement.continue_label());
1260 1260
1261 // Update the 'each' property or variable from the possibly filtered 1261 // Update the 'each' property or variable from the possibly filtered
1262 // entry in register r3. 1262 // entry in register r3.
1263 __ bind(&update_each); 1263 __ bind(&update_each);
1264 __ mov(result_register(), r3); 1264 __ mov(result_register(), r3);
1265 // Perform the assignment as if via '='. 1265 // Perform the assignment as if via '='.
1266 { EffectContext context(this); 1266 { EffectContext context(this);
1267 EmitAssignment(stmt->each()); 1267 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1268 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); 1268 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS);
1269 } 1269 }
1270 1270
1271 // Generate code for the body of the loop. 1271 // Generate code for the body of the loop.
1272 Visit(stmt->body()); 1272 Visit(stmt->body());
1273 1273
1274 // Generate code for the going to the next element by incrementing 1274 // Generate code for the going to the next element by incrementing
1275 // the index (smi) stored on top of the stack. 1275 // the index (smi) stored on top of the stack.
1276 __ bind(loop_statement.continue_label()); 1276 __ bind(loop_statement.continue_label());
1277 __ pop(r0); 1277 __ pop(r0);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1340 1340
1341 __ cmp(r0, Operand(isolate()->factory()->undefined_value())); 1341 __ cmp(r0, Operand(isolate()->factory()->undefined_value()));
1342 Label done; 1342 Label done;
1343 __ b(ne, &done); 1343 __ b(ne, &done);
1344 __ CallRuntime(Runtime::kThrowNonMethodError, 0); 1344 __ CallRuntime(Runtime::kThrowNonMethodError, 0);
1345 __ bind(&done); 1345 __ bind(&done);
1346 } 1346 }
1347 1347
1348 1348
1349 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, 1349 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
1350 int offset) { 1350 int offset,
1351 FeedbackVectorICSlot slot) {
1351 if (NeedsHomeObject(initializer)) { 1352 if (NeedsHomeObject(initializer)) {
1352 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1353 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1353 __ mov(StoreDescriptor::NameRegister(), 1354 __ mov(StoreDescriptor::NameRegister(),
1354 Operand(isolate()->factory()->home_object_symbol())); 1355 Operand(isolate()->factory()->home_object_symbol()));
1355 __ ldr(StoreDescriptor::ValueRegister(), 1356 __ ldr(StoreDescriptor::ValueRegister(),
1356 MemOperand(sp, offset * kPointerSize)); 1357 MemOperand(sp, offset * kPointerSize));
1358 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1357 CallStoreIC(); 1359 CallStoreIC();
1358 } 1360 }
1359 } 1361 }
1360 1362
1361 1363
1362 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1364 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1363 TypeofState typeof_state, 1365 TypeofState typeof_state,
1364 Label* slow) { 1366 Label* slow) {
1365 Register current = cp; 1367 Register current = cp;
1366 Register next = r1; 1368 Register next = r1;
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 __ CallStub(&stub); 1673 __ CallStub(&stub);
1672 } 1674 }
1673 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1675 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1674 1676
1675 // If result_saved is true the result is on top of the stack. If 1677 // If result_saved is true the result is on top of the stack. If
1676 // result_saved is false the result is in r0. 1678 // result_saved is false the result is in r0.
1677 bool result_saved = false; 1679 bool result_saved = false;
1678 1680
1679 AccessorTable accessor_table(zone()); 1681 AccessorTable accessor_table(zone());
1680 int property_index = 0; 1682 int property_index = 0;
1683 int store_slot_index = 0;
1681 for (; property_index < expr->properties()->length(); property_index++) { 1684 for (; property_index < expr->properties()->length(); property_index++) {
1682 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1685 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1683 if (property->is_computed_name()) break; 1686 if (property->is_computed_name()) break;
1684 if (property->IsCompileTimeValue()) continue; 1687 if (property->IsCompileTimeValue()) continue;
1685 1688
1686 Literal* key = property->key()->AsLiteral(); 1689 Literal* key = property->key()->AsLiteral();
1687 Expression* value = property->value(); 1690 Expression* value = property->value();
1688 if (!result_saved) { 1691 if (!result_saved) {
1689 __ push(r0); // Save result on stack 1692 __ push(r0); // Save result on stack
1690 result_saved = true; 1693 result_saved = true;
1691 } 1694 }
1692 switch (property->kind()) { 1695 switch (property->kind()) {
1693 case ObjectLiteral::Property::CONSTANT: 1696 case ObjectLiteral::Property::CONSTANT:
1694 UNREACHABLE(); 1697 UNREACHABLE();
1695 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1698 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1696 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1699 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1697 // Fall through. 1700 // Fall through.
1698 case ObjectLiteral::Property::COMPUTED: 1701 case ObjectLiteral::Property::COMPUTED:
1699 // It is safe to use [[Put]] here because the boilerplate already 1702 // It is safe to use [[Put]] here because the boilerplate already
1700 // contains computed properties with an uninitialized value. 1703 // contains computed properties with an uninitialized value.
1701 if (key->value()->IsInternalizedString()) { 1704 if (key->value()->IsInternalizedString()) {
1702 if (property->emit_store()) { 1705 if (property->emit_store()) {
1703 VisitForAccumulatorValue(value); 1706 VisitForAccumulatorValue(value);
1704 DCHECK(StoreDescriptor::ValueRegister().is(r0)); 1707 DCHECK(StoreDescriptor::ValueRegister().is(r0));
1705 __ mov(StoreDescriptor::NameRegister(), Operand(key->value())); 1708 __ mov(StoreDescriptor::NameRegister(), Operand(key->value()));
1706 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1709 __ ldr(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1707 CallStoreIC(key->LiteralFeedbackId()); 1710 if (FLAG_vector_stores) {
1711 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
1712 CallStoreIC();
1713 } else {
1714 CallStoreIC(key->LiteralFeedbackId());
1715 }
1708 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1716 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1709 1717
1710 if (NeedsHomeObject(value)) { 1718 if (NeedsHomeObject(value)) {
1711 __ Move(StoreDescriptor::ReceiverRegister(), r0); 1719 __ Move(StoreDescriptor::ReceiverRegister(), r0);
1712 __ mov(StoreDescriptor::NameRegister(), 1720 __ mov(StoreDescriptor::NameRegister(),
1713 Operand(isolate()->factory()->home_object_symbol())); 1721 Operand(isolate()->factory()->home_object_symbol()));
1714 __ ldr(StoreDescriptor::ValueRegister(), MemOperand(sp)); 1722 __ ldr(StoreDescriptor::ValueRegister(), MemOperand(sp));
1723 if (FLAG_vector_stores) {
1724 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
1725 }
1715 CallStoreIC(); 1726 CallStoreIC();
1716 } 1727 }
1717 } else { 1728 } else {
1718 VisitForEffect(value); 1729 VisitForEffect(value);
1719 } 1730 }
1720 break; 1731 break;
1721 } 1732 }
1722 // Duplicate receiver on stack. 1733 // Duplicate receiver on stack.
1723 __ ldr(r0, MemOperand(sp)); 1734 __ ldr(r0, MemOperand(sp));
1724 __ push(r0); 1735 __ push(r0);
1725 VisitForStackValue(key); 1736 VisitForStackValue(key);
1726 VisitForStackValue(value); 1737 VisitForStackValue(value);
1727 if (property->emit_store()) { 1738 if (property->emit_store()) {
1728 EmitSetHomeObjectIfNeeded(value, 2); 1739 EmitSetHomeObjectIfNeeded(
1740 value, 2, expr->SlotForHomeObject(value, &store_slot_index));
1729 __ mov(r0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes 1741 __ mov(r0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes
1730 __ push(r0); 1742 __ push(r0);
1731 __ CallRuntime(Runtime::kSetProperty, 4); 1743 __ CallRuntime(Runtime::kSetProperty, 4);
1732 } else { 1744 } else {
1733 __ Drop(3); 1745 __ Drop(3);
1734 } 1746 }
1735 break; 1747 break;
1736 case ObjectLiteral::Property::PROTOTYPE: 1748 case ObjectLiteral::Property::PROTOTYPE:
1737 // Duplicate receiver on stack. 1749 // Duplicate receiver on stack.
1738 __ ldr(r0, MemOperand(sp)); 1750 __ ldr(r0, MemOperand(sp));
(...skipping 18 matching lines...) Expand all
1757 1769
1758 // Emit code to define accessors, using only a single call to the runtime for 1770 // Emit code to define accessors, using only a single call to the runtime for
1759 // each pair of corresponding getters and setters. 1771 // each pair of corresponding getters and setters.
1760 for (AccessorTable::Iterator it = accessor_table.begin(); 1772 for (AccessorTable::Iterator it = accessor_table.begin();
1761 it != accessor_table.end(); 1773 it != accessor_table.end();
1762 ++it) { 1774 ++it) {
1763 __ ldr(r0, MemOperand(sp)); // Duplicate receiver. 1775 __ ldr(r0, MemOperand(sp)); // Duplicate receiver.
1764 __ push(r0); 1776 __ push(r0);
1765 VisitForStackValue(it->first); 1777 VisitForStackValue(it->first);
1766 EmitAccessor(it->second->getter); 1778 EmitAccessor(it->second->getter);
1767 EmitSetHomeObjectIfNeeded(it->second->getter, 2); 1779 EmitSetHomeObjectIfNeeded(
1780 it->second->getter, 2,
1781 expr->SlotForHomeObject(it->second->getter, &store_slot_index));
1768 EmitAccessor(it->second->setter); 1782 EmitAccessor(it->second->setter);
1769 EmitSetHomeObjectIfNeeded(it->second->setter, 3); 1783 EmitSetHomeObjectIfNeeded(
1784 it->second->setter, 3,
1785 expr->SlotForHomeObject(it->second->setter, &store_slot_index));
1770 __ mov(r0, Operand(Smi::FromInt(NONE))); 1786 __ mov(r0, Operand(Smi::FromInt(NONE)));
1771 __ push(r0); 1787 __ push(r0);
1772 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1788 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1773 } 1789 }
1774 1790
1775 // Object literals have two parts. The "static" part on the left contains no 1791 // Object literals have two parts. The "static" part on the left contains no
1776 // computed property names, and so we can compute its map ahead of time; see 1792 // computed property names, and so we can compute its map ahead of time; see
1777 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1793 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1778 // starts with the first computed property name, and continues with all 1794 // starts with the first computed property name, and continues with all
1779 // properties to its right. All the code from above initializes the static 1795 // properties to its right. All the code from above initializes the static
(...skipping 14 matching lines...) Expand all
1794 __ push(r0); 1810 __ push(r0);
1795 1811
1796 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1812 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1797 DCHECK(!property->is_computed_name()); 1813 DCHECK(!property->is_computed_name());
1798 VisitForStackValue(value); 1814 VisitForStackValue(value);
1799 DCHECK(property->emit_store()); 1815 DCHECK(property->emit_store());
1800 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1816 __ CallRuntime(Runtime::kInternalSetPrototype, 2);
1801 } else { 1817 } else {
1802 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); 1818 EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1803 VisitForStackValue(value); 1819 VisitForStackValue(value);
1804 EmitSetHomeObjectIfNeeded(value, 2); 1820 EmitSetHomeObjectIfNeeded(
1821 value, 2, expr->SlotForHomeObject(value, &store_slot_index));
1805 1822
1806 switch (property->kind()) { 1823 switch (property->kind()) {
1807 case ObjectLiteral::Property::CONSTANT: 1824 case ObjectLiteral::Property::CONSTANT:
1808 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1825 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1809 case ObjectLiteral::Property::COMPUTED: 1826 case ObjectLiteral::Property::COMPUTED:
1810 if (property->emit_store()) { 1827 if (property->emit_store()) {
1811 __ mov(r0, Operand(Smi::FromInt(NONE))); 1828 __ mov(r0, Operand(Smi::FromInt(NONE)));
1812 __ push(r0); 1829 __ push(r0);
1813 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1830 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
1814 } else { 1831 } else {
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1955 } 1972 }
1956 } 1973 }
1957 1974
1958 1975
1959 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1976 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1960 DCHECK(expr->target()->IsValidReferenceExpression()); 1977 DCHECK(expr->target()->IsValidReferenceExpression());
1961 1978
1962 Comment cmnt(masm_, "[ Assignment"); 1979 Comment cmnt(masm_, "[ Assignment");
1963 1980
1964 Property* property = expr->target()->AsProperty(); 1981 Property* property = expr->target()->AsProperty();
1965 LhsKind assign_type = GetAssignType(property); 1982 LhsKind assign_type = Property::GetAssignType(property);
1966 1983
1967 // Evaluate LHS expression. 1984 // Evaluate LHS expression.
1968 switch (assign_type) { 1985 switch (assign_type) {
1969 case VARIABLE: 1986 case VARIABLE:
1970 // Nothing to do here. 1987 // Nothing to do here.
1971 break; 1988 break;
1972 case NAMED_PROPERTY: 1989 case NAMED_PROPERTY:
1973 if (expr->is_compound()) { 1990 if (expr->is_compound()) {
1974 // We need the receiver both on the stack and in the register. 1991 // We need the receiver both on the stack and in the register.
1975 VisitForStackValue(property->obj()); 1992 VisitForStackValue(property->obj());
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2067 VisitForAccumulatorValue(expr->value()); 2084 VisitForAccumulatorValue(expr->value());
2068 } 2085 }
2069 2086
2070 // Record source position before possible IC call. 2087 // Record source position before possible IC call.
2071 SetSourcePosition(expr->position()); 2088 SetSourcePosition(expr->position());
2072 2089
2073 // Store the value. 2090 // Store the value.
2074 switch (assign_type) { 2091 switch (assign_type) {
2075 case VARIABLE: 2092 case VARIABLE:
2076 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 2093 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
2077 expr->op()); 2094 expr->op(), expr->AssignmentSlot());
2078 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2095 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2079 context()->Plug(r0); 2096 context()->Plug(r0);
2080 break; 2097 break;
2081 case NAMED_PROPERTY: 2098 case NAMED_PROPERTY:
2082 EmitNamedPropertyAssignment(expr); 2099 EmitNamedPropertyAssignment(expr);
2083 break; 2100 break;
2084 case NAMED_SUPER_PROPERTY: 2101 case NAMED_SUPER_PROPERTY:
2085 EmitNamedSuperPropertyStore(property); 2102 EmitNamedSuperPropertyStore(property);
2086 context()->Plug(r0); 2103 context()->Plug(r0);
2087 break; 2104 break;
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
2601 __ pop(r1); 2618 __ pop(r1);
2602 Handle<Code> code = CodeFactory::BinaryOpIC( 2619 Handle<Code> code = CodeFactory::BinaryOpIC(
2603 isolate(), op, language_mode()).code(); 2620 isolate(), op, language_mode()).code();
2604 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2621 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2605 CallIC(code, expr->BinaryOperationFeedbackId()); 2622 CallIC(code, expr->BinaryOperationFeedbackId());
2606 patch_site.EmitPatchInfo(); 2623 patch_site.EmitPatchInfo();
2607 context()->Plug(r0); 2624 context()->Plug(r0);
2608 } 2625 }
2609 2626
2610 2627
2611 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2628 void FullCodeGenerator::EmitAssignment(Expression* expr,
2629 FeedbackVectorICSlot slot) {
2612 DCHECK(expr->IsValidReferenceExpression()); 2630 DCHECK(expr->IsValidReferenceExpression());
2613 2631
2614 Property* prop = expr->AsProperty(); 2632 Property* prop = expr->AsProperty();
2615 LhsKind assign_type = GetAssignType(prop); 2633 LhsKind assign_type = Property::GetAssignType(prop);
2616 2634
2617 switch (assign_type) { 2635 switch (assign_type) {
2618 case VARIABLE: { 2636 case VARIABLE: {
2619 Variable* var = expr->AsVariableProxy()->var(); 2637 Variable* var = expr->AsVariableProxy()->var();
2620 EffectContext context(this); 2638 EffectContext context(this);
2621 EmitVariableAssignment(var, Token::ASSIGN); 2639 EmitVariableAssignment(var, Token::ASSIGN, slot);
2622 break; 2640 break;
2623 } 2641 }
2624 case NAMED_PROPERTY: { 2642 case NAMED_PROPERTY: {
2625 __ push(r0); // Preserve value. 2643 __ push(r0); // Preserve value.
2626 VisitForAccumulatorValue(prop->obj()); 2644 VisitForAccumulatorValue(prop->obj());
2627 __ Move(StoreDescriptor::ReceiverRegister(), r0); 2645 __ Move(StoreDescriptor::ReceiverRegister(), r0);
2628 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2646 __ pop(StoreDescriptor::ValueRegister()); // Restore value.
2629 __ mov(StoreDescriptor::NameRegister(), 2647 __ mov(StoreDescriptor::NameRegister(),
2630 Operand(prop->key()->AsLiteral()->value())); 2648 Operand(prop->key()->AsLiteral()->value()));
2649 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
2631 CallStoreIC(); 2650 CallStoreIC();
2632 break; 2651 break;
2633 } 2652 }
2634 case NAMED_SUPER_PROPERTY: { 2653 case NAMED_SUPER_PROPERTY: {
2635 __ Push(r0); 2654 __ Push(r0);
2636 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); 2655 VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
2637 EmitLoadHomeObject(prop->obj()->AsSuperReference()); 2656 EmitLoadHomeObject(prop->obj()->AsSuperReference());
2638 // stack: value, this; r0: home_object 2657 // stack: value, this; r0: home_object
2639 Register scratch = r2; 2658 Register scratch = r2;
2640 Register scratch2 = r3; 2659 Register scratch2 = r3;
(...skipping 26 matching lines...) Expand all
2667 EmitKeyedSuperPropertyStore(prop); 2686 EmitKeyedSuperPropertyStore(prop);
2668 break; 2687 break;
2669 } 2688 }
2670 case KEYED_PROPERTY: { 2689 case KEYED_PROPERTY: {
2671 __ push(r0); // Preserve value. 2690 __ push(r0); // Preserve value.
2672 VisitForStackValue(prop->obj()); 2691 VisitForStackValue(prop->obj());
2673 VisitForAccumulatorValue(prop->key()); 2692 VisitForAccumulatorValue(prop->key());
2674 __ Move(StoreDescriptor::NameRegister(), r0); 2693 __ Move(StoreDescriptor::NameRegister(), r0);
2675 __ Pop(StoreDescriptor::ValueRegister(), 2694 __ Pop(StoreDescriptor::ValueRegister(),
2676 StoreDescriptor::ReceiverRegister()); 2695 StoreDescriptor::ReceiverRegister());
2696 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
2677 Handle<Code> ic = 2697 Handle<Code> ic =
2678 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2698 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2679 CallIC(ic); 2699 CallIC(ic);
2680 break; 2700 break;
2681 } 2701 }
2682 } 2702 }
2683 context()->Plug(r0); 2703 context()->Plug(r0);
2684 } 2704 }
2685 2705
2686 2706
2687 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2707 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2688 Variable* var, MemOperand location) { 2708 Variable* var, MemOperand location) {
2689 __ str(result_register(), location); 2709 __ str(result_register(), location);
2690 if (var->IsContextSlot()) { 2710 if (var->IsContextSlot()) {
2691 // RecordWrite may destroy all its register arguments. 2711 // RecordWrite may destroy all its register arguments.
2692 __ mov(r3, result_register()); 2712 __ mov(r3, result_register());
2693 int offset = Context::SlotOffset(var->index()); 2713 int offset = Context::SlotOffset(var->index());
2694 __ RecordWriteContextSlot( 2714 __ RecordWriteContextSlot(
2695 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); 2715 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
2696 } 2716 }
2697 } 2717 }
2698 2718
2699 2719
2700 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { 2720 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
2721 FeedbackVectorICSlot slot) {
2701 if (var->IsUnallocated()) { 2722 if (var->IsUnallocated()) {
2702 // Global var, const, or let. 2723 // Global var, const, or let.
2703 __ mov(StoreDescriptor::NameRegister(), Operand(var->name())); 2724 __ mov(StoreDescriptor::NameRegister(), Operand(var->name()));
2704 __ ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); 2725 __ ldr(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
2726 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
2705 CallStoreIC(); 2727 CallStoreIC();
2706 2728
2707 } else if (var->mode() == LET && op != Token::INIT_LET) { 2729 } else if (var->mode() == LET && op != Token::INIT_LET) {
2708 // Non-initializing assignment to let variable needs a write barrier. 2730 // Non-initializing assignment to let variable needs a write barrier.
2709 DCHECK(!var->IsLookupSlot()); 2731 DCHECK(!var->IsLookupSlot());
2710 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2732 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2711 Label assign; 2733 Label assign;
2712 MemOperand location = VarOperand(var, r1); 2734 MemOperand location = VarOperand(var, r1);
2713 __ ldr(r3, location); 2735 __ ldr(r3, location);
2714 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 2736 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
2791 // Assignment to a property, using a named store IC. 2813 // Assignment to a property, using a named store IC.
2792 Property* prop = expr->target()->AsProperty(); 2814 Property* prop = expr->target()->AsProperty();
2793 DCHECK(prop != NULL); 2815 DCHECK(prop != NULL);
2794 DCHECK(prop->key()->IsLiteral()); 2816 DCHECK(prop->key()->IsLiteral());
2795 2817
2796 // Record source code position before IC call. 2818 // Record source code position before IC call.
2797 SetSourcePosition(expr->position()); 2819 SetSourcePosition(expr->position());
2798 __ mov(StoreDescriptor::NameRegister(), 2820 __ mov(StoreDescriptor::NameRegister(),
2799 Operand(prop->key()->AsLiteral()->value())); 2821 Operand(prop->key()->AsLiteral()->value()));
2800 __ pop(StoreDescriptor::ReceiverRegister()); 2822 __ pop(StoreDescriptor::ReceiverRegister());
2801 CallStoreIC(expr->AssignmentFeedbackId()); 2823 if (FLAG_vector_stores) {
2824 EmitLoadStoreICSlot(expr->AssignmentSlot());
2825 CallStoreIC();
2826 } else {
2827 CallStoreIC(expr->AssignmentFeedbackId());
2828 }
2802 2829
2803 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2830 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2804 context()->Plug(r0); 2831 context()->Plug(r0);
2805 } 2832 }
2806 2833
2807 2834
2808 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2835 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2809 // Assignment to named property of super. 2836 // Assignment to named property of super.
2810 // r0 : value 2837 // r0 : value
2811 // stack : receiver ('this'), home_object 2838 // stack : receiver ('this'), home_object
(...skipping 26 matching lines...) Expand all
2838 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2865 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2839 // Assignment to a property, using a keyed store IC. 2866 // Assignment to a property, using a keyed store IC.
2840 2867
2841 // Record source code position before IC call. 2868 // Record source code position before IC call.
2842 SetSourcePosition(expr->position()); 2869 SetSourcePosition(expr->position());
2843 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2870 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
2844 DCHECK(StoreDescriptor::ValueRegister().is(r0)); 2871 DCHECK(StoreDescriptor::ValueRegister().is(r0));
2845 2872
2846 Handle<Code> ic = 2873 Handle<Code> ic =
2847 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2874 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2848 CallIC(ic, expr->AssignmentFeedbackId()); 2875 if (FLAG_vector_stores) {
2876 EmitLoadStoreICSlot(expr->AssignmentSlot());
2877 CallIC(ic);
2878 } else {
2879 CallIC(ic, expr->AssignmentFeedbackId());
2880 }
2849 2881
2850 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2882 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2851 context()->Plug(r0); 2883 context()->Plug(r0);
2852 } 2884 }
2853 2885
2854 2886
2855 void FullCodeGenerator::VisitProperty(Property* expr) { 2887 void FullCodeGenerator::VisitProperty(Property* expr) {
2856 Comment cmnt(masm_, "[ Property"); 2888 Comment cmnt(masm_, "[ Property");
2857 Expression* key = expr->key(); 2889 Expression* key = expr->key();
2858 2890
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
3087 3119
3088 3120
3089 void FullCodeGenerator::EmitLoadSuperConstructor() { 3121 void FullCodeGenerator::EmitLoadSuperConstructor() {
3090 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 3122 __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3091 __ Push(r0); 3123 __ Push(r0);
3092 __ CallRuntime(Runtime::kGetPrototype, 1); 3124 __ CallRuntime(Runtime::kGetPrototype, 1);
3093 } 3125 }
3094 3126
3095 3127
3096 void FullCodeGenerator::EmitInitializeThisAfterSuper( 3128 void FullCodeGenerator::EmitInitializeThisAfterSuper(
3097 SuperReference* super_ref) { 3129 SuperReference* super_ref, FeedbackVectorICSlot slot) {
3098 Variable* this_var = super_ref->this_var()->var(); 3130 Variable* this_var = super_ref->this_var()->var();
3099 GetVar(r1, this_var); 3131 GetVar(r1, this_var);
3100 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex); 3132 __ CompareRoot(r1, Heap::kTheHoleValueRootIndex);
3101 Label uninitialized_this; 3133 Label uninitialized_this;
3102 __ b(eq, &uninitialized_this); 3134 __ b(eq, &uninitialized_this);
3103 __ mov(r0, Operand(this_var->name())); 3135 __ mov(r0, Operand(this_var->name()));
3104 __ Push(r0); 3136 __ Push(r0);
3105 __ CallRuntime(Runtime::kThrowReferenceError, 1); 3137 __ CallRuntime(Runtime::kThrowReferenceError, 1);
3106 __ bind(&uninitialized_this); 3138 __ bind(&uninitialized_this);
3107 3139
3108 EmitVariableAssignment(this_var, Token::INIT_CONST); 3140 EmitVariableAssignment(this_var, Token::INIT_CONST, slot);
3109 } 3141 }
3110 3142
3111 3143
3112 void FullCodeGenerator::VisitCall(Call* expr) { 3144 void FullCodeGenerator::VisitCall(Call* expr) {
3113 #ifdef DEBUG 3145 #ifdef DEBUG
3114 // We want to verify that RecordJSReturnSite gets called on all paths 3146 // We want to verify that RecordJSReturnSite gets called on all paths
3115 // through this function. Avoid early returns. 3147 // through this function. Avoid early returns.
3116 expr->return_is_recorded_ = false; 3148 expr->return_is_recorded_ = false;
3117 #endif 3149 #endif
3118 3150
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
3325 __ Move(r2, FeedbackVector()); 3357 __ Move(r2, FeedbackVector());
3326 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); 3358 __ mov(r3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
3327 3359
3328 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); 3360 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
3329 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); 3361 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
3330 3362
3331 __ Drop(1); 3363 __ Drop(1);
3332 3364
3333 RecordJSReturnSite(expr); 3365 RecordJSReturnSite(expr);
3334 3366
3335 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); 3367 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(),
3368 expr->CallFeedbackICSlot());
3336 context()->Plug(r0); 3369 context()->Plug(r0);
3337 } 3370 }
3338 3371
3339 3372
3340 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 3373 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
3341 ZoneList<Expression*>* args = expr->arguments(); 3374 ZoneList<Expression*>* args = expr->arguments();
3342 DCHECK(args->length() == 1); 3375 DCHECK(args->length() == 1);
3343 3376
3344 VisitForAccumulatorValue(args->at(0)); 3377 VisitForAccumulatorValue(args->at(0));
3345 3378
(...skipping 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after
4614 // Push NewTarget 4647 // Push NewTarget
4615 DCHECK(args->at(2)->IsVariableProxy()); 4648 DCHECK(args->at(2)->IsVariableProxy());
4616 VisitForStackValue(args->at(2)); 4649 VisitForStackValue(args->at(2));
4617 4650
4618 EmitCallJSRuntimeFunction(call); 4651 EmitCallJSRuntimeFunction(call);
4619 4652
4620 // Restore context register. 4653 // Restore context register.
4621 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4654 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4622 context()->DropAndPlug(1, r0); 4655 context()->DropAndPlug(1, r0);
4623 4656
4657 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id.
4624 EmitInitializeThisAfterSuper(super_reference); 4658 EmitInitializeThisAfterSuper(super_reference);
4625 } 4659 }
4626 4660
4627 4661
4628 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 4662 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
4629 // Push the builtins object as the receiver. 4663 // Push the builtins object as the receiver.
4630 Register receiver = LoadDescriptor::ReceiverRegister(); 4664 Register receiver = LoadDescriptor::ReceiverRegister();
4631 __ ldr(receiver, GlobalObjectOperand()); 4665 __ ldr(receiver, GlobalObjectOperand());
4632 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); 4666 __ ldr(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
4633 __ push(receiver); 4667 __ push(receiver);
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
4816 } 4850 }
4817 4851
4818 4852
4819 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 4853 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
4820 DCHECK(expr->expression()->IsValidReferenceExpression()); 4854 DCHECK(expr->expression()->IsValidReferenceExpression());
4821 4855
4822 Comment cmnt(masm_, "[ CountOperation"); 4856 Comment cmnt(masm_, "[ CountOperation");
4823 SetSourcePosition(expr->position()); 4857 SetSourcePosition(expr->position());
4824 4858
4825 Property* prop = expr->expression()->AsProperty(); 4859 Property* prop = expr->expression()->AsProperty();
4826 LhsKind assign_type = GetAssignType(prop); 4860 LhsKind assign_type = Property::GetAssignType(prop);
4827 4861
4828 // Evaluate expression and get value. 4862 // Evaluate expression and get value.
4829 if (assign_type == VARIABLE) { 4863 if (assign_type == VARIABLE) {
4830 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4864 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4831 AccumulatorValueContext context(this); 4865 AccumulatorValueContext context(this);
4832 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4866 EmitVariableLoad(expr->expression()->AsVariableProxy());
4833 } else { 4867 } else {
4834 // Reserve space for result of postfix operation. 4868 // Reserve space for result of postfix operation.
4835 if (expr->is_postfix() && !context()->IsEffect()) { 4869 if (expr->is_postfix() && !context()->IsEffect()) {
4836 __ mov(ip, Operand(Smi::FromInt(0))); 4870 __ mov(ip, Operand(Smi::FromInt(0)));
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4981 CallIC(code, expr->CountBinOpFeedbackId()); 5015 CallIC(code, expr->CountBinOpFeedbackId());
4982 patch_site.EmitPatchInfo(); 5016 patch_site.EmitPatchInfo();
4983 __ bind(&done); 5017 __ bind(&done);
4984 5018
4985 // Store the value returned in r0. 5019 // Store the value returned in r0.
4986 switch (assign_type) { 5020 switch (assign_type) {
4987 case VARIABLE: 5021 case VARIABLE:
4988 if (expr->is_postfix()) { 5022 if (expr->is_postfix()) {
4989 { EffectContext context(this); 5023 { EffectContext context(this);
4990 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 5024 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4991 Token::ASSIGN); 5025 Token::ASSIGN, expr->CountSlot());
4992 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 5026 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4993 context.Plug(r0); 5027 context.Plug(r0);
4994 } 5028 }
4995 // For all contexts except EffectConstant We have the result on 5029 // For all contexts except EffectConstant We have the result on
4996 // top of the stack. 5030 // top of the stack.
4997 if (!context()->IsEffect()) { 5031 if (!context()->IsEffect()) {
4998 context()->PlugTOS(); 5032 context()->PlugTOS();
4999 } 5033 }
5000 } else { 5034 } else {
5001 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 5035 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
5002 Token::ASSIGN); 5036 Token::ASSIGN, expr->CountSlot());
5003 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 5037 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
5004 context()->Plug(r0); 5038 context()->Plug(r0);
5005 } 5039 }
5006 break; 5040 break;
5007 case NAMED_PROPERTY: { 5041 case NAMED_PROPERTY: {
5008 __ mov(StoreDescriptor::NameRegister(), 5042 __ mov(StoreDescriptor::NameRegister(),
5009 Operand(prop->key()->AsLiteral()->value())); 5043 Operand(prop->key()->AsLiteral()->value()));
5010 __ pop(StoreDescriptor::ReceiverRegister()); 5044 __ pop(StoreDescriptor::ReceiverRegister());
5011 CallStoreIC(expr->CountStoreFeedbackId()); 5045 if (FLAG_vector_stores) {
5046 EmitLoadStoreICSlot(expr->CountSlot());
5047 CallStoreIC();
5048 } else {
5049 CallStoreIC(expr->CountStoreFeedbackId());
5050 }
5012 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 5051 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
5013 if (expr->is_postfix()) { 5052 if (expr->is_postfix()) {
5014 if (!context()->IsEffect()) { 5053 if (!context()->IsEffect()) {
5015 context()->PlugTOS(); 5054 context()->PlugTOS();
5016 } 5055 }
5017 } else { 5056 } else {
5018 context()->Plug(r0); 5057 context()->Plug(r0);
5019 } 5058 }
5020 break; 5059 break;
5021 } 5060 }
(...skipping 17 matching lines...) Expand all
5039 } else { 5078 } else {
5040 context()->Plug(r0); 5079 context()->Plug(r0);
5041 } 5080 }
5042 break; 5081 break;
5043 } 5082 }
5044 case KEYED_PROPERTY: { 5083 case KEYED_PROPERTY: {
5045 __ Pop(StoreDescriptor::ReceiverRegister(), 5084 __ Pop(StoreDescriptor::ReceiverRegister(),
5046 StoreDescriptor::NameRegister()); 5085 StoreDescriptor::NameRegister());
5047 Handle<Code> ic = 5086 Handle<Code> ic =
5048 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 5087 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
5049 CallIC(ic, expr->CountStoreFeedbackId()); 5088 if (FLAG_vector_stores) {
5089 EmitLoadStoreICSlot(expr->CountSlot());
5090 CallIC(ic);
5091 } else {
5092 CallIC(ic, expr->CountStoreFeedbackId());
5093 }
5050 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 5094 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
5051 if (expr->is_postfix()) { 5095 if (expr->is_postfix()) {
5052 if (!context()->IsEffect()) { 5096 if (!context()->IsEffect()) {
5053 context()->PlugTOS(); 5097 context()->PlugTOS();
5054 } 5098 }
5055 } else { 5099 } else {
5056 context()->Plug(r0); 5100 context()->Plug(r0);
5057 } 5101 }
5058 break; 5102 break;
5059 } 5103 }
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
5374 void FullCodeGenerator::ClearPendingMessage() { 5418 void FullCodeGenerator::ClearPendingMessage() {
5375 DCHECK(!result_register().is(r1)); 5419 DCHECK(!result_register().is(r1));
5376 ExternalReference pending_message_obj = 5420 ExternalReference pending_message_obj =
5377 ExternalReference::address_of_pending_message_obj(isolate()); 5421 ExternalReference::address_of_pending_message_obj(isolate());
5378 __ LoadRoot(r1, Heap::kTheHoleValueRootIndex); 5422 __ LoadRoot(r1, Heap::kTheHoleValueRootIndex);
5379 __ mov(ip, Operand(pending_message_obj)); 5423 __ mov(ip, Operand(pending_message_obj));
5380 __ str(r1, MemOperand(ip)); 5424 __ str(r1, MemOperand(ip));
5381 } 5425 }
5382 5426
5383 5427
5428 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) {
5429 DCHECK(FLAG_vector_stores && !slot.IsInvalid());
5430 __ mov(VectorStoreICTrampolineDescriptor::SlotRegister(),
5431 Operand(SmiFromSlot(slot)));
5432 }
5433
5434
5384 #undef __ 5435 #undef __
5385 5436
5386 5437
5387 static Address GetInterruptImmediateLoadAddress(Address pc) { 5438 static Address GetInterruptImmediateLoadAddress(Address pc) {
5388 Address load_address = pc - 2 * Assembler::kInstrSize; 5439 Address load_address = pc - 2 * Assembler::kInstrSize;
5389 if (!FLAG_enable_ool_constant_pool) { 5440 if (!FLAG_enable_ool_constant_pool) {
5390 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(load_address))); 5441 DCHECK(Assembler::IsLdrPcImmediateOffset(Memory::int32_at(load_address)));
5391 } else if (Assembler::IsLdrPpRegOffset(Memory::int32_at(load_address))) { 5442 } else if (Assembler::IsLdrPpRegOffset(Memory::int32_at(load_address))) {
5392 // This is an extended constant pool lookup. 5443 // This is an extended constant pool lookup.
5393 if (CpuFeatures::IsSupported(ARMv7)) { 5444 if (CpuFeatures::IsSupported(ARMv7)) {
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
5519 5570
5520 DCHECK(interrupt_address == 5571 DCHECK(interrupt_address ==
5521 isolate->builtins()->OsrAfterStackCheck()->entry()); 5572 isolate->builtins()->OsrAfterStackCheck()->entry());
5522 return OSR_AFTER_STACK_CHECK; 5573 return OSR_AFTER_STACK_CHECK;
5523 } 5574 }
5524 5575
5525 5576
5526 } } // namespace v8::internal 5577 } } // namespace v8::internal
5527 5578
5528 #endif // V8_TARGET_ARCH_ARM 5579 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm64/full-codegen-arm64.cc » ('j') | src/ast.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698