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

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

Powered by Google App Engine
This is Rietveld 408576698