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 |