| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 result_saved = true; | 910 result_saved = true; |
| 911 } | 911 } |
| 912 switch (property->kind()) { | 912 switch (property->kind()) { |
| 913 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 913 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 914 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 914 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 915 // Fall through. | 915 // Fall through. |
| 916 case ObjectLiteral::Property::COMPUTED: | 916 case ObjectLiteral::Property::COMPUTED: |
| 917 if (key->handle()->IsSymbol()) { | 917 if (key->handle()->IsSymbol()) { |
| 918 VisitForValue(value, kAccumulator); | 918 VisitForValue(value, kAccumulator); |
| 919 __ mov(ecx, Immediate(key->handle())); | 919 __ mov(ecx, Immediate(key->handle())); |
| 920 __ mov(edx, Operand(esp, 0)); |
| 920 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 921 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 921 __ call(ic, RelocInfo::CODE_TARGET); | 922 __ call(ic, RelocInfo::CODE_TARGET); |
| 922 __ nop(); | 923 __ nop(); |
| 923 // StoreIC leaves the receiver on the stack. | |
| 924 break; | 924 break; |
| 925 } | 925 } |
| 926 // Fall through. | 926 // Fall through. |
| 927 case ObjectLiteral::Property::PROTOTYPE: | 927 case ObjectLiteral::Property::PROTOTYPE: |
| 928 __ push(Operand(esp, 0)); // Duplicate receiver. | 928 __ push(Operand(esp, 0)); // Duplicate receiver. |
| 929 VisitForValue(key, kStack); | 929 VisitForValue(key, kStack); |
| 930 VisitForValue(value, kStack); | 930 VisitForValue(value, kStack); |
| 931 __ CallRuntime(Runtime::kSetProperty, 3); | 931 __ CallRuntime(Runtime::kSetProperty, 3); |
| 932 break; | 932 break; |
| 933 case ObjectLiteral::Property::SETTER: | 933 case ObjectLiteral::Property::SETTER: |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1039 ASSERT(var != NULL); | 1039 ASSERT(var != NULL); |
| 1040 ASSERT(var->is_global() || var->slot() != NULL); | 1040 ASSERT(var->is_global() || var->slot() != NULL); |
| 1041 | 1041 |
| 1042 Slot* slot = var->slot(); | 1042 Slot* slot = var->slot(); |
| 1043 if (var->is_global()) { | 1043 if (var->is_global()) { |
| 1044 ASSERT(!var->is_this()); | 1044 ASSERT(!var->is_this()); |
| 1045 // Assignment to a global variable. Use inline caching for the | 1045 // Assignment to a global variable. Use inline caching for the |
| 1046 // assignment. Right-hand-side value is passed in eax, variable name in | 1046 // assignment. Right-hand-side value is passed in eax, variable name in |
| 1047 // ecx, and the global object on the stack. | 1047 // ecx, and the global object on the stack. |
| 1048 __ mov(ecx, var->name()); | 1048 __ mov(ecx, var->name()); |
| 1049 __ push(CodeGenerator::GlobalObject()); | 1049 __ mov(edx, CodeGenerator::GlobalObject()); |
| 1050 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1050 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 1051 __ call(ic, RelocInfo::CODE_TARGET); | 1051 __ call(ic, RelocInfo::CODE_TARGET); |
| 1052 __ nop(); | 1052 __ nop(); |
| 1053 // Overwrite the receiver on the stack with the result if needed. | 1053 Apply(context, eax); |
| 1054 DropAndApply(1, context, eax); | |
| 1055 | 1054 |
| 1056 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1055 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
| 1057 __ push(result_register()); // Value. | 1056 __ push(result_register()); // Value. |
| 1058 __ push(esi); // Context. | 1057 __ push(esi); // Context. |
| 1059 __ push(Immediate(var->name())); | 1058 __ push(Immediate(var->name())); |
| 1060 __ CallRuntime(Runtime::kStoreContextSlot, 3); | 1059 __ CallRuntime(Runtime::kStoreContextSlot, 3); |
| 1061 Apply(context, eax); | 1060 Apply(context, eax); |
| 1062 | 1061 |
| 1063 } else if (slot != NULL) { | 1062 } else if (slot != NULL) { |
| 1064 switch (slot->type()) { | 1063 switch (slot->type()) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 if (expr->starts_initialization_block()) { | 1103 if (expr->starts_initialization_block()) { |
| 1105 __ push(result_register()); | 1104 __ push(result_register()); |
| 1106 __ push(Operand(esp, kPointerSize)); // Receiver is now under value. | 1105 __ push(Operand(esp, kPointerSize)); // Receiver is now under value. |
| 1107 __ CallRuntime(Runtime::kToSlowProperties, 1); | 1106 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 1108 __ pop(result_register()); | 1107 __ pop(result_register()); |
| 1109 } | 1108 } |
| 1110 | 1109 |
| 1111 // Record source code position before IC call. | 1110 // Record source code position before IC call. |
| 1112 SetSourcePosition(expr->position()); | 1111 SetSourcePosition(expr->position()); |
| 1113 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1112 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1113 if (expr->ends_initialization_block()) { |
| 1114 __ mov(edx, Operand(esp, 0)); |
| 1115 } else { |
| 1116 __ pop(edx); |
| 1117 } |
| 1114 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1118 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 1115 __ call(ic, RelocInfo::CODE_TARGET); | 1119 __ call(ic, RelocInfo::CODE_TARGET); |
| 1116 __ nop(); | 1120 __ nop(); |
| 1117 | 1121 |
| 1118 // If the assignment ends an initialization block, revert to fast case. | 1122 // If the assignment ends an initialization block, revert to fast case. |
| 1119 if (expr->ends_initialization_block()) { | 1123 if (expr->ends_initialization_block()) { |
| 1120 __ push(eax); // Result of assignment, saved even if not needed. | 1124 __ push(eax); // Result of assignment, saved even if not needed. |
| 1121 __ push(Operand(esp, kPointerSize)); // Receiver is under value. | 1125 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
| 1122 __ CallRuntime(Runtime::kToFastProperties, 1); | 1126 __ CallRuntime(Runtime::kToFastProperties, 1); |
| 1123 __ pop(eax); | 1127 __ pop(eax); |
| 1128 DropAndApply(1, context_, eax); |
| 1129 } else { |
| 1130 Apply(context_, eax); |
| 1124 } | 1131 } |
| 1125 | |
| 1126 DropAndApply(1, context_, eax); | |
| 1127 } | 1132 } |
| 1128 | 1133 |
| 1129 | 1134 |
| 1130 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1135 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 1131 // Assignment to a property, using a keyed store IC. | 1136 // Assignment to a property, using a keyed store IC. |
| 1132 | 1137 |
| 1133 // If the assignment starts a block of assignments to the same object, | 1138 // If the assignment starts a block of assignments to the same object, |
| 1134 // change to slow case to avoid the quadratic behavior of repeatedly | 1139 // change to slow case to avoid the quadratic behavior of repeatedly |
| 1135 // adding fast properties. | 1140 // adding fast properties. |
| 1136 if (expr->starts_initialization_block()) { | 1141 if (expr->starts_initialization_block()) { |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1635 if (context_ != Expression::kEffect) { | 1640 if (context_ != Expression::kEffect) { |
| 1636 ApplyTOS(context_); | 1641 ApplyTOS(context_); |
| 1637 } | 1642 } |
| 1638 } else { | 1643 } else { |
| 1639 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 1644 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
| 1640 context_); | 1645 context_); |
| 1641 } | 1646 } |
| 1642 break; | 1647 break; |
| 1643 case NAMED_PROPERTY: { | 1648 case NAMED_PROPERTY: { |
| 1644 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1649 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1650 __ pop(edx); |
| 1645 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1651 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 1646 __ call(ic, RelocInfo::CODE_TARGET); | 1652 __ call(ic, RelocInfo::CODE_TARGET); |
| 1647 // This nop signals to the IC that there is no inlined code at the call | 1653 // This nop signals to the IC that there is no inlined code at the call |
| 1648 // site for it to patch. | 1654 // site for it to patch. |
| 1649 __ nop(); | 1655 __ nop(); |
| 1650 if (expr->is_postfix()) { | 1656 if (expr->is_postfix()) { |
| 1651 __ Drop(1); // Result is on the stack under the receiver. | |
| 1652 if (context_ != Expression::kEffect) { | 1657 if (context_ != Expression::kEffect) { |
| 1653 ApplyTOS(context_); | 1658 ApplyTOS(context_); |
| 1654 } | 1659 } |
| 1655 } else { | 1660 } else { |
| 1656 DropAndApply(1, context_, eax); | 1661 Apply(context_, eax); |
| 1657 } | 1662 } |
| 1658 break; | 1663 break; |
| 1659 } | 1664 } |
| 1660 case KEYED_PROPERTY: { | 1665 case KEYED_PROPERTY: { |
| 1661 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1666 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
| 1662 __ call(ic, RelocInfo::CODE_TARGET); | 1667 __ call(ic, RelocInfo::CODE_TARGET); |
| 1663 // This nop signals to the IC that there is no inlined code at the call | 1668 // This nop signals to the IC that there is no inlined code at the call |
| 1664 // site for it to patch. | 1669 // site for it to patch. |
| 1665 __ nop(); | 1670 __ nop(); |
| 1666 if (expr->is_postfix()) { | 1671 if (expr->is_postfix()) { |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1877 __ add(Operand(edx), Immediate(masm_->CodeObject())); | 1882 __ add(Operand(edx), Immediate(masm_->CodeObject())); |
| 1878 __ mov(Operand(esp, 0), edx); | 1883 __ mov(Operand(esp, 0), edx); |
| 1879 // And return. | 1884 // And return. |
| 1880 __ ret(0); | 1885 __ ret(0); |
| 1881 } | 1886 } |
| 1882 | 1887 |
| 1883 | 1888 |
| 1884 #undef __ | 1889 #undef __ |
| 1885 | 1890 |
| 1886 } } // namespace v8::internal | 1891 } } // namespace v8::internal |
| OLD | NEW |