| OLD | NEW |
| 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 733 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 __ push(rax); | 744 __ push(rax); |
| 745 VisitForAccumulatorValue(function); | 745 VisitForAccumulatorValue(function); |
| 746 __ pop(rdx); | 746 __ pop(rdx); |
| 747 ASSERT(prop->key()->AsLiteral() != NULL && | 747 ASSERT(prop->key()->AsLiteral() != NULL && |
| 748 prop->key()->AsLiteral()->handle()->IsSmi()); | 748 prop->key()->AsLiteral()->handle()->IsSmi()); |
| 749 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 749 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 750 | 750 |
| 751 Handle<Code> ic = is_strict_mode() | 751 Handle<Code> ic = is_strict_mode() |
| 752 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 752 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 753 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 753 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 754 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 754 __ call(ic); |
| 755 } | 755 } |
| 756 } | 756 } |
| 757 } | 757 } |
| 758 | 758 |
| 759 | 759 |
| 760 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 760 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
| 761 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 761 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
| 762 } | 762 } |
| 763 | 763 |
| 764 | 764 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 __ cmpq(rdx, rax); | 817 __ cmpq(rdx, rax); |
| 818 __ j(not_equal, &next_test); | 818 __ j(not_equal, &next_test); |
| 819 __ Drop(1); // Switch value is no longer needed. | 819 __ Drop(1); // Switch value is no longer needed. |
| 820 __ jmp(clause->body_target()); | 820 __ jmp(clause->body_target()); |
| 821 __ bind(&slow_case); | 821 __ bind(&slow_case); |
| 822 } | 822 } |
| 823 | 823 |
| 824 // Record position before stub call for type feedback. | 824 // Record position before stub call for type feedback. |
| 825 SetSourcePosition(clause->position()); | 825 SetSourcePosition(clause->position()); |
| 826 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); | 826 Handle<Code> ic = CompareIC::GetUninitialized(Token::EQ_STRICT); |
| 827 EmitCallIC(ic, RelocInfo::CODE_TARGET, clause->CompareId()); | 827 __ call(ic, RelocInfo::CODE_TARGET, clause->CompareId()); |
| 828 patch_site.EmitPatchInfo(); | 828 patch_site.EmitPatchInfo(); |
| 829 | 829 |
| 830 __ testq(rax, rax); | 830 __ testq(rax, rax); |
| 831 __ j(not_equal, &next_test); | 831 __ j(not_equal, &next_test); |
| 832 __ Drop(1); // Switch value is no longer needed. | 832 __ Drop(1); // Switch value is no longer needed. |
| 833 __ jmp(clause->body_target()); | 833 __ jmp(clause->body_target()); |
| 834 } | 834 } |
| 835 | 835 |
| 836 // Discard the test value and jump to the default if present, otherwise to | 836 // Discard the test value and jump to the default if present, otherwise to |
| 837 // the end of the statement. | 837 // the end of the statement. |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 } | 1124 } |
| 1125 | 1125 |
| 1126 // All extension objects were empty and it is safe to use a global | 1126 // All extension objects were empty and it is safe to use a global |
| 1127 // load IC call. | 1127 // load IC call. |
| 1128 __ movq(rax, GlobalObjectOperand()); | 1128 __ movq(rax, GlobalObjectOperand()); |
| 1129 __ Move(rcx, slot->var()->name()); | 1129 __ Move(rcx, slot->var()->name()); |
| 1130 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1130 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1131 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1131 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1132 ? RelocInfo::CODE_TARGET | 1132 ? RelocInfo::CODE_TARGET |
| 1133 : RelocInfo::CODE_TARGET_CONTEXT; | 1133 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1134 EmitCallIC(ic, mode, AstNode::kNoNumber); | 1134 __ call(ic, mode); |
| 1135 } | 1135 } |
| 1136 | 1136 |
| 1137 | 1137 |
| 1138 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( | 1138 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions( |
| 1139 Slot* slot, | 1139 Slot* slot, |
| 1140 Label* slow) { | 1140 Label* slow) { |
| 1141 ASSERT(slot->type() == Slot::CONTEXT); | 1141 ASSERT(slot->type() == Slot::CONTEXT); |
| 1142 Register context = rsi; | 1142 Register context = rsi; |
| 1143 Register temp = rbx; | 1143 Register temp = rbx; |
| 1144 | 1144 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1204 key_literal->handle()->IsSmi()) { | 1204 key_literal->handle()->IsSmi()) { |
| 1205 // Load arguments object if there are no eval-introduced | 1205 // Load arguments object if there are no eval-introduced |
| 1206 // variables. Then load the argument from the arguments | 1206 // variables. Then load the argument from the arguments |
| 1207 // object using keyed load. | 1207 // object using keyed load. |
| 1208 __ movq(rdx, | 1208 __ movq(rdx, |
| 1209 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), | 1209 ContextSlotOperandCheckExtensions(obj_proxy->var()->AsSlot(), |
| 1210 slow)); | 1210 slow)); |
| 1211 __ Move(rax, key_literal->handle()); | 1211 __ Move(rax, key_literal->handle()); |
| 1212 Handle<Code> ic = | 1212 Handle<Code> ic = |
| 1213 isolate()->builtins()->KeyedLoadIC_Initialize(); | 1213 isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1214 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); | 1214 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); |
| 1215 __ jmp(done); | 1215 __ jmp(done); |
| 1216 } | 1216 } |
| 1217 } | 1217 } |
| 1218 } | 1218 } |
| 1219 } | 1219 } |
| 1220 } | 1220 } |
| 1221 | 1221 |
| 1222 | 1222 |
| 1223 void FullCodeGenerator::EmitVariableLoad(Variable* var) { | 1223 void FullCodeGenerator::EmitVariableLoad(Variable* var) { |
| 1224 // Three cases: non-this global variables, lookup slots, and all other | 1224 // Three cases: non-this global variables, lookup slots, and all other |
| 1225 // types of slots. | 1225 // types of slots. |
| 1226 Slot* slot = var->AsSlot(); | 1226 Slot* slot = var->AsSlot(); |
| 1227 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); | 1227 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL)); |
| 1228 | 1228 |
| 1229 if (slot == NULL) { | 1229 if (slot == NULL) { |
| 1230 Comment cmnt(masm_, "Global variable"); | 1230 Comment cmnt(masm_, "Global variable"); |
| 1231 // Use inline caching. Variable name is passed in rcx and the global | 1231 // Use inline caching. Variable name is passed in rcx and the global |
| 1232 // object on the stack. | 1232 // object on the stack. |
| 1233 __ Move(rcx, var->name()); | 1233 __ Move(rcx, var->name()); |
| 1234 __ movq(rax, GlobalObjectOperand()); | 1234 __ movq(rax, GlobalObjectOperand()); |
| 1235 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1235 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1236 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); | 1236 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1237 context()->Plug(rax); | 1237 context()->Plug(rax); |
| 1238 | 1238 |
| 1239 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1239 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1240 Label done, slow; | 1240 Label done, slow; |
| 1241 | 1241 |
| 1242 // Generate code for loading from variables potentially shadowed | 1242 // Generate code for loading from variables potentially shadowed |
| 1243 // by eval-introduced variables. | 1243 // by eval-introduced variables. |
| 1244 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); | 1244 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); |
| 1245 | 1245 |
| 1246 __ bind(&slow); | 1246 __ bind(&slow); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 // Fall through. | 1374 // Fall through. |
| 1375 case ObjectLiteral::Property::COMPUTED: | 1375 case ObjectLiteral::Property::COMPUTED: |
| 1376 if (key->handle()->IsSymbol()) { | 1376 if (key->handle()->IsSymbol()) { |
| 1377 if (property->emit_store()) { | 1377 if (property->emit_store()) { |
| 1378 VisitForAccumulatorValue(value); | 1378 VisitForAccumulatorValue(value); |
| 1379 __ Move(rcx, key->handle()); | 1379 __ Move(rcx, key->handle()); |
| 1380 __ movq(rdx, Operand(rsp, 0)); | 1380 __ movq(rdx, Operand(rsp, 0)); |
| 1381 Handle<Code> ic = is_strict_mode() | 1381 Handle<Code> ic = is_strict_mode() |
| 1382 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1382 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1383 : isolate()->builtins()->StoreIC_Initialize(); | 1383 : isolate()->builtins()->StoreIC_Initialize(); |
| 1384 EmitCallIC(ic, RelocInfo::CODE_TARGET, key->id()); | 1384 __ call(ic, RelocInfo::CODE_TARGET, key->id()); |
| 1385 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1385 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
| 1386 } else { | 1386 } else { |
| 1387 VisitForEffect(value); | 1387 VisitForEffect(value); |
| 1388 } | 1388 } |
| 1389 break; | 1389 break; |
| 1390 } | 1390 } |
| 1391 // Fall through. | 1391 // Fall through. |
| 1392 case ObjectLiteral::Property::PROTOTYPE: | 1392 case ObjectLiteral::Property::PROTOTYPE: |
| 1393 __ push(Operand(rsp, 0)); // Duplicate receiver. | 1393 __ push(Operand(rsp, 0)); // Duplicate receiver. |
| 1394 VisitForStackValue(key); | 1394 VisitForStackValue(key); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1603 break; | 1603 break; |
| 1604 } | 1604 } |
| 1605 } | 1605 } |
| 1606 | 1606 |
| 1607 | 1607 |
| 1608 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 1608 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 1609 SetSourcePosition(prop->position()); | 1609 SetSourcePosition(prop->position()); |
| 1610 Literal* key = prop->key()->AsLiteral(); | 1610 Literal* key = prop->key()->AsLiteral(); |
| 1611 __ Move(rcx, key->handle()); | 1611 __ Move(rcx, key->handle()); |
| 1612 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1612 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1613 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1613 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 1614 } | 1614 } |
| 1615 | 1615 |
| 1616 | 1616 |
| 1617 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 1617 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 1618 SetSourcePosition(prop->position()); | 1618 SetSourcePosition(prop->position()); |
| 1619 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 1619 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 1620 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 1620 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 1621 } | 1621 } |
| 1622 | 1622 |
| 1623 | 1623 |
| 1624 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1624 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 1625 Token::Value op, | 1625 Token::Value op, |
| 1626 OverwriteMode mode, | 1626 OverwriteMode mode, |
| 1627 Expression* left, | 1627 Expression* left, |
| 1628 Expression* right) { | 1628 Expression* right) { |
| 1629 // Do combined smi check of the operands. Left operand is on the | 1629 // Do combined smi check of the operands. Left operand is on the |
| 1630 // stack (popped into rdx). Right operand is in rax but moved into | 1630 // stack (popped into rdx). Right operand is in rax but moved into |
| 1631 // rcx to make the shifts easier. | 1631 // rcx to make the shifts easier. |
| 1632 Label done, stub_call, smi_case; | 1632 Label done, stub_call, smi_case; |
| 1633 __ pop(rdx); | 1633 __ pop(rdx); |
| 1634 __ movq(rcx, rax); | 1634 __ movq(rcx, rax); |
| 1635 __ or_(rax, rdx); | 1635 __ or_(rax, rdx); |
| 1636 JumpPatchSite patch_site(masm_); | 1636 JumpPatchSite patch_site(masm_); |
| 1637 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); | 1637 patch_site.EmitJumpIfSmi(rax, &smi_case, Label::kNear); |
| 1638 | 1638 |
| 1639 __ bind(&stub_call); | 1639 __ bind(&stub_call); |
| 1640 __ movq(rax, rcx); | 1640 __ movq(rax, rcx); |
| 1641 BinaryOpStub stub(op, mode); | 1641 BinaryOpStub stub(op, mode); |
| 1642 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1642 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 1643 patch_site.EmitPatchInfo(); | 1643 patch_site.EmitPatchInfo(); |
| 1644 __ jmp(&done, Label::kNear); | 1644 __ jmp(&done, Label::kNear); |
| 1645 | 1645 |
| 1646 __ bind(&smi_case); | 1646 __ bind(&smi_case); |
| 1647 switch (op) { | 1647 switch (op) { |
| 1648 case Token::SAR: | 1648 case Token::SAR: |
| 1649 __ SmiShiftArithmeticRight(rax, rdx, rcx); | 1649 __ SmiShiftArithmeticRight(rax, rdx, rcx); |
| 1650 break; | 1650 break; |
| 1651 case Token::SHL: | 1651 case Token::SHL: |
| 1652 __ SmiShiftLeft(rax, rdx, rcx); | 1652 __ SmiShiftLeft(rax, rdx, rcx); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1681 context()->Plug(rax); | 1681 context()->Plug(rax); |
| 1682 } | 1682 } |
| 1683 | 1683 |
| 1684 | 1684 |
| 1685 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, | 1685 void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, |
| 1686 Token::Value op, | 1686 Token::Value op, |
| 1687 OverwriteMode mode) { | 1687 OverwriteMode mode) { |
| 1688 __ pop(rdx); | 1688 __ pop(rdx); |
| 1689 BinaryOpStub stub(op, mode); | 1689 BinaryOpStub stub(op, mode); |
| 1690 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. | 1690 JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code. |
| 1691 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 1691 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 1692 patch_site.EmitPatchInfo(); | 1692 patch_site.EmitPatchInfo(); |
| 1693 context()->Plug(rax); | 1693 context()->Plug(rax); |
| 1694 } | 1694 } |
| 1695 | 1695 |
| 1696 | 1696 |
| 1697 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { | 1697 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { |
| 1698 // Invalid left-hand sides are rewritten to have a 'throw | 1698 // Invalid left-hand sides are rewritten to have a 'throw |
| 1699 // ReferenceError' on the left-hand side. | 1699 // ReferenceError' on the left-hand side. |
| 1700 if (!expr->IsValidLeftHandSide()) { | 1700 if (!expr->IsValidLeftHandSide()) { |
| 1701 VisitForEffect(expr); | 1701 VisitForEffect(expr); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1722 } | 1722 } |
| 1723 case NAMED_PROPERTY: { | 1723 case NAMED_PROPERTY: { |
| 1724 __ push(rax); // Preserve value. | 1724 __ push(rax); // Preserve value. |
| 1725 VisitForAccumulatorValue(prop->obj()); | 1725 VisitForAccumulatorValue(prop->obj()); |
| 1726 __ movq(rdx, rax); | 1726 __ movq(rdx, rax); |
| 1727 __ pop(rax); // Restore value. | 1727 __ pop(rax); // Restore value. |
| 1728 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1728 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1729 Handle<Code> ic = is_strict_mode() | 1729 Handle<Code> ic = is_strict_mode() |
| 1730 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1730 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1731 : isolate()->builtins()->StoreIC_Initialize(); | 1731 : isolate()->builtins()->StoreIC_Initialize(); |
| 1732 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1732 __ call(ic); |
| 1733 break; | 1733 break; |
| 1734 } | 1734 } |
| 1735 case KEYED_PROPERTY: { | 1735 case KEYED_PROPERTY: { |
| 1736 __ push(rax); // Preserve value. | 1736 __ push(rax); // Preserve value. |
| 1737 VisitForStackValue(prop->obj()); | 1737 VisitForStackValue(prop->obj()); |
| 1738 VisitForAccumulatorValue(prop->key()); | 1738 VisitForAccumulatorValue(prop->key()); |
| 1739 __ movq(rcx, rax); | 1739 __ movq(rcx, rax); |
| 1740 __ pop(rdx); | 1740 __ pop(rdx); |
| 1741 __ pop(rax); // Restore value. | 1741 __ pop(rax); // Restore value. |
| 1742 Handle<Code> ic = is_strict_mode() | 1742 Handle<Code> ic = is_strict_mode() |
| 1743 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1743 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 1744 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1744 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 1745 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 1745 __ call(ic); |
| 1746 break; | 1746 break; |
| 1747 } | 1747 } |
| 1748 } | 1748 } |
| 1749 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1749 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
| 1750 context()->Plug(rax); | 1750 context()->Plug(rax); |
| 1751 } | 1751 } |
| 1752 | 1752 |
| 1753 | 1753 |
| 1754 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1754 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
| 1755 Token::Value op) { | 1755 Token::Value op) { |
| 1756 ASSERT(var != NULL); | 1756 ASSERT(var != NULL); |
| 1757 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1757 ASSERT(var->is_global() || var->AsSlot() != NULL); |
| 1758 | 1758 |
| 1759 if (var->is_global()) { | 1759 if (var->is_global()) { |
| 1760 ASSERT(!var->is_this()); | 1760 ASSERT(!var->is_this()); |
| 1761 // Assignment to a global variable. Use inline caching for the | 1761 // Assignment to a global variable. Use inline caching for the |
| 1762 // assignment. Right-hand-side value is passed in rax, variable name in | 1762 // assignment. Right-hand-side value is passed in rax, variable name in |
| 1763 // rcx, and the global object on the stack. | 1763 // rcx, and the global object on the stack. |
| 1764 __ Move(rcx, var->name()); | 1764 __ Move(rcx, var->name()); |
| 1765 __ movq(rdx, GlobalObjectOperand()); | 1765 __ movq(rdx, GlobalObjectOperand()); |
| 1766 Handle<Code> ic = is_strict_mode() | 1766 Handle<Code> ic = is_strict_mode() |
| 1767 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1767 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1768 : isolate()->builtins()->StoreIC_Initialize(); | 1768 : isolate()->builtins()->StoreIC_Initialize(); |
| 1769 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); | 1769 __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1770 | 1770 |
| 1771 } else if (op == Token::INIT_CONST) { | 1771 } else if (op == Token::INIT_CONST) { |
| 1772 // Like var declarations, const declarations are hoisted to function | 1772 // Like var declarations, const declarations are hoisted to function |
| 1773 // scope. However, unlike var initializers, const initializers are able | 1773 // scope. However, unlike var initializers, const initializers are able |
| 1774 // to drill a hole to that function context, even from inside a 'with' | 1774 // to drill a hole to that function context, even from inside a 'with' |
| 1775 // context. We thus bypass the normal static scope lookup. | 1775 // context. We thus bypass the normal static scope lookup. |
| 1776 Slot* slot = var->AsSlot(); | 1776 Slot* slot = var->AsSlot(); |
| 1777 Label skip; | 1777 Label skip; |
| 1778 switch (slot->type()) { | 1778 switch (slot->type()) { |
| 1779 case Slot::PARAMETER: | 1779 case Slot::PARAMETER: |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1852 SetSourcePosition(expr->position()); | 1852 SetSourcePosition(expr->position()); |
| 1853 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1853 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1854 if (expr->ends_initialization_block()) { | 1854 if (expr->ends_initialization_block()) { |
| 1855 __ movq(rdx, Operand(rsp, 0)); | 1855 __ movq(rdx, Operand(rsp, 0)); |
| 1856 } else { | 1856 } else { |
| 1857 __ pop(rdx); | 1857 __ pop(rdx); |
| 1858 } | 1858 } |
| 1859 Handle<Code> ic = is_strict_mode() | 1859 Handle<Code> ic = is_strict_mode() |
| 1860 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 1860 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 1861 : isolate()->builtins()->StoreIC_Initialize(); | 1861 : isolate()->builtins()->StoreIC_Initialize(); |
| 1862 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 1862 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 1863 | 1863 |
| 1864 // If the assignment ends an initialization block, revert to fast case. | 1864 // If the assignment ends an initialization block, revert to fast case. |
| 1865 if (expr->ends_initialization_block()) { | 1865 if (expr->ends_initialization_block()) { |
| 1866 __ push(rax); // Result of assignment, saved even if not needed. | 1866 __ push(rax); // Result of assignment, saved even if not needed. |
| 1867 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. | 1867 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
| 1868 __ CallRuntime(Runtime::kToFastProperties, 1); | 1868 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1869 __ pop(rax); | 1869 __ pop(rax); |
| 1870 __ Drop(1); | 1870 __ Drop(1); |
| 1871 } | 1871 } |
| 1872 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 1872 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1892 if (expr->ends_initialization_block()) { | 1892 if (expr->ends_initialization_block()) { |
| 1893 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. | 1893 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. |
| 1894 } else { | 1894 } else { |
| 1895 __ pop(rdx); | 1895 __ pop(rdx); |
| 1896 } | 1896 } |
| 1897 // Record source code position before IC call. | 1897 // Record source code position before IC call. |
| 1898 SetSourcePosition(expr->position()); | 1898 SetSourcePosition(expr->position()); |
| 1899 Handle<Code> ic = is_strict_mode() | 1899 Handle<Code> ic = is_strict_mode() |
| 1900 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 1900 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 1901 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 1901 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 1902 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 1902 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 1903 | 1903 |
| 1904 // If the assignment ends an initialization block, revert to fast case. | 1904 // If the assignment ends an initialization block, revert to fast case. |
| 1905 if (expr->ends_initialization_block()) { | 1905 if (expr->ends_initialization_block()) { |
| 1906 __ pop(rdx); | 1906 __ pop(rdx); |
| 1907 __ push(rax); // Result of assignment, saved even if not needed. | 1907 __ push(rax); // Result of assignment, saved even if not needed. |
| 1908 __ push(rdx); | 1908 __ push(rdx); |
| 1909 __ CallRuntime(Runtime::kToFastProperties, 1); | 1909 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1910 __ pop(rax); | 1910 __ pop(rax); |
| 1911 } | 1911 } |
| 1912 | 1912 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1944 VisitForStackValue(args->at(i)); | 1944 VisitForStackValue(args->at(i)); |
| 1945 } | 1945 } |
| 1946 __ Move(rcx, name); | 1946 __ Move(rcx, name); |
| 1947 } | 1947 } |
| 1948 // Record source position for debugger. | 1948 // Record source position for debugger. |
| 1949 SetSourcePosition(expr->position()); | 1949 SetSourcePosition(expr->position()); |
| 1950 // Call the IC initialization code. | 1950 // Call the IC initialization code. |
| 1951 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1951 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1952 Handle<Code> ic = | 1952 Handle<Code> ic = |
| 1953 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); | 1953 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); |
| 1954 EmitCallIC(ic, mode, expr->id()); | 1954 __ call(ic, mode, expr->id()); |
| 1955 RecordJSReturnSite(expr); | 1955 RecordJSReturnSite(expr); |
| 1956 // Restore context register. | 1956 // Restore context register. |
| 1957 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1957 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 1958 context()->Plug(rax); | 1958 context()->Plug(rax); |
| 1959 } | 1959 } |
| 1960 | 1960 |
| 1961 | 1961 |
| 1962 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, | 1962 void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr, |
| 1963 Expression* key) { | 1963 Expression* key) { |
| 1964 // Load the key. | 1964 // Load the key. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1978 VisitForStackValue(args->at(i)); | 1978 VisitForStackValue(args->at(i)); |
| 1979 } | 1979 } |
| 1980 } | 1980 } |
| 1981 // Record source position for debugger. | 1981 // Record source position for debugger. |
| 1982 SetSourcePosition(expr->position()); | 1982 SetSourcePosition(expr->position()); |
| 1983 // Call the IC initialization code. | 1983 // Call the IC initialization code. |
| 1984 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 1984 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 1985 Handle<Code> ic = | 1985 Handle<Code> ic = |
| 1986 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); | 1986 ISOLATE->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); |
| 1987 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. | 1987 __ movq(rcx, Operand(rsp, (arg_count + 1) * kPointerSize)); // Key. |
| 1988 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 1988 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 1989 RecordJSReturnSite(expr); | 1989 RecordJSReturnSite(expr); |
| 1990 // Restore context register. | 1990 // Restore context register. |
| 1991 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 1991 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 1992 context()->DropAndPlug(1, rax); // Drop the key still on the stack. | 1992 context()->DropAndPlug(1, rax); // Drop the key still on the stack. |
| 1993 } | 1993 } |
| 1994 | 1994 |
| 1995 | 1995 |
| 1996 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { | 1996 void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) { |
| 1997 // Code common for calls using the call stub. | 1997 // Code common for calls using the call stub. |
| 1998 ZoneList<Expression*>* args = expr->arguments(); | 1998 ZoneList<Expression*>* args = expr->arguments(); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2155 Literal* key = prop->key()->AsLiteral(); | 2155 Literal* key = prop->key()->AsLiteral(); |
| 2156 if (key != NULL && key->handle()->IsSymbol()) { | 2156 if (key != NULL && key->handle()->IsSymbol()) { |
| 2157 // Call to a named property, use call IC. | 2157 // Call to a named property, use call IC. |
| 2158 { PreservePositionScope scope(masm()->positions_recorder()); | 2158 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2159 VisitForStackValue(prop->obj()); | 2159 VisitForStackValue(prop->obj()); |
| 2160 } | 2160 } |
| 2161 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); | 2161 EmitCallWithIC(expr, key->handle(), RelocInfo::CODE_TARGET); |
| 2162 } else { | 2162 } else { |
| 2163 // Call to a keyed property. | 2163 // Call to a keyed property. |
| 2164 // For a synthetic property use keyed load IC followed by function call, | 2164 // For a synthetic property use keyed load IC followed by function call, |
| 2165 // for a regular property use keyed EmitCallIC. | 2165 // for a regular property use EmitKeyedCallWithIC. |
| 2166 if (prop->is_synthetic()) { | 2166 if (prop->is_synthetic()) { |
| 2167 // Do not visit the object and key subexpressions (they are shared | 2167 // Do not visit the object and key subexpressions (they are shared |
| 2168 // by all occurrences of the same rewritten parameter). | 2168 // by all occurrences of the same rewritten parameter). |
| 2169 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 2169 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
| 2170 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); | 2170 ASSERT(prop->obj()->AsVariableProxy()->var()->AsSlot() != NULL); |
| 2171 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); | 2171 Slot* slot = prop->obj()->AsVariableProxy()->var()->AsSlot(); |
| 2172 MemOperand operand = EmitSlotSearch(slot, rdx); | 2172 MemOperand operand = EmitSlotSearch(slot, rdx); |
| 2173 __ movq(rdx, operand); | 2173 __ movq(rdx, operand); |
| 2174 | 2174 |
| 2175 ASSERT(prop->key()->AsLiteral() != NULL); | 2175 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2176 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); | 2176 ASSERT(prop->key()->AsLiteral()->handle()->IsSmi()); |
| 2177 __ Move(rax, prop->key()->AsLiteral()->handle()); | 2177 __ Move(rax, prop->key()->AsLiteral()->handle()); |
| 2178 | 2178 |
| 2179 // Record source code position for IC call. | 2179 // Record source code position for IC call. |
| 2180 SetSourcePosition(prop->position()); | 2180 SetSourcePosition(prop->position()); |
| 2181 | 2181 |
| 2182 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); | 2182 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); |
| 2183 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); | 2183 __ call(ic, RelocInfo::CODE_TARGET, GetPropertyId(prop)); |
| 2184 // Push result (function). | 2184 // Push result (function). |
| 2185 __ push(rax); | 2185 __ push(rax); |
| 2186 // Push Global receiver. | 2186 // Push Global receiver. |
| 2187 __ movq(rcx, GlobalObjectOperand()); | 2187 __ movq(rcx, GlobalObjectOperand()); |
| 2188 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); | 2188 __ push(FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset)); |
| 2189 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); | 2189 EmitCallWithStub(expr, NO_CALL_FUNCTION_FLAGS); |
| 2190 } else { | 2190 } else { |
| 2191 { PreservePositionScope scope(masm()->positions_recorder()); | 2191 { PreservePositionScope scope(masm()->positions_recorder()); |
| 2192 VisitForStackValue(prop->obj()); | 2192 VisitForStackValue(prop->obj()); |
| 2193 } | 2193 } |
| (...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3535 VisitForStackValue(args->at(i)); | 3535 VisitForStackValue(args->at(i)); |
| 3536 } | 3536 } |
| 3537 | 3537 |
| 3538 if (expr->is_jsruntime()) { | 3538 if (expr->is_jsruntime()) { |
| 3539 // Call the JS runtime function using a call IC. | 3539 // Call the JS runtime function using a call IC. |
| 3540 __ Move(rcx, expr->name()); | 3540 __ Move(rcx, expr->name()); |
| 3541 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 3541 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
| 3542 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; | 3542 RelocInfo::Mode mode = RelocInfo::CODE_TARGET; |
| 3543 Handle<Code> ic = | 3543 Handle<Code> ic = |
| 3544 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); | 3544 ISOLATE->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); |
| 3545 EmitCallIC(ic, mode, expr->id()); | 3545 __ call(ic, mode, expr->id()); |
| 3546 // Restore context register. | 3546 // Restore context register. |
| 3547 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); | 3547 __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
| 3548 } else { | 3548 } else { |
| 3549 __ CallRuntime(expr->function(), arg_count); | 3549 __ CallRuntime(expr->function(), arg_count); |
| 3550 } | 3550 } |
| 3551 context()->Plug(rax); | 3551 context()->Plug(rax); |
| 3552 } | 3552 } |
| 3553 | 3553 |
| 3554 | 3554 |
| 3555 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 3555 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3672 // TODO(svenpanne): Allowing format strings in Comment would be nice here... | 3672 // TODO(svenpanne): Allowing format strings in Comment would be nice here... |
| 3673 Comment cmt(masm_, comment); | 3673 Comment cmt(masm_, comment); |
| 3674 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); | 3674 bool can_overwrite = expr->expression()->ResultOverwriteAllowed(); |
| 3675 UnaryOverwriteMode overwrite = | 3675 UnaryOverwriteMode overwrite = |
| 3676 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; | 3676 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE; |
| 3677 UnaryOpStub stub(expr->op(), overwrite); | 3677 UnaryOpStub stub(expr->op(), overwrite); |
| 3678 // UnaryOpStub expects the argument to be in the | 3678 // UnaryOpStub expects the argument to be in the |
| 3679 // accumulator register rax. | 3679 // accumulator register rax. |
| 3680 VisitForAccumulatorValue(expr->expression()); | 3680 VisitForAccumulatorValue(expr->expression()); |
| 3681 SetSourcePosition(expr->position()); | 3681 SetSourcePosition(expr->position()); |
| 3682 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); | 3682 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->id()); |
| 3683 context()->Plug(rax); | 3683 context()->Plug(rax); |
| 3684 } | 3684 } |
| 3685 | 3685 |
| 3686 | 3686 |
| 3687 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 3687 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 3688 Comment cmnt(masm_, "[ CountOperation"); | 3688 Comment cmnt(masm_, "[ CountOperation"); |
| 3689 SetSourcePosition(expr->position()); | 3689 SetSourcePosition(expr->position()); |
| 3690 | 3690 |
| 3691 // Invalid left-hand-sides are rewritten to have a 'throw | 3691 // Invalid left-hand-sides are rewritten to have a 'throw |
| 3692 // ReferenceError' as the left-hand side. | 3692 // ReferenceError' as the left-hand side. |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3793 SetSourcePosition(expr->position()); | 3793 SetSourcePosition(expr->position()); |
| 3794 | 3794 |
| 3795 // Call stub for +1/-1. | 3795 // Call stub for +1/-1. |
| 3796 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); | 3796 BinaryOpStub stub(expr->binary_op(), NO_OVERWRITE); |
| 3797 if (expr->op() == Token::INC) { | 3797 if (expr->op() == Token::INC) { |
| 3798 __ Move(rdx, Smi::FromInt(1)); | 3798 __ Move(rdx, Smi::FromInt(1)); |
| 3799 } else { | 3799 } else { |
| 3800 __ movq(rdx, rax); | 3800 __ movq(rdx, rax); |
| 3801 __ Move(rax, Smi::FromInt(1)); | 3801 __ Move(rax, Smi::FromInt(1)); |
| 3802 } | 3802 } |
| 3803 EmitCallIC(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); | 3803 __ call(stub.GetCode(), RelocInfo::CODE_TARGET, expr->CountId()); |
| 3804 patch_site.EmitPatchInfo(); | 3804 patch_site.EmitPatchInfo(); |
| 3805 __ bind(&done); | 3805 __ bind(&done); |
| 3806 | 3806 |
| 3807 // Store the value returned in rax. | 3807 // Store the value returned in rax. |
| 3808 switch (assign_type) { | 3808 switch (assign_type) { |
| 3809 case VARIABLE: | 3809 case VARIABLE: |
| 3810 if (expr->is_postfix()) { | 3810 if (expr->is_postfix()) { |
| 3811 // Perform the assignment as if via '='. | 3811 // Perform the assignment as if via '='. |
| 3812 { EffectContext context(this); | 3812 { EffectContext context(this); |
| 3813 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3813 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3827 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3827 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3828 context()->Plug(rax); | 3828 context()->Plug(rax); |
| 3829 } | 3829 } |
| 3830 break; | 3830 break; |
| 3831 case NAMED_PROPERTY: { | 3831 case NAMED_PROPERTY: { |
| 3832 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 3832 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 3833 __ pop(rdx); | 3833 __ pop(rdx); |
| 3834 Handle<Code> ic = is_strict_mode() | 3834 Handle<Code> ic = is_strict_mode() |
| 3835 ? isolate()->builtins()->StoreIC_Initialize_Strict() | 3835 ? isolate()->builtins()->StoreIC_Initialize_Strict() |
| 3836 : isolate()->builtins()->StoreIC_Initialize(); | 3836 : isolate()->builtins()->StoreIC_Initialize(); |
| 3837 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3837 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 3838 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3838 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3839 if (expr->is_postfix()) { | 3839 if (expr->is_postfix()) { |
| 3840 if (!context()->IsEffect()) { | 3840 if (!context()->IsEffect()) { |
| 3841 context()->PlugTOS(); | 3841 context()->PlugTOS(); |
| 3842 } | 3842 } |
| 3843 } else { | 3843 } else { |
| 3844 context()->Plug(rax); | 3844 context()->Plug(rax); |
| 3845 } | 3845 } |
| 3846 break; | 3846 break; |
| 3847 } | 3847 } |
| 3848 case KEYED_PROPERTY: { | 3848 case KEYED_PROPERTY: { |
| 3849 __ pop(rcx); | 3849 __ pop(rcx); |
| 3850 __ pop(rdx); | 3850 __ pop(rdx); |
| 3851 Handle<Code> ic = is_strict_mode() | 3851 Handle<Code> ic = is_strict_mode() |
| 3852 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() | 3852 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() |
| 3853 : isolate()->builtins()->KeyedStoreIC_Initialize(); | 3853 : isolate()->builtins()->KeyedStoreIC_Initialize(); |
| 3854 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 3854 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 3855 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3855 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 3856 if (expr->is_postfix()) { | 3856 if (expr->is_postfix()) { |
| 3857 if (!context()->IsEffect()) { | 3857 if (!context()->IsEffect()) { |
| 3858 context()->PlugTOS(); | 3858 context()->PlugTOS(); |
| 3859 } | 3859 } |
| 3860 } else { | 3860 } else { |
| 3861 context()->Plug(rax); | 3861 context()->Plug(rax); |
| 3862 } | 3862 } |
| 3863 break; | 3863 break; |
| 3864 } | 3864 } |
| 3865 } | 3865 } |
| 3866 } | 3866 } |
| 3867 | 3867 |
| 3868 | 3868 |
| 3869 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 3869 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 3870 VariableProxy* proxy = expr->AsVariableProxy(); | 3870 VariableProxy* proxy = expr->AsVariableProxy(); |
| 3871 ASSERT(!context()->IsEffect()); | 3871 ASSERT(!context()->IsEffect()); |
| 3872 ASSERT(!context()->IsTest()); | 3872 ASSERT(!context()->IsTest()); |
| 3873 | 3873 |
| 3874 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { | 3874 if (proxy != NULL && !proxy->var()->is_this() && proxy->var()->is_global()) { |
| 3875 Comment cmnt(masm_, "Global variable"); | 3875 Comment cmnt(masm_, "Global variable"); |
| 3876 __ Move(rcx, proxy->name()); | 3876 __ Move(rcx, proxy->name()); |
| 3877 __ movq(rax, GlobalObjectOperand()); | 3877 __ movq(rax, GlobalObjectOperand()); |
| 3878 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 3878 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 3879 // Use a regular load, not a contextual load, to avoid a reference | 3879 // Use a regular load, not a contextual load, to avoid a reference |
| 3880 // error. | 3880 // error. |
| 3881 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); | 3881 __ call(ic); |
| 3882 PrepareForBailout(expr, TOS_REG); | 3882 PrepareForBailout(expr, TOS_REG); |
| 3883 context()->Plug(rax); | 3883 context()->Plug(rax); |
| 3884 } else if (proxy != NULL && | 3884 } else if (proxy != NULL && |
| 3885 proxy->var()->AsSlot() != NULL && | 3885 proxy->var()->AsSlot() != NULL && |
| 3886 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { | 3886 proxy->var()->AsSlot()->type() == Slot::LOOKUP) { |
| 3887 Label done, slow; | 3887 Label done, slow; |
| 3888 | 3888 |
| 3889 // Generate code for loading from variables potentially shadowed | 3889 // Generate code for loading from variables potentially shadowed |
| 3890 // by eval-introduced variables. | 3890 // by eval-introduced variables. |
| 3891 Slot* slot = proxy->var()->AsSlot(); | 3891 Slot* slot = proxy->var()->AsSlot(); |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4066 __ or_(rcx, rax); | 4066 __ or_(rcx, rax); |
| 4067 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); | 4067 patch_site.EmitJumpIfNotSmi(rcx, &slow_case, Label::kNear); |
| 4068 __ cmpq(rdx, rax); | 4068 __ cmpq(rdx, rax); |
| 4069 Split(cc, if_true, if_false, NULL); | 4069 Split(cc, if_true, if_false, NULL); |
| 4070 __ bind(&slow_case); | 4070 __ bind(&slow_case); |
| 4071 } | 4071 } |
| 4072 | 4072 |
| 4073 // Record position and call the compare IC. | 4073 // Record position and call the compare IC. |
| 4074 SetSourcePosition(expr->position()); | 4074 SetSourcePosition(expr->position()); |
| 4075 Handle<Code> ic = CompareIC::GetUninitialized(op); | 4075 Handle<Code> ic = CompareIC::GetUninitialized(op); |
| 4076 EmitCallIC(ic, RelocInfo::CODE_TARGET, expr->id()); | 4076 __ call(ic, RelocInfo::CODE_TARGET, expr->id()); |
| 4077 patch_site.EmitPatchInfo(); | 4077 patch_site.EmitPatchInfo(); |
| 4078 | 4078 |
| 4079 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); | 4079 PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); |
| 4080 __ testq(rax, rax); | 4080 __ testq(rax, rax); |
| 4081 Split(cc, if_true, if_false, fall_through); | 4081 Split(cc, if_true, if_false, fall_through); |
| 4082 } | 4082 } |
| 4083 } | 4083 } |
| 4084 | 4084 |
| 4085 // Convert the result of the comparison into one expected for this | 4085 // Convert the result of the comparison into one expected for this |
| 4086 // expression's context. | 4086 // expression's context. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4126 Register FullCodeGenerator::result_register() { | 4126 Register FullCodeGenerator::result_register() { |
| 4127 return rax; | 4127 return rax; |
| 4128 } | 4128 } |
| 4129 | 4129 |
| 4130 | 4130 |
| 4131 Register FullCodeGenerator::context_register() { | 4131 Register FullCodeGenerator::context_register() { |
| 4132 return rsi; | 4132 return rsi; |
| 4133 } | 4133 } |
| 4134 | 4134 |
| 4135 | 4135 |
| 4136 void FullCodeGenerator::EmitCallIC(Handle<Code> ic, | |
| 4137 RelocInfo::Mode mode, | |
| 4138 unsigned ast_id) { | |
| 4139 ASSERT(mode == RelocInfo::CODE_TARGET || | |
| 4140 mode == RelocInfo::CODE_TARGET_CONTEXT); | |
| 4141 __ call(ic, mode, ast_id); | |
| 4142 } | |
| 4143 | |
| 4144 | |
| 4145 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { | 4136 void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
| 4146 ASSERT(IsAligned(frame_offset, kPointerSize)); | 4137 ASSERT(IsAligned(frame_offset, kPointerSize)); |
| 4147 __ movq(Operand(rbp, frame_offset), value); | 4138 __ movq(Operand(rbp, frame_offset), value); |
| 4148 } | 4139 } |
| 4149 | 4140 |
| 4150 | 4141 |
| 4151 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { | 4142 void FullCodeGenerator::LoadContextField(Register dst, int context_index) { |
| 4152 __ movq(dst, ContextOperand(rsi, context_index)); | 4143 __ movq(dst, ContextOperand(rsi, context_index)); |
| 4153 } | 4144 } |
| 4154 | 4145 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4205 __ ret(0); | 4196 __ ret(0); |
| 4206 } | 4197 } |
| 4207 | 4198 |
| 4208 | 4199 |
| 4209 #undef __ | 4200 #undef __ |
| 4210 | 4201 |
| 4211 | 4202 |
| 4212 } } // namespace v8::internal | 4203 } } // namespace v8::internal |
| 4213 | 4204 |
| 4214 #endif // V8_TARGET_ARCH_X64 | 4205 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |