| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1279 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); | 1279 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); |
| 1280 __ j(not_equal, slow); | 1280 __ j(not_equal, slow); |
| 1281 // Load next context in chain. | 1281 // Load next context in chain. |
| 1282 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1282 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
| 1283 __ jmp(&next); | 1283 __ jmp(&next); |
| 1284 __ bind(&fast); | 1284 __ bind(&fast); |
| 1285 } | 1285 } |
| 1286 | 1286 |
| 1287 // All extension objects were empty and it is safe to use a global | 1287 // All extension objects were empty and it is safe to use a global |
| 1288 // load IC call. | 1288 // load IC call. |
| 1289 __ mov(eax, GlobalObjectOperand()); | 1289 __ mov(edx, GlobalObjectOperand()); |
| 1290 __ mov(ecx, var->name()); | 1290 __ mov(ecx, var->name()); |
| 1291 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1291 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1292 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) | 1292 RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
| 1293 ? RelocInfo::CODE_TARGET | 1293 ? RelocInfo::CODE_TARGET |
| 1294 : RelocInfo::CODE_TARGET_CONTEXT; | 1294 : RelocInfo::CODE_TARGET_CONTEXT; |
| 1295 CallIC(ic, mode); | 1295 CallIC(ic, mode); |
| 1296 } | 1296 } |
| 1297 | 1297 |
| 1298 | 1298 |
| 1299 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1299 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 SetSourcePosition(proxy->position()); | 1363 SetSourcePosition(proxy->position()); |
| 1364 Variable* var = proxy->var(); | 1364 Variable* var = proxy->var(); |
| 1365 | 1365 |
| 1366 // Three cases: global variables, lookup variables, and all other types of | 1366 // Three cases: global variables, lookup variables, and all other types of |
| 1367 // variables. | 1367 // variables. |
| 1368 switch (var->location()) { | 1368 switch (var->location()) { |
| 1369 case Variable::UNALLOCATED: { | 1369 case Variable::UNALLOCATED: { |
| 1370 Comment cmnt(masm_, "Global variable"); | 1370 Comment cmnt(masm_, "Global variable"); |
| 1371 // Use inline caching. Variable name is passed in ecx and the global | 1371 // Use inline caching. Variable name is passed in ecx and the global |
| 1372 // object in eax. | 1372 // object in eax. |
| 1373 __ mov(eax, GlobalObjectOperand()); | 1373 __ mov(edx, GlobalObjectOperand()); |
| 1374 __ mov(ecx, var->name()); | 1374 __ mov(ecx, var->name()); |
| 1375 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 1375 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 1376 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); | 1376 CallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
| 1377 context()->Plug(eax); | 1377 context()->Plug(eax); |
| 1378 break; | 1378 break; |
| 1379 } | 1379 } |
| 1380 | 1380 |
| 1381 case Variable::PARAMETER: | 1381 case Variable::PARAMETER: |
| 1382 case Variable::LOCAL: | 1382 case Variable::LOCAL: |
| 1383 case Variable::CONTEXT: { | 1383 case Variable::CONTEXT: { |
| (...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 : KEYED_PROPERTY; | 1757 : KEYED_PROPERTY; |
| 1758 } | 1758 } |
| 1759 | 1759 |
| 1760 // Evaluate LHS expression. | 1760 // Evaluate LHS expression. |
| 1761 switch (assign_type) { | 1761 switch (assign_type) { |
| 1762 case VARIABLE: | 1762 case VARIABLE: |
| 1763 // Nothing to do here. | 1763 // Nothing to do here. |
| 1764 break; | 1764 break; |
| 1765 case NAMED_PROPERTY: | 1765 case NAMED_PROPERTY: |
| 1766 if (expr->is_compound()) { | 1766 if (expr->is_compound()) { |
| 1767 // We need the receiver both on the stack and in the accumulator. | 1767 // We need the receiver both on the stack and in edx. |
| 1768 VisitForAccumulatorValue(property->obj()); | 1768 VisitForStackValue(property->obj()); |
| 1769 __ push(result_register()); | 1769 __ mov(edx, Operand(esp, 0)); |
| 1770 } else { | 1770 } else { |
| 1771 VisitForStackValue(property->obj()); | 1771 VisitForStackValue(property->obj()); |
| 1772 } | 1772 } |
| 1773 break; | 1773 break; |
| 1774 case KEYED_PROPERTY: { | 1774 case KEYED_PROPERTY: { |
| 1775 if (expr->is_compound()) { | 1775 if (expr->is_compound()) { |
| 1776 VisitForStackValue(property->obj()); | 1776 VisitForStackValue(property->obj()); |
| 1777 VisitForAccumulatorValue(property->key()); | 1777 VisitForStackValue(property->key()); |
| 1778 __ mov(edx, Operand(esp, 0)); | 1778 __ mov(edx, Operand(esp, kPointerSize)); // Object. |
| 1779 __ push(eax); | 1779 __ mov(ecx, Operand(esp, 0)); // Key. |
| 1780 } else { | 1780 } else { |
| 1781 VisitForStackValue(property->obj()); | 1781 VisitForStackValue(property->obj()); |
| 1782 VisitForStackValue(property->key()); | 1782 VisitForStackValue(property->key()); |
| 1783 } | 1783 } |
| 1784 break; | 1784 break; |
| 1785 } | 1785 } |
| 1786 } | 1786 } |
| 1787 | 1787 |
| 1788 // For compound assignments we need another deoptimization point after the | 1788 // For compound assignments we need another deoptimization point after the |
| 1789 // variable/property load. | 1789 // variable/property load. |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2012 ? isolate()->builtins()->StoreIC_Initialize() | 2012 ? isolate()->builtins()->StoreIC_Initialize() |
| 2013 : isolate()->builtins()->StoreIC_Initialize_Strict(); | 2013 : isolate()->builtins()->StoreIC_Initialize_Strict(); |
| 2014 CallIC(ic); | 2014 CallIC(ic); |
| 2015 break; | 2015 break; |
| 2016 } | 2016 } |
| 2017 case KEYED_PROPERTY: { | 2017 case KEYED_PROPERTY: { |
| 2018 __ push(eax); // Preserve value. | 2018 __ push(eax); // Preserve value. |
| 2019 VisitForStackValue(prop->obj()); | 2019 VisitForStackValue(prop->obj()); |
| 2020 VisitForAccumulatorValue(prop->key()); | 2020 VisitForAccumulatorValue(prop->key()); |
| 2021 __ mov(ecx, eax); | 2021 __ mov(ecx, eax); |
| 2022 __ pop(edx); | 2022 __ pop(edx); // Receiver. |
| 2023 __ pop(eax); // Restore value. | 2023 __ pop(eax); // Restore value. |
| 2024 Handle<Code> ic = is_classic_mode() | 2024 Handle<Code> ic = is_classic_mode() |
| 2025 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2025 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2026 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2026 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| 2027 CallIC(ic); | 2027 CallIC(ic); |
| 2028 break; | 2028 break; |
| 2029 } | 2029 } |
| 2030 } | 2030 } |
| 2031 context()->Plug(eax); | 2031 context()->Plug(eax); |
| 2032 } | 2032 } |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2118 __ push(Immediate(Smi::FromInt(language_mode()))); | 2118 __ push(Immediate(Smi::FromInt(language_mode()))); |
| 2119 __ CallRuntime(Runtime::kStoreContextSlot, 4); | 2119 __ CallRuntime(Runtime::kStoreContextSlot, 4); |
| 2120 } | 2120 } |
| 2121 } | 2121 } |
| 2122 // Non-initializing assignments to consts are ignored. | 2122 // Non-initializing assignments to consts are ignored. |
| 2123 } | 2123 } |
| 2124 | 2124 |
| 2125 | 2125 |
| 2126 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2126 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2127 // Assignment to a property, using a named store IC. | 2127 // Assignment to a property, using a named store IC. |
| 2128 // eax : value |
| 2129 // esp[0] : receiver |
| 2130 |
| 2128 Property* prop = expr->target()->AsProperty(); | 2131 Property* prop = expr->target()->AsProperty(); |
| 2129 ASSERT(prop != NULL); | 2132 ASSERT(prop != NULL); |
| 2130 ASSERT(prop->key()->AsLiteral() != NULL); | 2133 ASSERT(prop->key()->AsLiteral() != NULL); |
| 2131 | 2134 |
| 2132 // If the assignment starts a block of assignments to the same object, | 2135 // If the assignment starts a block of assignments to the same object, |
| 2133 // change to slow case to avoid the quadratic behavior of repeatedly | 2136 // change to slow case to avoid the quadratic behavior of repeatedly |
| 2134 // adding fast properties. | 2137 // adding fast properties. |
| 2135 if (expr->starts_initialization_block()) { | 2138 if (expr->starts_initialization_block()) { |
| 2136 __ push(result_register()); | 2139 __ push(result_register()); |
| 2137 __ push(Operand(esp, kPointerSize)); // Receiver is now under value. | 2140 __ push(Operand(esp, kPointerSize)); // Receiver is now under value. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2160 __ pop(eax); | 2163 __ pop(eax); |
| 2161 __ Drop(1); | 2164 __ Drop(1); |
| 2162 } | 2165 } |
| 2163 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2166 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2164 context()->Plug(eax); | 2167 context()->Plug(eax); |
| 2165 } | 2168 } |
| 2166 | 2169 |
| 2167 | 2170 |
| 2168 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2171 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2169 // Assignment to a property, using a keyed store IC. | 2172 // Assignment to a property, using a keyed store IC. |
| 2173 // eax : value |
| 2174 // esp[0] : key |
| 2175 // esp[kPointerSize] : receiver |
| 2170 | 2176 |
| 2171 // If the assignment starts a block of assignments to the same object, | 2177 // If the assignment starts a block of assignments to the same object, |
| 2172 // change to slow case to avoid the quadratic behavior of repeatedly | 2178 // change to slow case to avoid the quadratic behavior of repeatedly |
| 2173 // adding fast properties. | 2179 // adding fast properties. |
| 2174 if (expr->starts_initialization_block()) { | 2180 if (expr->starts_initialization_block()) { |
| 2175 __ push(result_register()); | 2181 __ push(result_register()); |
| 2176 // Receiver is now under the key and value. | 2182 // Receiver is now under the key and value. |
| 2177 __ push(Operand(esp, 2 * kPointerSize)); | 2183 __ push(Operand(esp, 2 * kPointerSize)); |
| 2178 __ CallRuntime(Runtime::kToSlowProperties, 1); | 2184 __ CallRuntime(Runtime::kToSlowProperties, 1); |
| 2179 __ pop(result_register()); | 2185 __ pop(result_register()); |
| 2180 } | 2186 } |
| 2181 | 2187 |
| 2182 __ pop(ecx); | 2188 __ pop(ecx); // Key. |
| 2183 if (expr->ends_initialization_block()) { | 2189 if (expr->ends_initialization_block()) { |
| 2184 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. | 2190 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. |
| 2185 } else { | 2191 } else { |
| 2186 __ pop(edx); | 2192 __ pop(edx); |
| 2187 } | 2193 } |
| 2188 // Record source code position before IC call. | 2194 // Record source code position before IC call. |
| 2189 SetSourcePosition(expr->position()); | 2195 SetSourcePosition(expr->position()); |
| 2190 Handle<Code> ic = is_classic_mode() | 2196 Handle<Code> ic = is_classic_mode() |
| 2191 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2197 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
| 2192 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2198 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2205 context()->Plug(eax); | 2211 context()->Plug(eax); |
| 2206 } | 2212 } |
| 2207 | 2213 |
| 2208 | 2214 |
| 2209 void FullCodeGenerator::VisitProperty(Property* expr) { | 2215 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2210 Comment cmnt(masm_, "[ Property"); | 2216 Comment cmnt(masm_, "[ Property"); |
| 2211 Expression* key = expr->key(); | 2217 Expression* key = expr->key(); |
| 2212 | 2218 |
| 2213 if (key->IsPropertyName()) { | 2219 if (key->IsPropertyName()) { |
| 2214 VisitForAccumulatorValue(expr->obj()); | 2220 VisitForAccumulatorValue(expr->obj()); |
| 2221 __ mov(edx, result_register()); |
| 2215 EmitNamedPropertyLoad(expr); | 2222 EmitNamedPropertyLoad(expr); |
| 2216 context()->Plug(eax); | 2223 context()->Plug(eax); |
| 2217 } else { | 2224 } else { |
| 2218 VisitForStackValue(expr->obj()); | 2225 VisitForStackValue(expr->obj()); |
| 2219 VisitForAccumulatorValue(expr->key()); | 2226 VisitForAccumulatorValue(expr->key()); |
| 2220 __ pop(edx); | 2227 __ pop(edx); // Object. |
| 2228 __ mov(ecx, result_register()); // Key. |
| 2221 EmitKeyedPropertyLoad(expr); | 2229 EmitKeyedPropertyLoad(expr); |
| 2222 context()->Plug(eax); | 2230 context()->Plug(eax); |
| 2223 } | 2231 } |
| 2224 } | 2232 } |
| 2225 | 2233 |
| 2226 | 2234 |
| 2227 void FullCodeGenerator::CallIC(Handle<Code> code, | 2235 void FullCodeGenerator::CallIC(Handle<Code> code, |
| 2228 RelocInfo::Mode rmode, | 2236 RelocInfo::Mode rmode, |
| 2229 unsigned ast_id) { | 2237 unsigned ast_id) { |
| 2230 ic_total_count_++; | 2238 ic_total_count_++; |
| (...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4102 if (assign_type == VARIABLE) { | 4110 if (assign_type == VARIABLE) { |
| 4103 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); | 4111 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4104 AccumulatorValueContext context(this); | 4112 AccumulatorValueContext context(this); |
| 4105 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4113 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4106 } else { | 4114 } else { |
| 4107 // Reserve space for result of postfix operation. | 4115 // Reserve space for result of postfix operation. |
| 4108 if (expr->is_postfix() && !context()->IsEffect()) { | 4116 if (expr->is_postfix() && !context()->IsEffect()) { |
| 4109 __ push(Immediate(Smi::FromInt(0))); | 4117 __ push(Immediate(Smi::FromInt(0))); |
| 4110 } | 4118 } |
| 4111 if (assign_type == NAMED_PROPERTY) { | 4119 if (assign_type == NAMED_PROPERTY) { |
| 4112 // Put the object both on the stack and in the accumulator. | 4120 // Put the object both on the stack and in edx. |
| 4113 VisitForAccumulatorValue(prop->obj()); | 4121 VisitForAccumulatorValue(prop->obj()); |
| 4114 __ push(eax); | 4122 __ push(eax); |
| 4123 __ mov(edx, eax); |
| 4115 EmitNamedPropertyLoad(prop); | 4124 EmitNamedPropertyLoad(prop); |
| 4116 } else { | 4125 } else { |
| 4117 VisitForStackValue(prop->obj()); | 4126 VisitForStackValue(prop->obj()); |
| 4118 VisitForAccumulatorValue(prop->key()); | 4127 VisitForStackValue(prop->key()); |
| 4119 __ mov(edx, Operand(esp, 0)); | 4128 __ mov(edx, Operand(esp, kPointerSize)); // Object. |
| 4120 __ push(eax); | 4129 __ mov(ecx, Operand(esp, 0)); // Key. |
| 4121 EmitKeyedPropertyLoad(prop); | 4130 EmitKeyedPropertyLoad(prop); |
| 4122 } | 4131 } |
| 4123 } | 4132 } |
| 4124 | 4133 |
| 4125 // We need a second deoptimization point after loading the value | 4134 // We need a second deoptimization point after loading the value |
| 4126 // in case evaluating the property load my have a side effect. | 4135 // in case evaluating the property load my have a side effect. |
| 4127 if (assign_type == VARIABLE) { | 4136 if (assign_type == VARIABLE) { |
| 4128 PrepareForBailout(expr->expression(), TOS_REG); | 4137 PrepareForBailout(expr->expression(), TOS_REG); |
| 4129 } else { | 4138 } else { |
| 4130 PrepareForBailoutForId(expr->CountId(), TOS_REG); | 4139 PrepareForBailoutForId(expr->CountId(), TOS_REG); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4257 } | 4266 } |
| 4258 | 4267 |
| 4259 | 4268 |
| 4260 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4269 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
| 4261 VariableProxy* proxy = expr->AsVariableProxy(); | 4270 VariableProxy* proxy = expr->AsVariableProxy(); |
| 4262 ASSERT(!context()->IsEffect()); | 4271 ASSERT(!context()->IsEffect()); |
| 4263 ASSERT(!context()->IsTest()); | 4272 ASSERT(!context()->IsTest()); |
| 4264 | 4273 |
| 4265 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4274 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
| 4266 Comment cmnt(masm_, "Global variable"); | 4275 Comment cmnt(masm_, "Global variable"); |
| 4267 __ mov(eax, GlobalObjectOperand()); | 4276 __ mov(edx, GlobalObjectOperand()); |
| 4268 __ mov(ecx, Immediate(proxy->name())); | 4277 __ mov(ecx, Immediate(proxy->name())); |
| 4269 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 4278 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
| 4270 // Use a regular load, not a contextual load, to avoid a reference | 4279 // Use a regular load, not a contextual load, to avoid a reference |
| 4271 // error. | 4280 // error. |
| 4272 CallIC(ic); | 4281 CallIC(ic); |
| 4273 PrepareForBailout(expr, TOS_REG); | 4282 PrepareForBailout(expr, TOS_REG); |
| 4274 context()->Plug(eax); | 4283 context()->Plug(eax); |
| 4275 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4284 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
| 4276 Label done, slow; | 4285 Label done, slow; |
| 4277 | 4286 |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4602 *context_length = 0; | 4611 *context_length = 0; |
| 4603 return previous_; | 4612 return previous_; |
| 4604 } | 4613 } |
| 4605 | 4614 |
| 4606 | 4615 |
| 4607 #undef __ | 4616 #undef __ |
| 4608 | 4617 |
| 4609 } } // namespace v8::internal | 4618 } } // namespace v8::internal |
| 4610 | 4619 |
| 4611 #endif // V8_TARGET_ARCH_IA32 | 4620 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |