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

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

Issue 6880036: Merge revision 7664 (revert of 7644 and 7632) to trunk. (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/assembler-x64-inl.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 26 matching lines...) Expand all
37 #include "parser.h" 37 #include "parser.h"
38 #include "scopes.h" 38 #include "scopes.h"
39 #include "stub-cache.h" 39 #include "stub-cache.h"
40 40
41 namespace v8 { 41 namespace v8 {
42 namespace internal { 42 namespace internal {
43 43
44 #define __ ACCESS_MASM(masm_) 44 #define __ ACCESS_MASM(masm_)
45 45
46 46
47 static unsigned GetPropertyId(Property* property) {
48 if (property->is_synthetic()) return AstNode::kNoNumber;
49 return property->id();
50 }
51
52
53 class JumpPatchSite BASE_EMBEDDED { 47 class JumpPatchSite BASE_EMBEDDED {
54 public: 48 public:
55 explicit JumpPatchSite(MacroAssembler* masm) 49 explicit JumpPatchSite(MacroAssembler* masm)
56 : masm_(masm) { 50 : masm_(masm) {
57 #ifdef DEBUG 51 #ifdef DEBUG
58 info_emitted_ = false; 52 info_emitted_ = false;
59 #endif 53 #endif
60 } 54 }
61 55
62 ~JumpPatchSite() { 56 ~JumpPatchSite() {
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 __ movq(rdx, rax); 736 __ movq(rdx, rax);
743 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); 737 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex);
744 } 738 }
745 ASSERT(prop->key()->AsLiteral() != NULL && 739 ASSERT(prop->key()->AsLiteral() != NULL &&
746 prop->key()->AsLiteral()->handle()->IsSmi()); 740 prop->key()->AsLiteral()->handle()->IsSmi());
747 __ Move(rcx, prop->key()->AsLiteral()->handle()); 741 __ Move(rcx, prop->key()->AsLiteral()->handle());
748 742
749 Handle<Code> ic = is_strict_mode() 743 Handle<Code> ic = is_strict_mode()
750 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 744 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
751 : isolate()->builtins()->KeyedStoreIC_Initialize(); 745 : isolate()->builtins()->KeyedStoreIC_Initialize();
752 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 746 EmitCallIC(ic, RelocInfo::CODE_TARGET);
753 } 747 }
754 } 748 }
755 } 749 }
756 750
757 751
758 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { 752 void FullCodeGenerator::VisitDeclaration(Declaration* decl) {
759 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); 753 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun());
760 } 754 }
761 755
762 756
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 __ cmpq(rdx, rax); 809 __ cmpq(rdx, rax);
816 __ j(not_equal, &next_test); 810 __ j(not_equal, &next_test);
817 __ Drop(1); // Switch value is no longer needed. 811 __ Drop(1); // Switch value is no longer needed.
818 __ jmp(clause->body_target()); 812 __ jmp(clause->body_target());
819 __ bind(&slow_case); 813 __ bind(&slow_case);
820 } 814 }
821 815
822 // Record position before stub call for type feedback. 816 // Record position before stub call for type feedback.
823 SetSourcePosition(clause->position()); 817 SetSourcePosition(clause->position());
824 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); 818 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT);
825 EmitCallIC(ic, &patch_site, clause->label()->id()); 819 EmitCallIC(ic, &patch_site);
826 820
827 __ testq(rax, rax); 821 __ testq(rax, rax);
828 __ j(not_equal, &next_test); 822 __ j(not_equal, &next_test);
829 __ Drop(1); // Switch value is no longer needed. 823 __ Drop(1); // Switch value is no longer needed.
830 __ jmp(clause->body_target()); 824 __ jmp(clause->body_target());
831 } 825 }
832 826
833 // Discard the test value and jump to the default if present, otherwise to 827 // Discard the test value and jump to the default if present, otherwise to
834 // the end of the statement. 828 // the end of the statement.
835 __ bind(&next_test); 829 __ bind(&next_test);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 } 1118 }
1125 1119
1126 // All extension objects were empty and it is safe to use a global 1120 // All extension objects were empty and it is safe to use a global
1127 // load IC call. 1121 // load IC call.
1128 __ movq(rax, GlobalObjectOperand()); 1122 __ movq(rax, GlobalObjectOperand());
1129 __ Move(rcx, slot->var()->name()); 1123 __ Move(rcx, slot->var()->name());
1130 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1124 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1131 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) 1125 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF)
1132 ? RelocInfo::CODE_TARGET 1126 ? RelocInfo::CODE_TARGET
1133 : RelocInfo::CODE_TARGET_CONTEXT; 1127 : RelocInfo::CODE_TARGET_CONTEXT;
1134 EmitCallIC(ic, mode, AstNode::kNoNumber); 1128 EmitCallIC(ic, mode);
1135 } 1129 }
1136 1130
1137 1131
1138 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( 1132 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(
1139 Slot* slot, 1133 Slot* slot,
1140 Label* slow) { 1134 Label* slow) {
1141 ASSERT(slot->type() == Slot::CONTEXT); 1135 ASSERT(slot->type() == Slot::CONTEXT);
1142 Register context = rsi; 1136 Register context = rsi;
1143 Register temp = rbx; 1137 Register temp = rbx;
1144 1138
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 key_literal->handle()->IsSmi()) { 1199 key_literal->handle()->IsSmi()) {
1206 // Load arguments object if there are no eval-introduced 1200 // Load arguments object if there are no eval-introduced
1207 // variables. Then load the argument from the arguments 1201 // variables. Then load the argument from the arguments
1208 // object using keyed load. 1202 // object using keyed load.
1209 __ movq(rdx, 1203 __ movq(rdx,
1210 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), 1204 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(),
1211 slow)); 1205 slow));
1212 __ Move(rax, key_literal->handle()); 1206 __ Move(rax, key_literal->handle());
1213 Handle<Code> ic = 1207 Handle<Code> ic =
1214 isolate()->builtins()->KeyedLoadIC_Initialize(); 1208 isolate()->builtins()->KeyedLoadIC_Initialize();
1215 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); 1209 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1216 __ jmp(done); 1210 __ jmp(done);
1217 } 1211 }
1218 } 1212 }
1219 } 1213 }
1220 } 1214 }
1221 } 1215 }
1222 1216
1223 1217
1224 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1218 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1225 // Four cases: non-this global variables, lookup slots, all other 1219 // Four cases: non-this global variables, lookup slots, all other
1226 // types of slots, and parameters that rewrite to explicit property 1220 // types of slots, and parameters that rewrite to explicit property
1227 // accesses on the arguments object. 1221 // accesses on the arguments object.
1228 Slot* slot = var->AsSlot(); 1222 Slot* slot = var->AsSlot();
1229 Property* property = var->AsProperty(); 1223 Property* property = var->AsProperty();
1230 1224
1231 if (var->is_global() && !var->is_this()) { 1225 if (var->is_global() && !var->is_this()) {
1232 Comment cmnt(masm_, "Global variable"); 1226 Comment cmnt(masm_, "Global variable");
1233 // Use inline caching. Variable name is passed in rcx and the global 1227 // Use inline caching. Variable name is passed in rcx and the global
1234 // object on the stack. 1228 // object on the stack.
1235 __ Move(rcx, var->name()); 1229 __ Move(rcx, var->name());
1236 __ movq(rax, GlobalObjectOperand()); 1230 __ movq(rax, GlobalObjectOperand());
1237 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1231 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1238 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1232 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1239 context()->Plug(rax); 1233 context()->Plug(rax);
1240 1234
1241 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1235 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1242 Label done, slow; 1236 Label done, slow;
1243 1237
1244 // Generate code for loading from variables potentially shadowed 1238 // Generate code for loading from variables potentially shadowed
1245 // by eval-introduced variables. 1239 // by eval-introduced variables.
1246 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1240 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1247 1241
1248 __ bind(&slow); 1242 __ bind(&slow);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 // Assert that the key is a smi. 1285 // Assert that the key is a smi.
1292 Literal* key_literal = property->key()->AsLiteral(); 1286 Literal* key_literal = property->key()->AsLiteral();
1293 ASSERT_NOT_NULL(key_literal); 1287 ASSERT_NOT_NULL(key_literal);
1294 ASSERT(key_literal->handle()->IsSmi()); 1288 ASSERT(key_literal->handle()->IsSmi());
1295 1289
1296 // Load the key. 1290 // Load the key.
1297 __ Move(rax, key_literal->handle()); 1291 __ Move(rax, key_literal->handle());
1298 1292
1299 // Do a keyed property load. 1293 // Do a keyed property load.
1300 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1294 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1301 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); 1295 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1302 context()->Plug(rax); 1296 context()->Plug(rax);
1303 } 1297 }
1304 } 1298 }
1305 1299
1306 1300
1307 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1301 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1308 Comment cmnt(masm_, "[ RegExpLiteral"); 1302 Comment cmnt(masm_, "[ RegExpLiteral");
1309 Label materialized; 1303 Label materialized;
1310 // Registers will be used as follows: 1304 // Registers will be used as follows:
1311 // rdi = JS function. 1305 // rdi = JS function.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 1396 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
1403 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); 1397 ASSERT(!CompileTimeValue::IsCompileTimeValue(value));
1404 // Fall through. 1398 // Fall through.
1405 case ObjectLiteral::Property::COMPUTED: 1399 case ObjectLiteral::Property::COMPUTED:
1406 if (key->handle()->IsSymbol()) { 1400 if (key->handle()->IsSymbol()) {
1407 VisitForAccumulatorValue(value); 1401 VisitForAccumulatorValue(value);
1408 __ Move(rcx, key->handle()); 1402 __ Move(rcx, key->handle());
1409 __ movq(rdx, Operand(rsp, 0)); 1403 __ movq(rdx, Operand(rsp, 0));
1410 if (property->emit_store()) { 1404 if (property->emit_store()) {
1411 Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize(); 1405 Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize();
1412 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id()); 1406 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1413 PrepareForBailoutForId(key->id(), NO_REGISTERS); 1407 PrepareForBailoutForId(key->id(), NO_REGISTERS);
1414 } 1408 }
1415 break; 1409 break;
1416 } 1410 }
1417 // Fall through. 1411 // Fall through.
1418 case ObjectLiteral::Property::PROTOTYPE: 1412 case ObjectLiteral::Property::PROTOTYPE:
1419 __ push(Operand(rsp, 0)); // Duplicate receiver. 1413 __ push(Operand(rsp, 0)); // Duplicate receiver.
1420 VisitForStackValue(key); 1414 VisitForStackValue(key);
1421 VisitForStackValue(value); 1415 VisitForStackValue(value);
1422 if (property->emit_store()) { 1416 if (property->emit_store()) {
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 Token::Value op = expr->binary_op(); 1599 Token::Value op = expr->binary_op();
1606 __ push(rax); // Left operand goes on the stack. 1600 __ push(rax); // Left operand goes on the stack.
1607 VisitForAccumulatorValue(expr->value()); 1601 VisitForAccumulatorValue(expr->value());
1608 1602
1609 OverwriteMode mode = expr->value()->ResultOverwriteAllowed() 1603 OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
1610 ? OVERWRITE_RIGHT 1604 ? OVERWRITE_RIGHT
1611 : NO_OVERWRITE; 1605 : NO_OVERWRITE;
1612 SetSourcePosition(expr->position() + 1); 1606 SetSourcePosition(expr->position() + 1);
1613 AccumulatorValueContext context(this); 1607 AccumulatorValueContext context(this);
1614 if (ShouldInlineSmiCase(op)) { 1608 if (ShouldInlineSmiCase(op)) {
1615 EmitInlineSmiBinaryOp(expr->binary_operation(), 1609 EmitInlineSmiBinaryOp(expr,
1616 op, 1610 op,
1617 mode, 1611 mode,
1618 expr->target(), 1612 expr->target(),
1619 expr->value()); 1613 expr->value());
1620 } else { 1614 } else {
1621 EmitBinaryOp(expr->binary_operation(), op, mode); 1615 EmitBinaryOp(op, mode);
1622 } 1616 }
1623 // Deoptimization point in case the binary operation may have side effects. 1617 // Deoptimization point in case the binary operation may have side effects.
1624 PrepareForBailout(expr->binary_operation(), TOS_REG); 1618 PrepareForBailout(expr->binary_operation(), TOS_REG);
1625 } else { 1619 } else {
1626 VisitForAccumulatorValue(expr->value()); 1620 VisitForAccumulatorValue(expr->value());
1627 } 1621 }
1628 1622
1629 // Record source position before possible IC call. 1623 // Record source position before possible IC call.
1630 SetSourcePosition(expr->position()); 1624 SetSourcePosition(expr->position());
1631 1625
(...skipping 13 matching lines...) Expand all
1645 break; 1639 break;
1646 } 1640 }
1647 } 1641 }
1648 1642
1649 1643
1650 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { 1644 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
1651 SetSourcePosition(prop->position()); 1645 SetSourcePosition(prop->position());
1652 Literal* key = prop->key()->AsLiteral(); 1646 Literal* key = prop->key()->AsLiteral();
1653 __ Move(rcx, key->handle()); 1647 __ Move(rcx, key->handle());
1654 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1648 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1655 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 1649 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1656 } 1650 }
1657 1651
1658 1652
1659 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { 1653 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
1660 SetSourcePosition(prop->position()); 1654 SetSourcePosition(prop->position());
1661 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 1655 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1662 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 1656 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1663 } 1657 }
1664 1658
1665 1659
1666 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, 1660 void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
1667 Token::Value op, 1661 Token::Value op,
1668 OverwriteMode mode, 1662 OverwriteMode mode,
1669 Expression* left, 1663 Expression* left,
1670 Expression* right) { 1664 Expression* right) {
1671 // Do combined smi check of the operands. Left operand is on the 1665 // Do combined smi check of the operands. Left operand is on the
1672 // stack (popped into rdx). Right operand is in rax but moved into 1666 // stack (popped into rdx). Right operand is in rax but moved into
1673 // rcx to make the shifts easier. 1667 // rcx to make the shifts easier.
1674 NearLabel done, stub_call, smi_case; 1668 NearLabel done, stub_call, smi_case;
1675 __ pop(rdx); 1669 __ pop(rdx);
1676 __ movq(rcx, rax); 1670 __ movq(rcx, rax);
1677 __ or_(rax, rdx); 1671 __ or_(rax, rdx);
1678 JumpPatchSite patch_site(masm_); 1672 JumpPatchSite patch_site(masm_);
1679 patch_site.EmitJumpIfSmi(rax, &smi_case); 1673 patch_site.EmitJumpIfSmi(rax, &smi_case);
1680 1674
1681 __ bind(&stub_call); 1675 __ bind(&stub_call);
1682 __ movq(rax, rcx); 1676 __ movq(rax, rcx);
1683 TypeRecordingBinaryOpStub stub(op, mode); 1677 TypeRecordingBinaryOpStub stub(op, mode);
1684 EmitCallIC(stub.GetCode(), &patch_site, expr->id()); 1678 EmitCallIC(stub.GetCode(), &patch_site);
1685 __ jmp(&done); 1679 __ jmp(&done);
1686 1680
1687 __ bind(&smi_case); 1681 __ bind(&smi_case);
1688 switch (op) { 1682 switch (op) {
1689 case Token::SAR: 1683 case Token::SAR:
1690 __ SmiShiftArithmeticRight(rax, rdx, rcx); 1684 __ SmiShiftArithmeticRight(rax, rdx, rcx);
1691 break; 1685 break;
1692 case Token::SHL: 1686 case Token::SHL:
1693 __ SmiShiftLeft(rax, rdx, rcx); 1687 __ SmiShiftLeft(rax, rdx, rcx);
1694 break; 1688 break;
(...skipping 21 matching lines...) Expand all
1716 default: 1710 default:
1717 UNREACHABLE(); 1711 UNREACHABLE();
1718 break; 1712 break;
1719 } 1713 }
1720 1714
1721 __ bind(&done); 1715 __ bind(&done);
1722 context()->Plug(rax); 1716 context()->Plug(rax);
1723 } 1717 }
1724 1718
1725 1719
1726 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, 1720 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
1727 Token::Value op,
1728 OverwriteMode mode) { 1721 OverwriteMode mode) {
1729 __ pop(rdx); 1722 __ pop(rdx);
1730 TypeRecordingBinaryOpStub stub(op, mode); 1723 TypeRecordingBinaryOpStub stub(op, mode);
1731 // NULL signals no inlined smi code. 1724 EmitCallIC(stub.GetCode(), NULL); // NULL signals no inlined smi code.
1732 EmitCallIC(stub.GetCode(), NULL, expr->id());
1733 context()->Plug(rax); 1725 context()->Plug(rax);
1734 } 1726 }
1735 1727
1736 1728
1737 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1729 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1738 // Invalid left-hand sides are rewritten to have a 'throw 1730 // Invalid left-hand sides are rewritten to have a 'throw
1739 // ReferenceError' on the left-hand side. 1731 // ReferenceError' on the left-hand side.
1740 if (!expr->IsValidLeftHandSide()) { 1732 if (!expr->IsValidLeftHandSide()) {
1741 VisitForEffect(expr); 1733 VisitForEffect(expr);
1742 return; 1734 return;
(...skipping 19 matching lines...) Expand all
1762 } 1754 }
1763 case NAMED_PROPERTY: { 1755 case NAMED_PROPERTY: {
1764 __ push(rax); // Preserve value. 1756 __ push(rax); // Preserve value.
1765 VisitForAccumulatorValue(prop->obj()); 1757 VisitForAccumulatorValue(prop->obj());
1766 __ movq(rdx, rax); 1758 __ movq(rdx, rax);
1767 __ pop(rax); // Restore value. 1759 __ pop(rax); // Restore value.
1768 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1760 __ Move(rcx, prop->key()->AsLiteral()->handle());
1769 Handle<Code> ic = is_strict_mode() 1761 Handle<Code> ic = is_strict_mode()
1770 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1762 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1771 : isolate()->builtins()->StoreIC_Initialize(); 1763 : isolate()->builtins()->StoreIC_Initialize();
1772 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1764 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1773 break; 1765 break;
1774 } 1766 }
1775 case KEYED_PROPERTY: { 1767 case KEYED_PROPERTY: {
1776 __ push(rax); // Preserve value. 1768 __ push(rax); // Preserve value.
1777 if (prop->is_synthetic()) { 1769 if (prop->is_synthetic()) {
1778 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1770 ASSERT(prop->obj()->AsVariableProxy() != NULL);
1779 ASSERT(prop->key()->AsLiteral() != NULL); 1771 ASSERT(prop->key()->AsLiteral() != NULL);
1780 { AccumulatorValueContext for_object(this); 1772 { AccumulatorValueContext for_object(this);
1781 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); 1773 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1782 } 1774 }
1783 __ movq(rdx, rax); 1775 __ movq(rdx, rax);
1784 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1776 __ Move(rcx, prop->key()->AsLiteral()->handle());
1785 } else { 1777 } else {
1786 VisitForStackValue(prop->obj()); 1778 VisitForStackValue(prop->obj());
1787 VisitForAccumulatorValue(prop->key()); 1779 VisitForAccumulatorValue(prop->key());
1788 __ movq(rcx, rax); 1780 __ movq(rcx, rax);
1789 __ pop(rdx); 1781 __ pop(rdx);
1790 } 1782 }
1791 __ pop(rax); // Restore value. 1783 __ pop(rax); // Restore value.
1792 Handle<Code> ic = is_strict_mode() 1784 Handle<Code> ic = is_strict_mode()
1793 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1785 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1794 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1786 : isolate()->builtins()->KeyedStoreIC_Initialize();
1795 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1787 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1796 break; 1788 break;
1797 } 1789 }
1798 } 1790 }
1799 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1791 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1800 context()->Plug(rax); 1792 context()->Plug(rax);
1801 } 1793 }
1802 1794
1803 1795
1804 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1796 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1805 Token::Value op) { 1797 Token::Value op) {
1806 // Left-hand sides that rewrite to explicit property accesses do not reach 1798 // Left-hand sides that rewrite to explicit property accesses do not reach
1807 // here. 1799 // here.
1808 ASSERT(var != NULL); 1800 ASSERT(var != NULL);
1809 ASSERT(var->is_global() || var->AsSlot() != NULL); 1801 ASSERT(var->is_global() || var->AsSlot() != NULL);
1810 1802
1811 if (var->is_global()) { 1803 if (var->is_global()) {
1812 ASSERT(!var->is_this()); 1804 ASSERT(!var->is_this());
1813 // Assignment to a global variable. Use inline caching for the 1805 // Assignment to a global variable. Use inline caching for the
1814 // assignment. Right-hand-side value is passed in rax, variable name in 1806 // assignment. Right-hand-side value is passed in rax, variable name in
1815 // rcx, and the global object on the stack. 1807 // rcx, and the global object on the stack.
1816 __ Move(rcx, var->name()); 1808 __ Move(rcx, var->name());
1817 __ movq(rdx, GlobalObjectOperand()); 1809 __ movq(rdx, GlobalObjectOperand());
1818 Handle<Code> ic = is_strict_mode() 1810 Handle<Code> ic = is_strict_mode()
1819 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1811 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1820 : isolate()->builtins()->StoreIC_Initialize(); 1812 : isolate()->builtins()->StoreIC_Initialize();
1821 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1813 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT);
1822 1814
1823 } else if (op == Token::INIT_CONST) { 1815 } else if (op == Token::INIT_CONST) {
1824 // Like var declarations, const declarations are hoisted to function 1816 // Like var declarations, const declarations are hoisted to function
1825 // scope. However, unlike var initializers, const initializers are able 1817 // scope. However, unlike var initializers, const initializers are able
1826 // to drill a hole to that function context, even from inside a 'with' 1818 // to drill a hole to that function context, even from inside a 'with'
1827 // context. We thus bypass the normal static scope lookup. 1819 // context. We thus bypass the normal static scope lookup.
1828 Slot* slot = var->AsSlot(); 1820 Slot* slot = var->AsSlot();
1829 Label skip; 1821 Label skip;
1830 switch (slot->type()) { 1822 switch (slot->type()) {
1831 case Slot::PARAMETER: 1823 case Slot::PARAMETER:
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 SetSourcePosition(expr->position()); 1906 SetSourcePosition(expr->position());
1915 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1907 __ Move(rcx, prop->key()->AsLiteral()->handle());
1916 if (expr->ends_initialization_block()) { 1908 if (expr->ends_initialization_block()) {
1917 __ movq(rdx, Operand(rsp, 0)); 1909 __ movq(rdx, Operand(rsp, 0));
1918 } else { 1910 } else {
1919 __ pop(rdx); 1911 __ pop(rdx);
1920 } 1912 }
1921 Handle<Code> ic = is_strict_mode() 1913 Handle<Code> ic = is_strict_mode()
1922 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1914 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1923 : isolate()->builtins()->StoreIC_Initialize(); 1915 : isolate()->builtins()->StoreIC_Initialize();
1924 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 1916 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1925 1917
1926 // If the assignment ends an initialization block, revert to fast case. 1918 // If the assignment ends an initialization block, revert to fast case.
1927 if (expr->ends_initialization_block()) { 1919 if (expr->ends_initialization_block()) {
1928 __ push(rax); // Result of assignment, saved even if not needed. 1920 __ push(rax); // Result of assignment, saved even if not needed.
1929 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. 1921 __ push(Operand(rsp, kPointerSize)); // Receiver is under value.
1930 __ CallRuntime(Runtime::kToFastProperties, 1); 1922 __ CallRuntime(Runtime::kToFastProperties, 1);
1931 __ pop(rax); 1923 __ pop(rax);
1932 __ Drop(1); 1924 __ Drop(1);
1933 } 1925 }
1934 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 1926 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
(...skipping 19 matching lines...) Expand all
1954 if (expr->ends_initialization_block()) { 1946 if (expr->ends_initialization_block()) {
1955 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. 1947 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later.
1956 } else { 1948 } else {
1957 __ pop(rdx); 1949 __ pop(rdx);
1958 } 1950 }
1959 // Record source code position before IC call. 1951 // Record source code position before IC call.
1960 SetSourcePosition(expr->position()); 1952 SetSourcePosition(expr->position());
1961 Handle<Code> ic = is_strict_mode() 1953 Handle<Code> ic = is_strict_mode()
1962 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1954 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1963 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1955 : isolate()->builtins()->KeyedStoreIC_Initialize();
1964 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 1956 EmitCallIC(ic, RelocInfo::CODE_TARGET);
1965 1957
1966 // If the assignment ends an initialization block, revert to fast case. 1958 // If the assignment ends an initialization block, revert to fast case.
1967 if (expr->ends_initialization_block()) { 1959 if (expr->ends_initialization_block()) {
1968 __ pop(rdx); 1960 __ pop(rdx);
1969 __ push(rax); // Result of assignment, saved even if not needed. 1961 __ push(rax); // Result of assignment, saved even if not needed.
1970 __ push(rdx); 1962 __ push(rdx);
1971 __ CallRuntime(Runtime::kToFastProperties, 1); 1963 __ CallRuntime(Runtime::kToFastProperties, 1);
1972 __ pop(rax); 1964 __ pop(rax);
1973 } 1965 }
1974 1966
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2006 VisitForStackValue(args->at(i)); 1998 VisitForStackValue(args->at(i));
2007 } 1999 }
2008 __ Move(rcx, name); 2000 __ Move(rcx, name);
2009 } 2001 }
2010 // Record source position for debugger. 2002 // Record source position for debugger.
2011 SetSourcePosition(expr->position()); 2003 SetSourcePosition(expr->position());
2012 // Call the IC initialization code. 2004 // Call the IC initialization code.
2013 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2005 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2014 Handle<Code> ic = 2006 Handle<Code> ic =
2015 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop); 2007 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop);
2016 EmitCallIC(ic, mode, expr->id()); 2008 EmitCallIC(ic, mode);
2017 RecordJSReturnSite(expr); 2009 RecordJSReturnSite(expr);
2018 // Restore context register. 2010 // Restore context register.
2019 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2011 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2020 context()->Plug(rax); 2012 context()->Plug(rax);
2021 } 2013 }
2022 2014
2023 2015
2024 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, 2016 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
2025 Expression* key, 2017 Expression* key,
2026 RelocInfo::Mode mode) { 2018 RelocInfo::Mode mode) {
(...skipping 14 matching lines...) Expand all
2041 VisitForStackValue(args->at(i)); 2033 VisitForStackValue(args->at(i));
2042 } 2034 }
2043 } 2035 }
2044 // Record source position for debugger. 2036 // Record source position for debugger.
2045 SetSourcePosition(expr->position()); 2037 SetSourcePosition(expr->position());
2046 // Call the IC initialization code. 2038 // Call the IC initialization code.
2047 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 2039 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
2048 Handle<Code> ic = 2040 Handle<Code> ic =
2049 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); 2041 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop);
2050 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. 2042 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key.
2051 EmitCallIC(ic, mode, expr->id()); 2043 EmitCallIC(ic, mode);
2052 RecordJSReturnSite(expr); 2044 RecordJSReturnSite(expr);
2053 // Restore context register. 2045 // Restore context register.
2054 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 2046 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
2055 context()->DropAndPlug(1, rax); // Drop the key still on the stack. 2047 context()->DropAndPlug(1, rax); // Drop the key still on the stack.
2056 } 2048 }
2057 2049
2058 2050
2059 void FullCodeGenerator::EmitCallWithStub(Call* expr) { 2051 void FullCodeGenerator::EmitCallWithStub(Call* expr) {
2060 // Code common for calls using the call stub. 2052 // Code common for calls using the call stub.
2061 ZoneList<Expression*>* args = expr->arguments(); 2053 ZoneList<Expression*>* args = expr->arguments();
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2233 __ movq(rdx, operand); 2225 __ movq(rdx, operand);
2234 2226
2235 ASSERT(prop->key()->AsLiteral() != NULL); 2227 ASSERT(prop->key()->AsLiteral() != NULL);
2236 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); 2228 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi());
2237 __ Move(rax, prop->key()->AsLiteral()->handle()); 2229 __ Move(rax, prop->key()->AsLiteral()->handle());
2238 2230
2239 // Record source code position for IC call. 2231 // Record source code position for IC call.
2240 SetSourcePosition(prop->position()); 2232 SetSourcePosition(prop->position());
2241 2233
2242 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2234 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2243 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); 2235 EmitCallIC(ic, RelocInfo::CODE_TARGET);
2244 // Push result (function). 2236 // Push result (function).
2245 __ push(rax); 2237 __ push(rax);
2246 // Push Global receiver. 2238 // Push Global receiver.
2247 __ movq(rcx, GlobalObjectOperand()); 2239 __ movq(rcx, GlobalObjectOperand());
2248 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); 2240 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
2249 EmitCallWithStub(expr); 2241 EmitCallWithStub(expr);
2250 } else { 2242 } else {
2251 { PreservePositionScope scope(masm()->positions_recorder()); 2243 { PreservePositionScope scope(masm()->positions_recorder());
2252 VisitForStackValue(prop->obj()); 2244 VisitForStackValue(prop->obj());
2253 } 2245 }
(...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after
3593 for (int i = 0; i < arg_count; i++) { 3585 for (int i = 0; i < arg_count; i++) {
3594 VisitForStackValue(args->at(i)); 3586 VisitForStackValue(args->at(i));
3595 } 3587 }
3596 3588
3597 if (expr->is_jsruntime()) { 3589 if (expr->is_jsruntime()) {
3598 // Call the JS runtime function using a call IC. 3590 // Call the JS runtime function using a call IC.
3599 __ Move(rcx, expr->name()); 3591 __ Move(rcx, expr->name());
3600 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; 3592 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
3601 Handle<Code> ic = 3593 Handle<Code> ic =
3602 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop); 3594 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop);
3603 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 3595 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3604 // Restore context register. 3596 // Restore context register.
3605 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); 3597 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
3606 } else { 3598 } else {
3607 __ CallRuntime(expr->function(), arg_count); 3599 __ CallRuntime(expr->function(), arg_count);
3608 } 3600 }
3609 context()->Plug(rax); 3601 context()->Plug(rax);
3610 } 3602 }
3611 3603
3612 3604
3613 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 3605 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
3878 SetSourcePosition(expr->position()); 3870 SetSourcePosition(expr->position());
3879 3871
3880 // Call stub for +1/-1. 3872 // Call stub for +1/-1.
3881 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); 3873 TypeRecordingBinaryOpStub stub(expr->binary_op(), NO_OVERWRITE);
3882 if (expr->op() == Token::INC) { 3874 if (expr->op() == Token::INC) {
3883 __ Move(rdx, Smi::FromInt(1)); 3875 __ Move(rdx, Smi::FromInt(1));
3884 } else { 3876 } else {
3885 __ movq(rdx, rax); 3877 __ movq(rdx, rax);
3886 __ Move(rax, Smi::FromInt(1)); 3878 __ Move(rax, Smi::FromInt(1));
3887 } 3879 }
3888 EmitCallIC(stub.GetCode(), &patch_site, expr->CountId()); 3880 EmitCallIC(stub.GetCode(), &patch_site);
3889 __ bind(&done); 3881 __ bind(&done);
3890 3882
3891 // Store the value returned in rax. 3883 // Store the value returned in rax.
3892 switch (assign_type) { 3884 switch (assign_type) {
3893 case VARIABLE: 3885 case VARIABLE:
3894 if (expr->is_postfix()) { 3886 if (expr->is_postfix()) {
3895 // Perform the assignment as if via '='. 3887 // Perform the assignment as if via '='.
3896 { EffectContext context(this); 3888 { EffectContext context(this);
3897 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), 3889 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(),
3898 Token::ASSIGN); 3890 Token::ASSIGN);
(...skipping 12 matching lines...) Expand all
3911 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3903 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3912 context()->Plug(rax); 3904 context()->Plug(rax);
3913 } 3905 }
3914 break; 3906 break;
3915 case NAMED_PROPERTY: { 3907 case NAMED_PROPERTY: {
3916 __ Move(rcx, prop->key()->AsLiteral()->handle()); 3908 __ Move(rcx, prop->key()->AsLiteral()->handle());
3917 __ pop(rdx); 3909 __ pop(rdx);
3918 Handle<Code> ic = is_strict_mode() 3910 Handle<Code> ic = is_strict_mode()
3919 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3911 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3920 : isolate()->builtins()->StoreIC_Initialize(); 3912 : isolate()->builtins()->StoreIC_Initialize();
3921 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 3913 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3922 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3914 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3923 if (expr->is_postfix()) { 3915 if (expr->is_postfix()) {
3924 if (!context()->IsEffect()) { 3916 if (!context()->IsEffect()) {
3925 context()->PlugTOS(); 3917 context()->PlugTOS();
3926 } 3918 }
3927 } else { 3919 } else {
3928 context()->Plug(rax); 3920 context()->Plug(rax);
3929 } 3921 }
3930 break; 3922 break;
3931 } 3923 }
3932 case KEYED_PROPERTY: { 3924 case KEYED_PROPERTY: {
3933 __ pop(rcx); 3925 __ pop(rcx);
3934 __ pop(rdx); 3926 __ pop(rdx);
3935 Handle<Code> ic = is_strict_mode() 3927 Handle<Code> ic = is_strict_mode()
3936 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3928 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3937 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3929 : isolate()->builtins()->KeyedStoreIC_Initialize();
3938 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); 3930 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3939 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 3931 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
3940 if (expr->is_postfix()) { 3932 if (expr->is_postfix()) {
3941 if (!context()->IsEffect()) { 3933 if (!context()->IsEffect()) {
3942 context()->PlugTOS(); 3934 context()->PlugTOS();
3943 } 3935 }
3944 } else { 3936 } else {
3945 context()->Plug(rax); 3937 context()->Plug(rax);
3946 } 3938 }
3947 break; 3939 break;
3948 } 3940 }
3949 } 3941 }
3950 } 3942 }
3951 3943
3952 3944
3953 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { 3945 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
3954 VariableProxy* proxy = expr->AsVariableProxy(); 3946 VariableProxy* proxy = expr->AsVariableProxy();
3955 ASSERT(!context()->IsEffect()); 3947 ASSERT(!context()->IsEffect());
3956 ASSERT(!context()->IsTest()); 3948 ASSERT(!context()->IsTest());
3957 3949
3958 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { 3950 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) {
3959 Comment cmnt(masm_, "Global variable"); 3951 Comment cmnt(masm_, "Global variable");
3960 __ Move(rcx, proxy->name()); 3952 __ Move(rcx, proxy->name());
3961 __ movq(rax, GlobalObjectOperand()); 3953 __ movq(rax, GlobalObjectOperand());
3962 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 3954 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
3963 // Use a regular load, not a contextual load, to avoid a reference 3955 // Use a regular load, not a contextual load, to avoid a reference
3964 // error. 3956 // error.
3965 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 3957 EmitCallIC(ic, RelocInfo::CODE_TARGET);
3966 PrepareForBailout(expr, TOS_REG); 3958 PrepareForBailout(expr, TOS_REG);
3967 context()->Plug(rax); 3959 context()->Plug(rax);
3968 } else if (proxy != NULL && 3960 } else if (proxy != NULL &&
3969 proxy->var()->AsSlot() != NULL && 3961 proxy->var()->AsSlot() != NULL &&
3970 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { 3962 proxy->var()->AsSlot()->type() == Slot::LOOKUP) {
3971 Label done, slow; 3963 Label done, slow;
3972 3964
3973 // Generate code for loading from variables potentially shadowed 3965 // Generate code for loading from variables potentially shadowed
3974 // by eval-introduced variables. 3966 // by eval-introduced variables.
3975 Slot* slot = proxy->var()->AsSlot(); 3967 Slot* slot = proxy->var()->AsSlot();
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
4153 __ or_(rcx, rax); 4145 __ or_(rcx, rax);
4154 patch_site.EmitJumpIfNotSmi(rcx, &slow_case); 4146 patch_site.EmitJumpIfNotSmi(rcx, &slow_case);
4155 __ cmpq(rdx, rax); 4147 __ cmpq(rdx, rax);
4156 Split(cc, if_true, if_false, NULL); 4148 Split(cc, if_true, if_false, NULL);
4157 __ bind(&slow_case); 4149 __ bind(&slow_case);
4158 } 4150 }
4159 4151
4160 // Record position and call the compare IC. 4152 // Record position and call the compare IC.
4161 SetSourcePosition(expr->position()); 4153 SetSourcePosition(expr->position());
4162 Handle<Code> ic = CompareIC::GetUninitialized(op); 4154 Handle<Code> ic = CompareIC::GetUninitialized(op);
4163 EmitCallIC(ic, &patch_site, expr->id()); 4155 EmitCallIC(ic, &patch_site);
4164 4156
4165 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); 4157 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
4166 __ testq(rax, rax); 4158 __ testq(rax, rax);
4167 Split(cc, if_true, if_false, fall_through); 4159 Split(cc, if_true, if_false, fall_through);
4168 } 4160 }
4169 } 4161 }
4170 4162
4171 // Convert the result of the comparison into one expected for this 4163 // Convert the result of the comparison into one expected for this
4172 // expression's context. 4164 // expression's context.
4173 context()->Plug(if_true, if_false); 4165 context()->Plug(if_true, if_false);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4213 Register FullCodeGenerator::result_register() { 4205 Register FullCodeGenerator::result_register() {
4214 return rax; 4206 return rax;
4215 } 4207 }
4216 4208
4217 4209
4218 Register FullCodeGenerator::context_register() { 4210 Register FullCodeGenerator::context_register() {
4219 return rsi; 4211 return rsi;
4220 } 4212 }
4221 4213
4222 4214
4223 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, 4215 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) {
4224 RelocInfo::Mode mode,
4225 unsigned ast_id) {
4226 ASSERT(mode == RelocInfo::CODE_TARGET || 4216 ASSERT(mode == RelocInfo::CODE_TARGET ||
4227 mode == RelocInfo::CODE_TARGET_CONTEXT); 4217 mode == RelocInfo::CODE_TARGET_CONTEXT);
4228 Counters* counters = isolate()->counters(); 4218 Counters* counters = isolate()->counters();
4229 switch (ic->kind()) { 4219 switch (ic->kind()) {
4230 case Code::LOAD_IC: 4220 case Code::LOAD_IC:
4231 __ IncrementCounter(counters->named_load_full(), 1); 4221 __ IncrementCounter(counters->named_load_full(), 1);
4232 break; 4222 break;
4233 case Code::KEYED_LOAD_IC: 4223 case Code::KEYED_LOAD_IC:
4234 __ IncrementCounter(counters->keyed_load_full(), 1); 4224 __ IncrementCounter(counters->keyed_load_full(), 1);
4235 break; 4225 break;
4236 case Code::STORE_IC: 4226 case Code::STORE_IC:
4237 __ IncrementCounter(counters->named_store_full(), 1); 4227 __ IncrementCounter(counters->named_store_full(), 1);
4238 break; 4228 break;
4239 case Code::KEYED_STORE_IC: 4229 case Code::KEYED_STORE_IC:
4240 __ IncrementCounter(counters->keyed_store_full(), 1); 4230 __ IncrementCounter(counters->keyed_store_full(), 1);
4241 default: 4231 default:
4242 break; 4232 break;
4243 } 4233 }
4244 __ call(ic, mode, ast_id); 4234 __ call(ic, mode);
4245 } 4235 }
4246 4236
4247 4237
4248 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, 4238 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, JumpPatchSite* patch_site) {
4249 JumpPatchSite* patch_site,
4250 unsigned ast_id) {
4251 Counters* counters = isolate()->counters(); 4239 Counters* counters = isolate()->counters();
4252 switch (ic->kind()) { 4240 switch (ic->kind()) {
4253 case Code::LOAD_IC: 4241 case Code::LOAD_IC:
4254 __ IncrementCounter(counters->named_load_full(), 1); 4242 __ IncrementCounter(counters->named_load_full(), 1);
4255 break; 4243 break;
4256 case Code::KEYED_LOAD_IC: 4244 case Code::KEYED_LOAD_IC:
4257 __ IncrementCounter(counters->keyed_load_full(), 1); 4245 __ IncrementCounter(counters->keyed_load_full(), 1);
4258 break; 4246 break;
4259 case Code::STORE_IC: 4247 case Code::STORE_IC:
4260 __ IncrementCounter(counters->named_store_full(), 1); 4248 __ IncrementCounter(counters->named_store_full(), 1);
4261 break; 4249 break;
4262 case Code::KEYED_STORE_IC: 4250 case Code::KEYED_STORE_IC:
4263 __ IncrementCounter(counters->keyed_store_full(), 1); 4251 __ IncrementCounter(counters->keyed_store_full(), 1);
4264 default: 4252 default:
4265 break; 4253 break;
4266 } 4254 }
4267 __ call(ic, RelocInfo::CODE_TARGET, ast_id); 4255 __ call(ic, RelocInfo::CODE_TARGET);
4268 if (patch_site != NULL && patch_site->is_bound()) { 4256 if (patch_site != NULL && patch_site->is_bound()) {
4269 patch_site->EmitPatchInfo(); 4257 patch_site->EmitPatchInfo();
4270 } else { 4258 } else {
4271 __ nop(); // Signals no inlined code. 4259 __ nop(); // Signals no inlined code.
4272 } 4260 }
4273 } 4261 }
4274 4262
4275 4263
4276 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { 4264 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) {
4277 ASSERT(IsAligned(frame_offset, kPointerSize)); 4265 ASSERT(IsAligned(frame_offset, kPointerSize));
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
4317 __ ret(0); 4305 __ ret(0);
4318 } 4306 }
4319 4307
4320 4308
4321 #undef __ 4309 #undef __
4322 4310
4323 4311
4324 } } // namespace v8::internal 4312 } } // namespace v8::internal
4325 4313
4326 #endif // V8_TARGET_ARCH_X64 4314 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64-inl.h ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698