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

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

Powered by Google App Engine
This is Rietveld 408576698