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 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 VisitForAccumulatorValue(function); | 731 VisitForAccumulatorValue(function); |
732 __ pop(rdx); | 732 __ pop(rdx); |
733 } else { | 733 } else { |
734 __ movq(rdx, rax); | 734 __ movq(rdx, rax); |
735 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); | 735 __ LoadRoot(rax, Heap::kTheHoleValueRootIndex); |
736 } | 736 } |
737 ASSERT(prop->key()->AsLiteral() != NULL && | 737 ASSERT(prop->key()->AsLiteral() != NULL && |
738 prop->key()->AsLiteral()->handle()->IsSmi()); | 738 prop->key()->AsLiteral()->handle()->IsSmi()); |
739 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 739 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
740 | 740 |
741 Handle<Code> ic(Builtins::builtin(is_strict() | 741 Handle<Code> ic(Builtins::builtin( |
742 ? Builtins::KeyedStoreIC_Initialize_Strict | 742 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
743 : Builtins::KeyedStoreIC_Initialize)); | 743 : Builtins::KeyedStoreIC_Initialize)); |
744 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 744 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
745 } | 745 } |
746 } | 746 } |
747 } | 747 } |
748 | 748 |
749 | 749 |
750 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 750 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
751 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 751 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
752 } | 752 } |
753 | 753 |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1736 EmitVariableAssignment(var, Token::ASSIGN); | 1736 EmitVariableAssignment(var, Token::ASSIGN); |
1737 break; | 1737 break; |
1738 } | 1738 } |
1739 case NAMED_PROPERTY: { | 1739 case NAMED_PROPERTY: { |
1740 __ push(rax); // Preserve value. | 1740 __ push(rax); // Preserve value. |
1741 VisitForAccumulatorValue(prop->obj()); | 1741 VisitForAccumulatorValue(prop->obj()); |
1742 __ movq(rdx, rax); | 1742 __ movq(rdx, rax); |
1743 __ pop(rax); // Restore value. | 1743 __ pop(rax); // Restore value. |
1744 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1744 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
1745 Handle<Code> ic(Builtins::builtin( | 1745 Handle<Code> ic(Builtins::builtin( |
1746 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1746 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
1747 : Builtins::StoreIC_Initialize)); | 1747 : Builtins::StoreIC_Initialize)); |
1748 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1748 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1749 break; | 1749 break; |
1750 } | 1750 } |
1751 case KEYED_PROPERTY: { | 1751 case KEYED_PROPERTY: { |
1752 __ push(rax); // Preserve value. | 1752 __ push(rax); // Preserve value. |
1753 if (prop->is_synthetic()) { | 1753 if (prop->is_synthetic()) { |
1754 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 1754 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
1755 ASSERT(prop->key()->AsLiteral() != NULL); | 1755 ASSERT(prop->key()->AsLiteral() != NULL); |
1756 { AccumulatorValueContext for_object(this); | 1756 { AccumulatorValueContext for_object(this); |
1757 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 1757 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
1758 } | 1758 } |
1759 __ movq(rdx, rax); | 1759 __ movq(rdx, rax); |
1760 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1760 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
1761 } else { | 1761 } else { |
1762 VisitForStackValue(prop->obj()); | 1762 VisitForStackValue(prop->obj()); |
1763 VisitForAccumulatorValue(prop->key()); | 1763 VisitForAccumulatorValue(prop->key()); |
1764 __ movq(rcx, rax); | 1764 __ movq(rcx, rax); |
1765 __ pop(rdx); | 1765 __ pop(rdx); |
1766 } | 1766 } |
1767 __ pop(rax); // Restore value. | 1767 __ pop(rax); // Restore value. |
1768 Handle<Code> ic(Builtins::builtin( | 1768 Handle<Code> ic(Builtins::builtin( |
1769 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 1769 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
1770 : Builtins::KeyedStoreIC_Initialize)); | 1770 : Builtins::KeyedStoreIC_Initialize)); |
1771 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1771 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1772 break; | 1772 break; |
1773 } | 1773 } |
1774 } | 1774 } |
1775 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 1775 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
1776 context()->Plug(rax); | 1776 context()->Plug(rax); |
1777 } | 1777 } |
1778 | 1778 |
1779 | 1779 |
1780 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 1780 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
1781 Token::Value op) { | 1781 Token::Value op) { |
1782 // Left-hand sides that rewrite to explicit property accesses do not reach | 1782 // Left-hand sides that rewrite to explicit property accesses do not reach |
1783 // here. | 1783 // here. |
1784 ASSERT(var != NULL); | 1784 ASSERT(var != NULL); |
1785 ASSERT(var->is_global() || var->AsSlot() != NULL); | 1785 ASSERT(var->is_global() || var->AsSlot() != NULL); |
1786 | 1786 |
1787 if (var->is_global()) { | 1787 if (var->is_global()) { |
1788 ASSERT(!var->is_this()); | 1788 ASSERT(!var->is_this()); |
1789 // Assignment to a global variable. Use inline caching for the | 1789 // Assignment to a global variable. Use inline caching for the |
1790 // assignment. Right-hand-side value is passed in rax, variable name in | 1790 // assignment. Right-hand-side value is passed in rax, variable name in |
1791 // rcx, and the global object on the stack. | 1791 // rcx, and the global object on the stack. |
1792 __ Move(rcx, var->name()); | 1792 __ Move(rcx, var->name()); |
1793 __ movq(rdx, GlobalObjectOperand()); | 1793 __ movq(rdx, GlobalObjectOperand()); |
1794 Handle<Code> ic(Builtins::builtin(is_strict() | 1794 Handle<Code> ic(Builtins::builtin( |
1795 ? Builtins::StoreIC_Initialize_Strict | 1795 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
1796 : Builtins::StoreIC_Initialize)); | 1796 : Builtins::StoreIC_Initialize)); |
1797 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1797 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
1798 | 1798 |
1799 } else if (op == Token::INIT_CONST) { | 1799 } else if (op == Token::INIT_CONST) { |
1800 // Like var declarations, const declarations are hoisted to function | 1800 // Like var declarations, const declarations are hoisted to function |
1801 // scope. However, unlike var initializers, const initializers are able | 1801 // scope. However, unlike var initializers, const initializers are able |
1802 // to drill a hole to that function context, even from inside a 'with' | 1802 // to drill a hole to that function context, even from inside a 'with' |
1803 // context. We thus bypass the normal static scope lookup. | 1803 // context. We thus bypass the normal static scope lookup. |
1804 Slot* slot = var->AsSlot(); | 1804 Slot* slot = var->AsSlot(); |
1805 Label skip; | 1805 Label skip; |
1806 switch (slot->type()) { | 1806 switch (slot->type()) { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1888 | 1888 |
1889 // Record source code position before IC call. | 1889 // Record source code position before IC call. |
1890 SetSourcePosition(expr->position()); | 1890 SetSourcePosition(expr->position()); |
1891 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1891 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
1892 if (expr->ends_initialization_block()) { | 1892 if (expr->ends_initialization_block()) { |
1893 __ movq(rdx, Operand(rsp, 0)); | 1893 __ movq(rdx, Operand(rsp, 0)); |
1894 } else { | 1894 } else { |
1895 __ pop(rdx); | 1895 __ pop(rdx); |
1896 } | 1896 } |
1897 Handle<Code> ic(Builtins::builtin( | 1897 Handle<Code> ic(Builtins::builtin( |
1898 is_strict() ? Builtins::StoreIC_Initialize_Strict | 1898 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
1899 : Builtins::StoreIC_Initialize)); | 1899 : Builtins::StoreIC_Initialize)); |
1900 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1900 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1901 | 1901 |
1902 // If the assignment ends an initialization block, revert to fast case. | 1902 // If the assignment ends an initialization block, revert to fast case. |
1903 if (expr->ends_initialization_block()) { | 1903 if (expr->ends_initialization_block()) { |
1904 __ push(rax); // Result of assignment, saved even if not needed. | 1904 __ push(rax); // Result of assignment, saved even if not needed. |
1905 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. | 1905 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
1906 __ CallRuntime(Runtime::kToFastProperties, 1); | 1906 __ CallRuntime(Runtime::kToFastProperties, 1); |
1907 __ pop(rax); | 1907 __ pop(rax); |
1908 __ Drop(1); | 1908 __ Drop(1); |
1909 } | 1909 } |
(...skipping 18 matching lines...) Expand all Loading... |
1928 | 1928 |
1929 __ pop(rcx); | 1929 __ pop(rcx); |
1930 if (expr->ends_initialization_block()) { | 1930 if (expr->ends_initialization_block()) { |
1931 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. | 1931 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. |
1932 } else { | 1932 } else { |
1933 __ pop(rdx); | 1933 __ pop(rdx); |
1934 } | 1934 } |
1935 // Record source code position before IC call. | 1935 // Record source code position before IC call. |
1936 SetSourcePosition(expr->position()); | 1936 SetSourcePosition(expr->position()); |
1937 Handle<Code> ic(Builtins::builtin( | 1937 Handle<Code> ic(Builtins::builtin( |
1938 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 1938 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
1939 : Builtins::KeyedStoreIC_Initialize)); | 1939 : Builtins::KeyedStoreIC_Initialize)); |
1940 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1940 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1941 | 1941 |
1942 // If the assignment ends an initialization block, revert to fast case. | 1942 // If the assignment ends an initialization block, revert to fast case. |
1943 if (expr->ends_initialization_block()) { | 1943 if (expr->ends_initialization_block()) { |
1944 __ pop(rdx); | 1944 __ pop(rdx); |
1945 __ push(rax); // Result of assignment, saved even if not needed. | 1945 __ push(rax); // Result of assignment, saved even if not needed. |
1946 __ push(rdx); | 1946 __ push(rdx); |
1947 __ CallRuntime(Runtime::kToFastProperties, 1); | 1947 __ CallRuntime(Runtime::kToFastProperties, 1); |
1948 __ pop(rax); | 1948 __ pop(rax); |
1949 } | 1949 } |
(...skipping 1591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3541 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 3541 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
3542 Token::ASSIGN); | 3542 Token::ASSIGN); |
3543 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3543 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3544 context()->Plug(rax); | 3544 context()->Plug(rax); |
3545 } | 3545 } |
3546 break; | 3546 break; |
3547 case NAMED_PROPERTY: { | 3547 case NAMED_PROPERTY: { |
3548 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 3548 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
3549 __ pop(rdx); | 3549 __ pop(rdx); |
3550 Handle<Code> ic(Builtins::builtin( | 3550 Handle<Code> ic(Builtins::builtin( |
3551 is_strict() ? Builtins::StoreIC_Initialize_Strict | 3551 is_strict_mode() ? Builtins::StoreIC_Initialize_Strict |
3552 : Builtins::StoreIC_Initialize)); | 3552 : Builtins::StoreIC_Initialize)); |
3553 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3553 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3554 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3554 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3555 if (expr->is_postfix()) { | 3555 if (expr->is_postfix()) { |
3556 if (!context()->IsEffect()) { | 3556 if (!context()->IsEffect()) { |
3557 context()->PlugTOS(); | 3557 context()->PlugTOS(); |
3558 } | 3558 } |
3559 } else { | 3559 } else { |
3560 context()->Plug(rax); | 3560 context()->Plug(rax); |
3561 } | 3561 } |
3562 break; | 3562 break; |
3563 } | 3563 } |
3564 case KEYED_PROPERTY: { | 3564 case KEYED_PROPERTY: { |
3565 __ pop(rcx); | 3565 __ pop(rcx); |
3566 __ pop(rdx); | 3566 __ pop(rdx); |
3567 Handle<Code> ic(Builtins::builtin( | 3567 Handle<Code> ic(Builtins::builtin( |
3568 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict | 3568 is_strict_mode() ? Builtins::KeyedStoreIC_Initialize_Strict |
3569 : Builtins::KeyedStoreIC_Initialize)); | 3569 : Builtins::KeyedStoreIC_Initialize)); |
3570 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 3570 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
3571 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 3571 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
3572 if (expr->is_postfix()) { | 3572 if (expr->is_postfix()) { |
3573 if (!context()->IsEffect()) { | 3573 if (!context()->IsEffect()) { |
3574 context()->PlugTOS(); | 3574 context()->PlugTOS(); |
3575 } | 3575 } |
3576 } else { | 3576 } else { |
3577 context()->Plug(rax); | 3577 context()->Plug(rax); |
3578 } | 3578 } |
3579 break; | 3579 break; |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3967 __ ret(0); | 3967 __ ret(0); |
3968 } | 3968 } |
3969 | 3969 |
3970 | 3970 |
3971 #undef __ | 3971 #undef __ |
3972 | 3972 |
3973 | 3973 |
3974 } } // namespace v8::internal | 3974 } } // namespace v8::internal |
3975 | 3975 |
3976 #endif // V8_TARGET_ARCH_X64 | 3976 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |