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

Side by Side Diff: src/mips/full-codegen-mips.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, 6 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
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_MIPS 7 #if V8_TARGET_ARCH_MIPS
8 8
9 // Note on Mips implementation: 9 // Note on Mips implementation:
10 // 10 //
(...skipping 1234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1245 PrepareForBailoutForId(stmt->FilterId(), TOS_REG); 1245 PrepareForBailoutForId(stmt->FilterId(), TOS_REG);
1246 __ mov(a3, result_register()); 1246 __ mov(a3, result_register());
1247 __ Branch(loop_statement.continue_label(), eq, a3, Operand(zero_reg)); 1247 __ Branch(loop_statement.continue_label(), eq, a3, Operand(zero_reg));
1248 1248
1249 // Update the 'each' property or variable from the possibly filtered 1249 // Update the 'each' property or variable from the possibly filtered
1250 // entry in register a3. 1250 // entry in register a3.
1251 __ bind(&update_each); 1251 __ bind(&update_each);
1252 __ mov(result_register(), a3); 1252 __ mov(result_register(), a3);
1253 // Perform the assignment as if via '='. 1253 // Perform the assignment as if via '='.
1254 { EffectContext context(this); 1254 { EffectContext context(this);
1255 EmitAssignment(stmt->each()); 1255 EmitAssignment(stmt->each(), stmt->EachFeedbackSlot());
1256 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS); 1256 PrepareForBailoutForId(stmt->AssignmentId(), NO_REGISTERS);
1257 } 1257 }
1258 1258
1259 // Generate code for the body of the loop. 1259 // Generate code for the body of the loop.
1260 Visit(stmt->body()); 1260 Visit(stmt->body());
1261 1261
1262 // Generate code for the going to the next element by incrementing 1262 // Generate code for the going to the next element by incrementing
1263 // the index (smi) stored on top of the stack. 1263 // the index (smi) stored on top of the stack.
1264 __ bind(loop_statement.continue_label()); 1264 __ bind(loop_statement.continue_label());
1265 __ pop(a0); 1265 __ pop(a0);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1327 CallLoadIC(NOT_CONTEXTUAL); 1327 CallLoadIC(NOT_CONTEXTUAL);
1328 1328
1329 Label done; 1329 Label done;
1330 __ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value())); 1330 __ Branch(&done, ne, v0, Operand(isolate()->factory()->undefined_value()));
1331 __ CallRuntime(Runtime::kThrowNonMethodError, 0); 1331 __ CallRuntime(Runtime::kThrowNonMethodError, 0);
1332 __ bind(&done); 1332 __ bind(&done);
1333 } 1333 }
1334 1334
1335 1335
1336 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer, 1336 void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
1337 int offset) { 1337 int offset,
1338 FeedbackVectorICSlot slot) {
1338 if (NeedsHomeObject(initializer)) { 1339 if (NeedsHomeObject(initializer)) {
1339 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1340 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1340 __ li(StoreDescriptor::NameRegister(), 1341 __ li(StoreDescriptor::NameRegister(),
1341 Operand(isolate()->factory()->home_object_symbol())); 1342 Operand(isolate()->factory()->home_object_symbol()));
1342 __ lw(StoreDescriptor::ValueRegister(), 1343 __ lw(StoreDescriptor::ValueRegister(),
1343 MemOperand(sp, offset * kPointerSize)); 1344 MemOperand(sp, offset * kPointerSize));
1345 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
1344 CallStoreIC(); 1346 CallStoreIC();
1345 } 1347 }
1346 } 1348 }
1347 1349
1348 1350
1349 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, 1351 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
1350 TypeofState typeof_state, 1352 TypeofState typeof_state,
1351 Label* slow) { 1353 Label* slow) {
1352 Register current = cp; 1354 Register current = cp;
1353 Register next = a1; 1355 Register next = a1;
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 __ CallStub(&stub); 1658 __ CallStub(&stub);
1657 } 1659 }
1658 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG); 1660 PrepareForBailoutForId(expr->CreateLiteralId(), TOS_REG);
1659 1661
1660 // If result_saved is true the result is on top of the stack. If 1662 // If result_saved is true the result is on top of the stack. If
1661 // result_saved is false the result is in v0. 1663 // result_saved is false the result is in v0.
1662 bool result_saved = false; 1664 bool result_saved = false;
1663 1665
1664 AccessorTable accessor_table(zone()); 1666 AccessorTable accessor_table(zone());
1665 int property_index = 0; 1667 int property_index = 0;
1668 int store_slot_index = 0;
1666 for (; property_index < expr->properties()->length(); property_index++) { 1669 for (; property_index < expr->properties()->length(); property_index++) {
1667 ObjectLiteral::Property* property = expr->properties()->at(property_index); 1670 ObjectLiteral::Property* property = expr->properties()->at(property_index);
1668 if (property->is_computed_name()) break; 1671 if (property->is_computed_name()) break;
1669 if (property->IsCompileTimeValue()) continue; 1672 if (property->IsCompileTimeValue()) continue;
1670 1673
1671 Literal* key = property->key()->AsLiteral(); 1674 Literal* key = property->key()->AsLiteral();
1672 Expression* value = property->value(); 1675 Expression* value = property->value();
1673 if (!result_saved) { 1676 if (!result_saved) {
1674 __ push(v0); // Save result on stack. 1677 __ push(v0); // Save result on stack.
1675 result_saved = true; 1678 result_saved = true;
1676 } 1679 }
1677 switch (property->kind()) { 1680 switch (property->kind()) {
1678 case ObjectLiteral::Property::CONSTANT: 1681 case ObjectLiteral::Property::CONSTANT:
1679 UNREACHABLE(); 1682 UNREACHABLE();
1680 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1683 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1681 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); 1684 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value()));
1682 // Fall through. 1685 // Fall through.
1683 case ObjectLiteral::Property::COMPUTED: 1686 case ObjectLiteral::Property::COMPUTED:
1684 // It is safe to use [[Put]] here because the boilerplate already 1687 // It is safe to use [[Put]] here because the boilerplate already
1685 // contains computed properties with an uninitialized value. 1688 // contains computed properties with an uninitialized value.
1686 if (key->value()->IsInternalizedString()) { 1689 if (key->value()->IsInternalizedString()) {
1687 if (property->emit_store()) { 1690 if (property->emit_store()) {
1688 VisitForAccumulatorValue(value); 1691 VisitForAccumulatorValue(value);
1689 __ mov(StoreDescriptor::ValueRegister(), result_register()); 1692 __ mov(StoreDescriptor::ValueRegister(), result_register());
1690 DCHECK(StoreDescriptor::ValueRegister().is(a0)); 1693 DCHECK(StoreDescriptor::ValueRegister().is(a0));
1691 __ li(StoreDescriptor::NameRegister(), Operand(key->value())); 1694 __ li(StoreDescriptor::NameRegister(), Operand(key->value()));
1692 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp)); 1695 __ lw(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
1693 CallStoreIC(key->LiteralFeedbackId()); 1696 if (FLAG_vector_stores) {
1697 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
1698 CallStoreIC();
1699 } else {
1700 CallStoreIC(key->LiteralFeedbackId());
1701 }
1694 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1702 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1695 1703
1696 if (NeedsHomeObject(value)) { 1704 if (NeedsHomeObject(value)) {
1697 __ Move(StoreDescriptor::ReceiverRegister(), v0); 1705 __ Move(StoreDescriptor::ReceiverRegister(), v0);
1698 __ li(StoreDescriptor::NameRegister(), 1706 __ li(StoreDescriptor::NameRegister(),
1699 Operand(isolate()->factory()->home_object_symbol())); 1707 Operand(isolate()->factory()->home_object_symbol()));
1700 __ lw(StoreDescriptor::ValueRegister(), MemOperand(sp)); 1708 __ lw(StoreDescriptor::ValueRegister(), MemOperand(sp));
1709 if (FLAG_vector_stores) {
1710 EmitLoadStoreICSlot(expr->GetNthSlot(store_slot_index++));
1711 }
1701 CallStoreIC(); 1712 CallStoreIC();
1702 } 1713 }
1703 } else { 1714 } else {
1704 VisitForEffect(value); 1715 VisitForEffect(value);
1705 } 1716 }
1706 break; 1717 break;
1707 } 1718 }
1708 // Duplicate receiver on stack. 1719 // Duplicate receiver on stack.
1709 __ lw(a0, MemOperand(sp)); 1720 __ lw(a0, MemOperand(sp));
1710 __ push(a0); 1721 __ push(a0);
1711 VisitForStackValue(key); 1722 VisitForStackValue(key);
1712 VisitForStackValue(value); 1723 VisitForStackValue(value);
1713 if (property->emit_store()) { 1724 if (property->emit_store()) {
1714 EmitSetHomeObjectIfNeeded(value, 2); 1725 EmitSetHomeObjectIfNeeded(
1726 value, 2, expr->SlotForHomeObject(value, &store_slot_index));
1715 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes. 1727 __ li(a0, Operand(Smi::FromInt(SLOPPY))); // PropertyAttributes.
1716 __ push(a0); 1728 __ push(a0);
1717 __ CallRuntime(Runtime::kSetProperty, 4); 1729 __ CallRuntime(Runtime::kSetProperty, 4);
1718 } else { 1730 } else {
1719 __ Drop(3); 1731 __ Drop(3);
1720 } 1732 }
1721 break; 1733 break;
1722 case ObjectLiteral::Property::PROTOTYPE: 1734 case ObjectLiteral::Property::PROTOTYPE:
1723 // Duplicate receiver on stack. 1735 // Duplicate receiver on stack.
1724 __ lw(a0, MemOperand(sp)); 1736 __ lw(a0, MemOperand(sp));
(...skipping 17 matching lines...) Expand all
1742 1754
1743 // Emit code to define accessors, using only a single call to the runtime for 1755 // Emit code to define accessors, using only a single call to the runtime for
1744 // each pair of corresponding getters and setters. 1756 // each pair of corresponding getters and setters.
1745 for (AccessorTable::Iterator it = accessor_table.begin(); 1757 for (AccessorTable::Iterator it = accessor_table.begin();
1746 it != accessor_table.end(); 1758 it != accessor_table.end();
1747 ++it) { 1759 ++it) {
1748 __ lw(a0, MemOperand(sp)); // Duplicate receiver. 1760 __ lw(a0, MemOperand(sp)); // Duplicate receiver.
1749 __ push(a0); 1761 __ push(a0);
1750 VisitForStackValue(it->first); 1762 VisitForStackValue(it->first);
1751 EmitAccessor(it->second->getter); 1763 EmitAccessor(it->second->getter);
1752 EmitSetHomeObjectIfNeeded(it->second->getter, 2); 1764 EmitSetHomeObjectIfNeeded(
1765 it->second->getter, 2,
1766 expr->SlotForHomeObject(it->second->getter, &store_slot_index));
1753 EmitAccessor(it->second->setter); 1767 EmitAccessor(it->second->setter);
1754 EmitSetHomeObjectIfNeeded(it->second->setter, 3); 1768 EmitSetHomeObjectIfNeeded(
1769 it->second->setter, 3,
1770 expr->SlotForHomeObject(it->second->setter, &store_slot_index));
1755 __ li(a0, Operand(Smi::FromInt(NONE))); 1771 __ li(a0, Operand(Smi::FromInt(NONE)));
1756 __ push(a0); 1772 __ push(a0);
1757 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5); 1773 __ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
1758 } 1774 }
1759 1775
1760 // Object literals have two parts. The "static" part on the left contains no 1776 // Object literals have two parts. The "static" part on the left contains no
1761 // computed property names, and so we can compute its map ahead of time; see 1777 // computed property names, and so we can compute its map ahead of time; see
1762 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part 1778 // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
1763 // starts with the first computed property name, and continues with all 1779 // starts with the first computed property name, and continues with all
1764 // properties to its right. All the code from above initializes the static 1780 // properties to its right. All the code from above initializes the static
(...skipping 14 matching lines...) Expand all
1779 __ push(a0); 1795 __ push(a0);
1780 1796
1781 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) { 1797 if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
1782 DCHECK(!property->is_computed_name()); 1798 DCHECK(!property->is_computed_name());
1783 VisitForStackValue(value); 1799 VisitForStackValue(value);
1784 DCHECK(property->emit_store()); 1800 DCHECK(property->emit_store());
1785 __ CallRuntime(Runtime::kInternalSetPrototype, 2); 1801 __ CallRuntime(Runtime::kInternalSetPrototype, 2);
1786 } else { 1802 } else {
1787 EmitPropertyKey(property, expr->GetIdForProperty(property_index)); 1803 EmitPropertyKey(property, expr->GetIdForProperty(property_index));
1788 VisitForStackValue(value); 1804 VisitForStackValue(value);
1789 EmitSetHomeObjectIfNeeded(value, 2); 1805 EmitSetHomeObjectIfNeeded(
1806 value, 2, expr->SlotForHomeObject(value, &store_slot_index));
1790 1807
1791 switch (property->kind()) { 1808 switch (property->kind()) {
1792 case ObjectLiteral::Property::CONSTANT: 1809 case ObjectLiteral::Property::CONSTANT:
1793 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1810 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1794 case ObjectLiteral::Property::COMPUTED: 1811 case ObjectLiteral::Property::COMPUTED:
1795 if (property->emit_store()) { 1812 if (property->emit_store()) {
1796 __ li(a0, Operand(Smi::FromInt(NONE))); 1813 __ li(a0, Operand(Smi::FromInt(NONE)));
1797 __ push(a0); 1814 __ push(a0);
1798 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4); 1815 __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
1799 } else { 1816 } else {
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1941 } 1958 }
1942 } 1959 }
1943 1960
1944 1961
1945 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1962 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1946 DCHECK(expr->target()->IsValidReferenceExpression()); 1963 DCHECK(expr->target()->IsValidReferenceExpression());
1947 1964
1948 Comment cmnt(masm_, "[ Assignment"); 1965 Comment cmnt(masm_, "[ Assignment");
1949 1966
1950 Property* property = expr->target()->AsProperty(); 1967 Property* property = expr->target()->AsProperty();
1951 LhsKind assign_type = GetAssignType(property); 1968 LhsKind assign_type = Property::GetAssignType(property);
1952 1969
1953 // Evaluate LHS expression. 1970 // Evaluate LHS expression.
1954 switch (assign_type) { 1971 switch (assign_type) {
1955 case VARIABLE: 1972 case VARIABLE:
1956 // Nothing to do here. 1973 // Nothing to do here.
1957 break; 1974 break;
1958 case NAMED_PROPERTY: 1975 case NAMED_PROPERTY:
1959 if (expr->is_compound()) { 1976 if (expr->is_compound()) {
1960 // We need the receiver both on the stack and in the register. 1977 // We need the receiver both on the stack and in the register.
1961 VisitForStackValue(property->obj()); 1978 VisitForStackValue(property->obj());
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
2052 VisitForAccumulatorValue(expr->value()); 2069 VisitForAccumulatorValue(expr->value());
2053 } 2070 }
2054 2071
2055 // Record source position before possible IC call. 2072 // Record source position before possible IC call.
2056 SetSourcePosition(expr->position()); 2073 SetSourcePosition(expr->position());
2057 2074
2058 // Store the value. 2075 // Store the value.
2059 switch (assign_type) { 2076 switch (assign_type) {
2060 case VARIABLE: 2077 case VARIABLE:
2061 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), 2078 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(),
2062 expr->op()); 2079 expr->op(), expr->AssignmentSlot());
2063 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2080 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2064 context()->Plug(v0); 2081 context()->Plug(v0);
2065 break; 2082 break;
2066 case NAMED_PROPERTY: 2083 case NAMED_PROPERTY:
2067 EmitNamedPropertyAssignment(expr); 2084 EmitNamedPropertyAssignment(expr);
2068 break; 2085 break;
2069 case NAMED_SUPER_PROPERTY: 2086 case NAMED_SUPER_PROPERTY:
2070 EmitNamedSuperPropertyStore(property); 2087 EmitNamedSuperPropertyStore(property);
2071 context()->Plug(v0); 2088 context()->Plug(v0);
2072 break; 2089 break;
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after
2577 __ pop(a1); 2594 __ pop(a1);
2578 Handle<Code> code = CodeFactory::BinaryOpIC( 2595 Handle<Code> code = CodeFactory::BinaryOpIC(
2579 isolate(), op, language_mode()).code(); 2596 isolate(), op, language_mode()).code();
2580 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. 2597 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
2581 CallIC(code, expr->BinaryOperationFeedbackId()); 2598 CallIC(code, expr->BinaryOperationFeedbackId());
2582 patch_site.EmitPatchInfo(); 2599 patch_site.EmitPatchInfo();
2583 context()->Plug(v0); 2600 context()->Plug(v0);
2584 } 2601 }
2585 2602
2586 2603
2587 void FullCodeGenerator::EmitAssignment(Expression* expr) { 2604 void FullCodeGenerator::EmitAssignment(Expression* expr,
2605 FeedbackVectorICSlot slot) {
2588 DCHECK(expr->IsValidReferenceExpression()); 2606 DCHECK(expr->IsValidReferenceExpression());
2589 2607
2590 Property* prop = expr->AsProperty(); 2608 Property* prop = expr->AsProperty();
2591 LhsKind assign_type = GetAssignType(prop); 2609 LhsKind assign_type = Property::GetAssignType(prop);
2592 2610
2593 switch (assign_type) { 2611 switch (assign_type) {
2594 case VARIABLE: { 2612 case VARIABLE: {
2595 Variable* var = expr->AsVariableProxy()->var(); 2613 Variable* var = expr->AsVariableProxy()->var();
2596 EffectContext context(this); 2614 EffectContext context(this);
2597 EmitVariableAssignment(var, Token::ASSIGN); 2615 EmitVariableAssignment(var, Token::ASSIGN, slot);
2598 break; 2616 break;
2599 } 2617 }
2600 case NAMED_PROPERTY: { 2618 case NAMED_PROPERTY: {
2601 __ push(result_register()); // Preserve value. 2619 __ push(result_register()); // Preserve value.
2602 VisitForAccumulatorValue(prop->obj()); 2620 VisitForAccumulatorValue(prop->obj());
2603 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); 2621 __ mov(StoreDescriptor::ReceiverRegister(), result_register());
2604 __ pop(StoreDescriptor::ValueRegister()); // Restore value. 2622 __ pop(StoreDescriptor::ValueRegister()); // Restore value.
2605 __ li(StoreDescriptor::NameRegister(), 2623 __ li(StoreDescriptor::NameRegister(),
2606 Operand(prop->key()->AsLiteral()->value())); 2624 Operand(prop->key()->AsLiteral()->value()));
2625 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
2607 CallStoreIC(); 2626 CallStoreIC();
2608 break; 2627 break;
2609 } 2628 }
2610 case NAMED_SUPER_PROPERTY: { 2629 case NAMED_SUPER_PROPERTY: {
2611 __ Push(v0); 2630 __ Push(v0);
2612 VisitForStackValue(prop->obj()->AsSuperReference()->this_var()); 2631 VisitForStackValue(prop->obj()->AsSuperReference()->this_var());
2613 EmitLoadHomeObject(prop->obj()->AsSuperReference()); 2632 EmitLoadHomeObject(prop->obj()->AsSuperReference());
2614 // stack: value, this; v0: home_object 2633 // stack: value, this; v0: home_object
2615 Register scratch = a2; 2634 Register scratch = a2;
2616 Register scratch2 = a3; 2635 Register scratch2 = a3;
(...skipping 26 matching lines...) Expand all
2643 EmitKeyedSuperPropertyStore(prop); 2662 EmitKeyedSuperPropertyStore(prop);
2644 break; 2663 break;
2645 } 2664 }
2646 case KEYED_PROPERTY: { 2665 case KEYED_PROPERTY: {
2647 __ push(result_register()); // Preserve value. 2666 __ push(result_register()); // Preserve value.
2648 VisitForStackValue(prop->obj()); 2667 VisitForStackValue(prop->obj());
2649 VisitForAccumulatorValue(prop->key()); 2668 VisitForAccumulatorValue(prop->key());
2650 __ mov(StoreDescriptor::NameRegister(), result_register()); 2669 __ mov(StoreDescriptor::NameRegister(), result_register());
2651 __ Pop(StoreDescriptor::ValueRegister(), 2670 __ Pop(StoreDescriptor::ValueRegister(),
2652 StoreDescriptor::ReceiverRegister()); 2671 StoreDescriptor::ReceiverRegister());
2672 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
2653 Handle<Code> ic = 2673 Handle<Code> ic =
2654 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2674 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2655 CallIC(ic); 2675 CallIC(ic);
2656 break; 2676 break;
2657 } 2677 }
2658 } 2678 }
2659 context()->Plug(v0); 2679 context()->Plug(v0);
2660 } 2680 }
2661 2681
2662 2682
2663 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2683 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2664 Variable* var, MemOperand location) { 2684 Variable* var, MemOperand location) {
2665 __ sw(result_register(), location); 2685 __ sw(result_register(), location);
2666 if (var->IsContextSlot()) { 2686 if (var->IsContextSlot()) {
2667 // RecordWrite may destroy all its register arguments. 2687 // RecordWrite may destroy all its register arguments.
2668 __ Move(a3, result_register()); 2688 __ Move(a3, result_register());
2669 int offset = Context::SlotOffset(var->index()); 2689 int offset = Context::SlotOffset(var->index());
2670 __ RecordWriteContextSlot( 2690 __ RecordWriteContextSlot(
2671 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs); 2691 a1, offset, a3, a2, kRAHasBeenSaved, kDontSaveFPRegs);
2672 } 2692 }
2673 } 2693 }
2674 2694
2675 2695
2676 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) { 2696 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op,
2697 FeedbackVectorICSlot slot) {
2677 if (var->IsUnallocated()) { 2698 if (var->IsUnallocated()) {
2678 // Global var, const, or let. 2699 // Global var, const, or let.
2679 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2700 __ mov(StoreDescriptor::ValueRegister(), result_register());
2680 __ li(StoreDescriptor::NameRegister(), Operand(var->name())); 2701 __ li(StoreDescriptor::NameRegister(), Operand(var->name()));
2681 __ lw(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand()); 2702 __ lw(StoreDescriptor::ReceiverRegister(), GlobalObjectOperand());
2703 if (FLAG_vector_stores) EmitLoadStoreICSlot(slot);
2682 CallStoreIC(); 2704 CallStoreIC();
2683 2705
2684 } else if (var->mode() == LET && op != Token::INIT_LET) { 2706 } else if (var->mode() == LET && op != Token::INIT_LET) {
2685 // Non-initializing assignment to let variable needs a write barrier. 2707 // Non-initializing assignment to let variable needs a write barrier.
2686 DCHECK(!var->IsLookupSlot()); 2708 DCHECK(!var->IsLookupSlot());
2687 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); 2709 DCHECK(var->IsStackAllocated() || var->IsContextSlot());
2688 Label assign; 2710 Label assign;
2689 MemOperand location = VarOperand(var, a1); 2711 MemOperand location = VarOperand(var, a1);
2690 __ lw(a3, location); 2712 __ lw(a3, location);
2691 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex); 2713 __ LoadRoot(t0, Heap::kTheHoleValueRootIndex);
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2766 Property* prop = expr->target()->AsProperty(); 2788 Property* prop = expr->target()->AsProperty();
2767 DCHECK(prop != NULL); 2789 DCHECK(prop != NULL);
2768 DCHECK(prop->key()->IsLiteral()); 2790 DCHECK(prop->key()->IsLiteral());
2769 2791
2770 // Record source code position before IC call. 2792 // Record source code position before IC call.
2771 SetSourcePosition(expr->position()); 2793 SetSourcePosition(expr->position());
2772 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2794 __ mov(StoreDescriptor::ValueRegister(), result_register());
2773 __ li(StoreDescriptor::NameRegister(), 2795 __ li(StoreDescriptor::NameRegister(),
2774 Operand(prop->key()->AsLiteral()->value())); 2796 Operand(prop->key()->AsLiteral()->value()));
2775 __ pop(StoreDescriptor::ReceiverRegister()); 2797 __ pop(StoreDescriptor::ReceiverRegister());
2776 CallStoreIC(expr->AssignmentFeedbackId()); 2798 if (FLAG_vector_stores) {
2799 EmitLoadStoreICSlot(expr->AssignmentSlot());
2800 CallStoreIC();
2801 } else {
2802 CallStoreIC(expr->AssignmentFeedbackId());
2803 }
2777 2804
2778 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2805 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2779 context()->Plug(v0); 2806 context()->Plug(v0);
2780 } 2807 }
2781 2808
2782 2809
2783 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { 2810 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
2784 // Assignment to named property of super. 2811 // Assignment to named property of super.
2785 // v0 : value 2812 // v0 : value
2786 // stack : receiver ('this'), home_object 2813 // stack : receiver ('this'), home_object
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2819 // The arguments are: 2846 // The arguments are:
2820 // - a0 is the value, 2847 // - a0 is the value,
2821 // - a1 is the key, 2848 // - a1 is the key,
2822 // - a2 is the receiver. 2849 // - a2 is the receiver.
2823 __ mov(StoreDescriptor::ValueRegister(), result_register()); 2850 __ mov(StoreDescriptor::ValueRegister(), result_register());
2824 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister()); 2851 __ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
2825 DCHECK(StoreDescriptor::ValueRegister().is(a0)); 2852 DCHECK(StoreDescriptor::ValueRegister().is(a0));
2826 2853
2827 Handle<Code> ic = 2854 Handle<Code> ic =
2828 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 2855 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
2829 CallIC(ic, expr->AssignmentFeedbackId()); 2856 if (FLAG_vector_stores) {
2857 EmitLoadStoreICSlot(expr->AssignmentSlot());
2858 CallIC(ic);
2859 } else {
2860 CallIC(ic, expr->AssignmentFeedbackId());
2861 }
2830 2862
2831 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2863 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2832 context()->Plug(v0); 2864 context()->Plug(v0);
2833 } 2865 }
2834 2866
2835 2867
2836 void FullCodeGenerator::VisitProperty(Property* expr) { 2868 void FullCodeGenerator::VisitProperty(Property* expr) {
2837 Comment cmnt(masm_, "[ Property"); 2869 Comment cmnt(masm_, "[ Property");
2838 Expression* key = expr->key(); 2870 Expression* key = expr->key();
2839 2871
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
3059 3091
3060 3092
3061 void FullCodeGenerator::EmitLoadSuperConstructor() { 3093 void FullCodeGenerator::EmitLoadSuperConstructor() {
3062 __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); 3094 __ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
3063 __ Push(a0); 3095 __ Push(a0);
3064 __ CallRuntime(Runtime::kGetPrototype, 1); 3096 __ CallRuntime(Runtime::kGetPrototype, 1);
3065 } 3097 }
3066 3098
3067 3099
3068 void FullCodeGenerator::EmitInitializeThisAfterSuper( 3100 void FullCodeGenerator::EmitInitializeThisAfterSuper(
3069 SuperReference* super_ref) { 3101 SuperReference* super_ref, FeedbackVectorICSlot slot) {
3070 Variable* this_var = super_ref->this_var()->var(); 3102 Variable* this_var = super_ref->this_var()->var();
3071 GetVar(a1, this_var); 3103 GetVar(a1, this_var);
3072 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 3104 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
3073 Label uninitialized_this; 3105 Label uninitialized_this;
3074 __ Branch(&uninitialized_this, eq, a1, Operand(at)); 3106 __ Branch(&uninitialized_this, eq, a1, Operand(at));
3075 __ li(a0, Operand(this_var->name())); 3107 __ li(a0, Operand(this_var->name()));
3076 __ Push(a0); 3108 __ Push(a0);
3077 __ CallRuntime(Runtime::kThrowReferenceError, 1); 3109 __ CallRuntime(Runtime::kThrowReferenceError, 1);
3078 __ bind(&uninitialized_this); 3110 __ bind(&uninitialized_this);
3079 3111
3080 EmitVariableAssignment(this_var, Token::INIT_CONST); 3112 EmitVariableAssignment(this_var, Token::INIT_CONST, slot);
3081 } 3113 }
3082 3114
3083 3115
3084 void FullCodeGenerator::VisitCall(Call* expr) { 3116 void FullCodeGenerator::VisitCall(Call* expr) {
3085 #ifdef DEBUG 3117 #ifdef DEBUG
3086 // We want to verify that RecordJSReturnSite gets called on all paths 3118 // We want to verify that RecordJSReturnSite gets called on all paths
3087 // through this function. Avoid early returns. 3119 // through this function. Avoid early returns.
3088 expr->return_is_recorded_ = false; 3120 expr->return_is_recorded_ = false;
3089 #endif 3121 #endif
3090 3122
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
3295 __ li(a2, FeedbackVector()); 3327 __ li(a2, FeedbackVector());
3296 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot()))); 3328 __ li(a3, Operand(SmiFromSlot(expr->CallFeedbackSlot())));
3297 3329
3298 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET); 3330 CallConstructStub stub(isolate(), SUPER_CALL_RECORD_TARGET);
3299 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL); 3331 __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
3300 3332
3301 __ Drop(1); 3333 __ Drop(1);
3302 3334
3303 RecordJSReturnSite(expr); 3335 RecordJSReturnSite(expr);
3304 3336
3305 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference()); 3337 EmitInitializeThisAfterSuper(expr->expression()->AsSuperReference(),
3338 expr->CallFeedbackICSlot());
3306 context()->Plug(v0); 3339 context()->Plug(v0);
3307 } 3340 }
3308 3341
3309 3342
3310 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) { 3343 void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
3311 ZoneList<Expression*>* args = expr->arguments(); 3344 ZoneList<Expression*>* args = expr->arguments();
3312 DCHECK(args->length() == 1); 3345 DCHECK(args->length() == 1);
3313 3346
3314 VisitForAccumulatorValue(args->at(0)); 3347 VisitForAccumulatorValue(args->at(0));
3315 3348
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after
4618 // Push NewTarget 4651 // Push NewTarget
4619 DCHECK(args->at(2)->IsVariableProxy()); 4652 DCHECK(args->at(2)->IsVariableProxy());
4620 VisitForStackValue(args->at(2)); 4653 VisitForStackValue(args->at(2));
4621 4654
4622 EmitCallJSRuntimeFunction(call); 4655 EmitCallJSRuntimeFunction(call);
4623 4656
4624 // Restore context register. 4657 // Restore context register.
4625 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 4658 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
4626 context()->DropAndPlug(1, v0); 4659 context()->DropAndPlug(1, v0);
4627 4660
4661 // TODO(mvstanton): with FLAG_vector_stores this needs a slot id.
4628 EmitInitializeThisAfterSuper(super_reference); 4662 EmitInitializeThisAfterSuper(super_reference);
4629 } 4663 }
4630 4664
4631 4665
4632 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) { 4666 void FullCodeGenerator::EmitLoadJSRuntimeFunction(CallRuntime* expr) {
4633 // Push the builtins object as the receiver. 4667 // Push the builtins object as the receiver.
4634 Register receiver = LoadDescriptor::ReceiverRegister(); 4668 Register receiver = LoadDescriptor::ReceiverRegister();
4635 __ lw(receiver, GlobalObjectOperand()); 4669 __ lw(receiver, GlobalObjectOperand());
4636 __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset)); 4670 __ lw(receiver, FieldMemOperand(receiver, GlobalObject::kBuiltinsOffset));
4637 __ push(receiver); 4671 __ push(receiver);
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
4820 } 4854 }
4821 4855
4822 4856
4823 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { 4857 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
4824 DCHECK(expr->expression()->IsValidReferenceExpression()); 4858 DCHECK(expr->expression()->IsValidReferenceExpression());
4825 4859
4826 Comment cmnt(masm_, "[ CountOperation"); 4860 Comment cmnt(masm_, "[ CountOperation");
4827 SetSourcePosition(expr->position()); 4861 SetSourcePosition(expr->position());
4828 4862
4829 Property* prop = expr->expression()->AsProperty(); 4863 Property* prop = expr->expression()->AsProperty();
4830 LhsKind assign_type = GetAssignType(prop); 4864 LhsKind assign_type = Property::GetAssignType(prop);
4831 4865
4832 // Evaluate expression and get value. 4866 // Evaluate expression and get value.
4833 if (assign_type == VARIABLE) { 4867 if (assign_type == VARIABLE) {
4834 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); 4868 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL);
4835 AccumulatorValueContext context(this); 4869 AccumulatorValueContext context(this);
4836 EmitVariableLoad(expr->expression()->AsVariableProxy()); 4870 EmitVariableLoad(expr->expression()->AsVariableProxy());
4837 } else { 4871 } else {
4838 // Reserve space for result of postfix operation. 4872 // Reserve space for result of postfix operation.
4839 if (expr->is_postfix() && !context()->IsEffect()) { 4873 if (expr->is_postfix() && !context()->IsEffect()) {
4840 __ li(at, Operand(Smi::FromInt(0))); 4874 __ li(at, Operand(Smi::FromInt(0)));
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4985 CallIC(code, expr->CountBinOpFeedbackId()); 5019 CallIC(code, expr->CountBinOpFeedbackId());
4986 patch_site.EmitPatchInfo(); 5020 patch_site.EmitPatchInfo();
4987 __ bind(&done); 5021 __ bind(&done);
4988 5022
4989 // Store the value returned in v0. 5023 // Store the value returned in v0.
4990 switch (assign_type) { 5024 switch (assign_type) {
4991 case VARIABLE: 5025 case VARIABLE:
4992 if (expr->is_postfix()) { 5026 if (expr->is_postfix()) {
4993 { EffectContext context(this); 5027 { EffectContext context(this);
4994 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 5028 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
4995 Token::ASSIGN); 5029 Token::ASSIGN, expr->CountSlot());
4996 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 5030 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4997 context.Plug(v0); 5031 context.Plug(v0);
4998 } 5032 }
4999 // For all contexts except EffectConstant we have the result on 5033 // For all contexts except EffectConstant we have the result on
5000 // top of the stack. 5034 // top of the stack.
5001 if (!context()->IsEffect()) { 5035 if (!context()->IsEffect()) {
5002 context()->PlugTOS(); 5036 context()->PlugTOS();
5003 } 5037 }
5004 } else { 5038 } else {
5005 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 5039 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
5006 Token::ASSIGN); 5040 Token::ASSIGN, expr->CountSlot());
5007 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 5041 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
5008 context()->Plug(v0); 5042 context()->Plug(v0);
5009 } 5043 }
5010 break; 5044 break;
5011 case NAMED_PROPERTY: { 5045 case NAMED_PROPERTY: {
5012 __ mov(StoreDescriptor::ValueRegister(), result_register()); 5046 __ mov(StoreDescriptor::ValueRegister(), result_register());
5013 __ li(StoreDescriptor::NameRegister(), 5047 __ li(StoreDescriptor::NameRegister(),
5014 Operand(prop->key()->AsLiteral()->value())); 5048 Operand(prop->key()->AsLiteral()->value()));
5015 __ pop(StoreDescriptor::ReceiverRegister()); 5049 __ pop(StoreDescriptor::ReceiverRegister());
5016 CallStoreIC(expr->CountStoreFeedbackId()); 5050 if (FLAG_vector_stores) {
5051 EmitLoadStoreICSlot(expr->CountSlot());
5052 CallStoreIC();
5053 } else {
5054 CallStoreIC(expr->CountStoreFeedbackId());
5055 }
5017 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 5056 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
5018 if (expr->is_postfix()) { 5057 if (expr->is_postfix()) {
5019 if (!context()->IsEffect()) { 5058 if (!context()->IsEffect()) {
5020 context()->PlugTOS(); 5059 context()->PlugTOS();
5021 } 5060 }
5022 } else { 5061 } else {
5023 context()->Plug(v0); 5062 context()->Plug(v0);
5024 } 5063 }
5025 break; 5064 break;
5026 } 5065 }
(...skipping 18 matching lines...) Expand all
5045 context()->Plug(v0); 5084 context()->Plug(v0);
5046 } 5085 }
5047 break; 5086 break;
5048 } 5087 }
5049 case KEYED_PROPERTY: { 5088 case KEYED_PROPERTY: {
5050 __ mov(StoreDescriptor::ValueRegister(), result_register()); 5089 __ mov(StoreDescriptor::ValueRegister(), result_register());
5051 __ Pop(StoreDescriptor::ReceiverRegister(), 5090 __ Pop(StoreDescriptor::ReceiverRegister(),
5052 StoreDescriptor::NameRegister()); 5091 StoreDescriptor::NameRegister());
5053 Handle<Code> ic = 5092 Handle<Code> ic =
5054 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); 5093 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
5055 CallIC(ic, expr->CountStoreFeedbackId()); 5094 if (FLAG_vector_stores) {
5095 EmitLoadStoreICSlot(expr->CountSlot());
5096 CallIC(ic);
5097 } else {
5098 CallIC(ic, expr->CountStoreFeedbackId());
5099 }
5056 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 5100 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
5057 if (expr->is_postfix()) { 5101 if (expr->is_postfix()) {
5058 if (!context()->IsEffect()) { 5102 if (!context()->IsEffect()) {
5059 context()->PlugTOS(); 5103 context()->PlugTOS();
5060 } 5104 }
5061 } else { 5105 } else {
5062 context()->Plug(v0); 5106 context()->Plug(v0);
5063 } 5107 }
5064 break; 5108 break;
5065 } 5109 }
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
5377 void FullCodeGenerator::ClearPendingMessage() { 5421 void FullCodeGenerator::ClearPendingMessage() {
5378 DCHECK(!result_register().is(a1)); 5422 DCHECK(!result_register().is(a1));
5379 ExternalReference pending_message_obj = 5423 ExternalReference pending_message_obj =
5380 ExternalReference::address_of_pending_message_obj(isolate()); 5424 ExternalReference::address_of_pending_message_obj(isolate());
5381 __ LoadRoot(a1, Heap::kTheHoleValueRootIndex); 5425 __ LoadRoot(a1, Heap::kTheHoleValueRootIndex);
5382 __ li(at, Operand(pending_message_obj)); 5426 __ li(at, Operand(pending_message_obj));
5383 __ sw(a1, MemOperand(at)); 5427 __ sw(a1, MemOperand(at));
5384 } 5428 }
5385 5429
5386 5430
5431 void FullCodeGenerator::EmitLoadStoreICSlot(FeedbackVectorICSlot slot) {
5432 DCHECK(FLAG_vector_stores && !slot.IsInvalid());
5433 __ li(VectorStoreICTrampolineDescriptor::SlotRegister(),
5434 Operand(SmiFromSlot(slot)));
5435 }
5436
5437
5387 #undef __ 5438 #undef __
5388 5439
5389 5440
5390 void BackEdgeTable::PatchAt(Code* unoptimized_code, 5441 void BackEdgeTable::PatchAt(Code* unoptimized_code,
5391 Address pc, 5442 Address pc,
5392 BackEdgeState target_state, 5443 BackEdgeState target_state,
5393 Code* replacement_code) { 5444 Code* replacement_code) {
5394 static const int kInstrSize = Assembler::kInstrSize; 5445 static const int kInstrSize = Assembler::kInstrSize;
5395 Address branch_address = pc - 6 * kInstrSize; 5446 Address branch_address = pc - 6 * kInstrSize;
5396 CodePatcher patcher(branch_address, 1); 5447 CodePatcher patcher(branch_address, 1);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
5459 Assembler::target_address_at(pc_immediate_load_address)) == 5510 Assembler::target_address_at(pc_immediate_load_address)) ==
5460 reinterpret_cast<uint32_t>( 5511 reinterpret_cast<uint32_t>(
5461 isolate->builtins()->OsrAfterStackCheck()->entry())); 5512 isolate->builtins()->OsrAfterStackCheck()->entry()));
5462 return OSR_AFTER_STACK_CHECK; 5513 return OSR_AFTER_STACK_CHECK;
5463 } 5514 }
5464 5515
5465 5516
5466 } } // namespace v8::internal 5517 } } // namespace v8::internal
5467 5518
5468 #endif // V8_TARGET_ARCH_MIPS 5519 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698