OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 __ CallRuntime(Runtime::kDeclareContextSlot, 4); | 844 __ CallRuntime(Runtime::kDeclareContextSlot, 4); |
845 break; | 845 break; |
846 } | 846 } |
847 } | 847 } |
848 | 848 |
849 } else if (prop != NULL) { | 849 } else if (prop != NULL) { |
850 if (function != NULL || mode == Variable::CONST) { | 850 if (function != NULL || mode == Variable::CONST) { |
851 // We are declaring a function or constant that rewrites to a | 851 // We are declaring a function or constant that rewrites to a |
852 // property. Use (keyed) IC to set the initial value. | 852 // property. Use (keyed) IC to set the initial value. |
853 VisitForValue(prop->obj(), kStack); | 853 VisitForValue(prop->obj(), kStack); |
854 VisitForValue(prop->key(), kStack); | |
855 | |
856 if (function != NULL) { | 854 if (function != NULL) { |
| 855 VisitForValue(prop->key(), kStack); |
857 VisitForValue(function, kAccumulator); | 856 VisitForValue(function, kAccumulator); |
| 857 __ pop(rcx); |
858 } else { | 858 } else { |
| 859 VisitForValue(prop->key(), kAccumulator); |
| 860 __ movq(rcx, result_register()); |
859 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex); | 861 __ LoadRoot(result_register(), Heap::kTheHoleValueRootIndex); |
860 } | 862 } |
| 863 __ pop(rdx); |
861 | 864 |
862 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 865 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
863 __ call(ic, RelocInfo::CODE_TARGET); | 866 __ call(ic, RelocInfo::CODE_TARGET); |
864 // Absence of a test rax instruction following the call | 867 // Absence of a test rax instruction following the call |
865 // indicates that none of the load was inlined. | 868 // indicates that none of the load was inlined. |
866 __ nop(); | 869 __ nop(); |
867 | |
868 // Value in rax is ignored (declarations are statements). Receiver | |
869 // and key on stack are discarded. | |
870 __ Drop(2); | |
871 } | 870 } |
872 } | 871 } |
873 } | 872 } |
874 | 873 |
875 | 874 |
876 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 875 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
877 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 876 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
878 } | 877 } |
879 | 878 |
880 | 879 |
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1658 // change to slow case to avoid the quadratic behavior of repeatedly | 1657 // change to slow case to avoid the quadratic behavior of repeatedly |
1659 // adding fast properties. | 1658 // adding fast properties. |
1660 if (expr->starts_initialization_block()) { | 1659 if (expr->starts_initialization_block()) { |
1661 __ push(result_register()); | 1660 __ push(result_register()); |
1662 // Receiver is now under the key and value. | 1661 // Receiver is now under the key and value. |
1663 __ push(Operand(rsp, 2 * kPointerSize)); | 1662 __ push(Operand(rsp, 2 * kPointerSize)); |
1664 __ CallRuntime(Runtime::kToSlowProperties, 1); | 1663 __ CallRuntime(Runtime::kToSlowProperties, 1); |
1665 __ pop(result_register()); | 1664 __ pop(result_register()); |
1666 } | 1665 } |
1667 | 1666 |
| 1667 __ pop(rcx); |
| 1668 if (expr->ends_initialization_block()) { |
| 1669 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on the stack for later. |
| 1670 } else { |
| 1671 __ pop(rdx); |
| 1672 } |
1668 // Record source code position before IC call. | 1673 // Record source code position before IC call. |
1669 SetSourcePosition(expr->position()); | 1674 SetSourcePosition(expr->position()); |
1670 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1675 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
1671 __ Call(ic, RelocInfo::CODE_TARGET); | 1676 __ Call(ic, RelocInfo::CODE_TARGET); |
1672 // This nop signals to the IC that there is no inlined code at the call | 1677 // This nop signals to the IC that there is no inlined code at the call |
1673 // site for it to patch. | 1678 // site for it to patch. |
1674 __ nop(); | 1679 __ nop(); |
1675 | 1680 |
1676 // If the assignment ends an initialization block, revert to fast case. | 1681 // If the assignment ends an initialization block, revert to fast case. |
1677 if (expr->ends_initialization_block()) { | 1682 if (expr->ends_initialization_block()) { |
| 1683 __ pop(rdx); |
1678 __ push(rax); // Result of assignment, saved even if not needed. | 1684 __ push(rax); // Result of assignment, saved even if not needed. |
1679 // Receiver is under the key and value. | 1685 __ push(rdx); |
1680 __ push(Operand(rsp, 2 * kPointerSize)); | |
1681 __ CallRuntime(Runtime::kToFastProperties, 1); | 1686 __ CallRuntime(Runtime::kToFastProperties, 1); |
1682 __ pop(rax); | 1687 __ pop(rax); |
1683 } | 1688 } |
1684 | 1689 |
1685 // Receiver and key are still on stack. | 1690 Apply(context_, rax); |
1686 DropAndApply(2, context_, rax); | |
1687 } | 1691 } |
1688 | 1692 |
1689 | 1693 |
1690 void FullCodeGenerator::VisitProperty(Property* expr) { | 1694 void FullCodeGenerator::VisitProperty(Property* expr) { |
1691 Comment cmnt(masm_, "[ Property"); | 1695 Comment cmnt(masm_, "[ Property"); |
1692 Expression* key = expr->key(); | 1696 Expression* key = expr->key(); |
1693 | 1697 |
1694 // Evaluate receiver. | 1698 // Evaluate receiver. |
1695 VisitForValue(expr->obj(), kStack); | 1699 VisitForValue(expr->obj(), kStack); |
1696 | 1700 |
(...skipping 1265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2962 if (expr->is_postfix()) { | 2966 if (expr->is_postfix()) { |
2963 if (context_ != Expression::kEffect) { | 2967 if (context_ != Expression::kEffect) { |
2964 ApplyTOS(context_); | 2968 ApplyTOS(context_); |
2965 } | 2969 } |
2966 } else { | 2970 } else { |
2967 Apply(context_, rax); | 2971 Apply(context_, rax); |
2968 } | 2972 } |
2969 break; | 2973 break; |
2970 } | 2974 } |
2971 case KEYED_PROPERTY: { | 2975 case KEYED_PROPERTY: { |
| 2976 __ pop(rcx); |
| 2977 __ pop(rdx); |
2972 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 2978 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
2973 __ call(ic, RelocInfo::CODE_TARGET); | 2979 __ call(ic, RelocInfo::CODE_TARGET); |
2974 // This nop signals to the IC that there is no inlined code at the call | 2980 // This nop signals to the IC that there is no inlined code at the call |
2975 // site for it to patch. | 2981 // site for it to patch. |
2976 __ nop(); | 2982 __ nop(); |
2977 if (expr->is_postfix()) { | 2983 if (expr->is_postfix()) { |
2978 __ Drop(2); // Result is on the stack under the key and the receiver. | |
2979 if (context_ != Expression::kEffect) { | 2984 if (context_ != Expression::kEffect) { |
2980 ApplyTOS(context_); | 2985 ApplyTOS(context_); |
2981 } | 2986 } |
2982 } else { | 2987 } else { |
2983 DropAndApply(2, context_, rax); | 2988 Apply(context_, rax); |
2984 } | 2989 } |
2985 break; | 2990 break; |
2986 } | 2991 } |
2987 } | 2992 } |
2988 } | 2993 } |
2989 | 2994 |
2990 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { | 2995 void FullCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
2991 Comment cmnt(masm_, "[ BinaryOperation"); | 2996 Comment cmnt(masm_, "[ BinaryOperation"); |
2992 switch (expr->op()) { | 2997 switch (expr->op()) { |
2993 case Token::COMMA: | 2998 case Token::COMMA: |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3207 __ ret(0); | 3212 __ ret(0); |
3208 } | 3213 } |
3209 | 3214 |
3210 | 3215 |
3211 #undef __ | 3216 #undef __ |
3212 | 3217 |
3213 | 3218 |
3214 } } // namespace v8::internal | 3219 } } // namespace v8::internal |
3215 | 3220 |
3216 #endif // V8_TARGET_ARCH_X64 | 3221 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |