OLD | NEW |
1 // Copyright 2009 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 |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 switch (property->kind()) { | 922 switch (property->kind()) { |
923 case ObjectLiteral::Property::CONSTANT: | 923 case ObjectLiteral::Property::CONSTANT: |
924 UNREACHABLE(); | 924 UNREACHABLE(); |
925 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 925 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
926 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 926 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
927 // Fall through. | 927 // Fall through. |
928 case ObjectLiteral::Property::COMPUTED: | 928 case ObjectLiteral::Property::COMPUTED: |
929 if (key->handle()->IsSymbol()) { | 929 if (key->handle()->IsSymbol()) { |
930 VisitForValue(value, kAccumulator); | 930 VisitForValue(value, kAccumulator); |
931 __ Move(rcx, key->handle()); | 931 __ Move(rcx, key->handle()); |
| 932 __ movq(rdx, Operand(rsp, 0)); |
932 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 933 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
933 __ call(ic, RelocInfo::CODE_TARGET); | 934 __ call(ic, RelocInfo::CODE_TARGET); |
934 __ nop(); | 935 __ nop(); |
935 // StoreIC leaves the receiver on the stack. | |
936 break; | 936 break; |
937 } | 937 } |
938 // Fall through. | 938 // Fall through. |
939 case ObjectLiteral::Property::PROTOTYPE: | 939 case ObjectLiteral::Property::PROTOTYPE: |
940 __ push(Operand(rsp, 0)); // Duplicate receiver. | 940 __ push(Operand(rsp, 0)); // Duplicate receiver. |
941 VisitForValue(key, kStack); | 941 VisitForValue(key, kStack); |
942 VisitForValue(value, kStack); | 942 VisitForValue(value, kStack); |
943 __ CallRuntime(Runtime::kSetProperty, 3); | 943 __ CallRuntime(Runtime::kSetProperty, 3); |
944 break; | 944 break; |
945 case ObjectLiteral::Property::SETTER: | 945 case ObjectLiteral::Property::SETTER: |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1047 // Three main cases: non-this global variables, lookup slots, and | 1047 // Three main cases: non-this global variables, lookup slots, and |
1048 // all other types of slots. Left-hand-side parameters that rewrite | 1048 // all other types of slots. Left-hand-side parameters that rewrite |
1049 // to explicit property accesses do not reach here. | 1049 // to explicit property accesses do not reach here. |
1050 ASSERT(var != NULL); | 1050 ASSERT(var != NULL); |
1051 ASSERT(var->is_global() || var->slot() != NULL); | 1051 ASSERT(var->is_global() || var->slot() != NULL); |
1052 Slot* slot = var->slot(); | 1052 Slot* slot = var->slot(); |
1053 if (var->is_global()) { | 1053 if (var->is_global()) { |
1054 ASSERT(!var->is_this()); | 1054 ASSERT(!var->is_this()); |
1055 // Assignment to a global variable. Use inline caching for the | 1055 // Assignment to a global variable. Use inline caching for the |
1056 // assignment. Right-hand-side value is passed in rax, variable name in | 1056 // assignment. Right-hand-side value is passed in rax, variable name in |
1057 // rcx, and the global object on the stack. | 1057 // rcx, and the global object in rdx. |
1058 __ Move(rcx, var->name()); | 1058 __ Move(rcx, var->name()); |
1059 __ push(CodeGenerator::GlobalObject()); | 1059 __ movq(rdx, CodeGenerator::GlobalObject()); |
1060 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1060 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1061 __ Call(ic, RelocInfo::CODE_TARGET); | 1061 __ Call(ic, RelocInfo::CODE_TARGET); |
1062 // Overwrite the global object on the stack with the result if needed. | 1062 Apply(context, rax); |
1063 DropAndApply(1, context, rax); | |
1064 | 1063 |
1065 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1064 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1066 __ push(result_register()); // Value. | 1065 __ push(result_register()); // Value. |
1067 __ push(rsi); // Context. | 1066 __ push(rsi); // Context. |
1068 __ Push(var->name()); | 1067 __ Push(var->name()); |
1069 __ CallRuntime(Runtime::kStoreContextSlot, 3); | 1068 __ CallRuntime(Runtime::kStoreContextSlot, 3); |
1070 Apply(context, rax); | 1069 Apply(context, rax); |
1071 | 1070 |
1072 } else if (var->slot() != NULL) { | 1071 } else if (var->slot() != NULL) { |
1073 switch (slot->type()) { | 1072 switch (slot->type()) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 if (expr->starts_initialization_block()) { | 1112 if (expr->starts_initialization_block()) { |
1114 __ push(result_register()); | 1113 __ push(result_register()); |
1115 __ push(Operand(rsp, kPointerSize)); // Receiver is now under value. | 1114 __ push(Operand(rsp, kPointerSize)); // Receiver is now under value. |
1116 __ CallRuntime(Runtime::kToSlowProperties, 1); | 1115 __ CallRuntime(Runtime::kToSlowProperties, 1); |
1117 __ pop(result_register()); | 1116 __ pop(result_register()); |
1118 } | 1117 } |
1119 | 1118 |
1120 // Record source code position before IC call. | 1119 // Record source code position before IC call. |
1121 SetSourcePosition(expr->position()); | 1120 SetSourcePosition(expr->position()); |
1122 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1121 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1122 if (expr->ends_initialization_block()) { |
| 1123 __ movq(rdx, Operand(rsp, 0)); |
| 1124 } else { |
| 1125 __ pop(rdx); |
| 1126 } |
1123 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1127 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1124 __ Call(ic, RelocInfo::CODE_TARGET); | 1128 __ Call(ic, RelocInfo::CODE_TARGET); |
1125 __ nop(); | 1129 __ nop(); |
1126 | 1130 |
1127 // If the assignment ends an initialization block, revert to fast case. | 1131 // If the assignment ends an initialization block, revert to fast case. |
1128 if (expr->ends_initialization_block()) { | 1132 if (expr->ends_initialization_block()) { |
1129 __ push(rax); // Result of assignment, saved even if not needed. | 1133 __ push(rax); // Result of assignment, saved even if not needed. |
1130 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. | 1134 __ push(Operand(rsp, kPointerSize)); // Receiver is under value. |
1131 __ CallRuntime(Runtime::kToFastProperties, 1); | 1135 __ CallRuntime(Runtime::kToFastProperties, 1); |
1132 __ pop(rax); | 1136 __ pop(rax); |
| 1137 DropAndApply(1, context_, rax); |
| 1138 } else { |
| 1139 Apply(context_, rax); |
1133 } | 1140 } |
1134 | |
1135 DropAndApply(1, context_, rax); | |
1136 } | 1141 } |
1137 | 1142 |
1138 | 1143 |
1139 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1144 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
1140 // Assignment to a property, using a keyed store IC. | 1145 // Assignment to a property, using a keyed store IC. |
1141 | 1146 |
1142 // If the assignment starts a block of assignments to the same object, | 1147 // If the assignment starts a block of assignments to the same object, |
1143 // change to slow case to avoid the quadratic behavior of repeatedly | 1148 // change to slow case to avoid the quadratic behavior of repeatedly |
1144 // adding fast properties. | 1149 // adding fast properties. |
1145 if (expr->starts_initialization_block()) { | 1150 if (expr->starts_initialization_block()) { |
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1651 if (context_ != Expression::kEffect) { | 1656 if (context_ != Expression::kEffect) { |
1652 ApplyTOS(context_); | 1657 ApplyTOS(context_); |
1653 } | 1658 } |
1654 } else { | 1659 } else { |
1655 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 1660 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
1656 context_); | 1661 context_); |
1657 } | 1662 } |
1658 break; | 1663 break; |
1659 case NAMED_PROPERTY: { | 1664 case NAMED_PROPERTY: { |
1660 __ Move(rcx, prop->key()->AsLiteral()->handle()); | 1665 __ Move(rcx, prop->key()->AsLiteral()->handle()); |
| 1666 __ pop(rdx); |
1661 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1667 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1662 __ call(ic, RelocInfo::CODE_TARGET); | 1668 __ call(ic, RelocInfo::CODE_TARGET); |
1663 // This nop signals to the IC that there is no inlined code at the call | 1669 // This nop signals to the IC that there is no inlined code at the call |
1664 // site for it to patch. | 1670 // site for it to patch. |
1665 __ nop(); | 1671 __ nop(); |
1666 if (expr->is_postfix()) { | 1672 if (expr->is_postfix()) { |
1667 __ Drop(1); // Result is on the stack under the receiver. | |
1668 if (context_ != Expression::kEffect) { | 1673 if (context_ != Expression::kEffect) { |
1669 ApplyTOS(context_); | 1674 ApplyTOS(context_); |
1670 } | 1675 } |
1671 } else { | 1676 } else { |
1672 DropAndApply(1, context_, rax); | 1677 Apply(context_, rax); |
1673 } | 1678 } |
1674 break; | 1679 break; |
1675 } | 1680 } |
1676 case KEYED_PROPERTY: { | 1681 case KEYED_PROPERTY: { |
1677 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1682 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
1678 __ call(ic, RelocInfo::CODE_TARGET); | 1683 __ call(ic, RelocInfo::CODE_TARGET); |
1679 // This nop signals to the IC that there is no inlined code at the call | 1684 // This nop signals to the IC that there is no inlined code at the call |
1680 // site for it to patch. | 1685 // site for it to patch. |
1681 __ nop(); | 1686 __ nop(); |
1682 if (expr->is_postfix()) { | 1687 if (expr->is_postfix()) { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1893 __ movq(Operand(rsp, 0), rdx); | 1898 __ movq(Operand(rsp, 0), rdx); |
1894 // And return. | 1899 // And return. |
1895 __ ret(0); | 1900 __ ret(0); |
1896 } | 1901 } |
1897 | 1902 |
1898 | 1903 |
1899 #undef __ | 1904 #undef __ |
1900 | 1905 |
1901 | 1906 |
1902 } } // namespace v8::internal | 1907 } } // namespace v8::internal |
OLD | NEW |