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()); | |
2222 if (FLAG_debug_code) { | |
2223 __ mov(result_register(), Immediate(0xbeefdeed)); // Zap eax. | |
2224 } | |
2215 EmitNamedPropertyLoad(expr); | 2225 EmitNamedPropertyLoad(expr); |
2216 context()->Plug(eax); | 2226 context()->Plug(eax); |
2217 } else { | 2227 } else { |
2218 VisitForStackValue(expr->obj()); | 2228 VisitForStackValue(expr->obj()); |
2219 VisitForAccumulatorValue(expr->key()); | 2229 VisitForAccumulatorValue(expr->key()); |
2220 __ pop(edx); | 2230 __ pop(edx); // Object. |
2231 __ mov(ecx, result_register()); // Key. | |
2232 if (FLAG_debug_code) { | |
2233 __ mov(result_register(), Immediate(0xbeefdeed)); // Zap eax. | |
2234 } | |
2221 EmitKeyedPropertyLoad(expr); | 2235 EmitKeyedPropertyLoad(expr); |
2222 context()->Plug(eax); | 2236 context()->Plug(eax); |
2223 } | 2237 } |
2224 } | 2238 } |
2225 | 2239 |
2226 | 2240 |
2227 void FullCodeGenerator::CallIC(Handle<Code> code, | 2241 void FullCodeGenerator::CallIC(Handle<Code> code, |
2228 RelocInfo::Mode rmode, | 2242 RelocInfo::Mode rmode, |
2229 unsigned ast_id) { | 2243 unsigned ast_id) { |
2230 ic_total_count_++; | 2244 ic_total_count_++; |
(...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4102 if (assign_type == VARIABLE) { | 4116 if (assign_type == VARIABLE) { |
4103 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); | 4117 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); |
4104 AccumulatorValueContext context(this); | 4118 AccumulatorValueContext context(this); |
4105 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4119 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
4106 } else { | 4120 } else { |
4107 // Reserve space for result of postfix operation. | 4121 // Reserve space for result of postfix operation. |
4108 if (expr->is_postfix() && !context()->IsEffect()) { | 4122 if (expr->is_postfix() && !context()->IsEffect()) { |
4109 __ push(Immediate(Smi::FromInt(0))); | 4123 __ push(Immediate(Smi::FromInt(0))); |
4110 } | 4124 } |
4111 if (assign_type == NAMED_PROPERTY) { | 4125 if (assign_type == NAMED_PROPERTY) { |
4112 // Put the object both on the stack and in the accumulator. | 4126 // Put the object both on the stack and in edx. |
4113 VisitForAccumulatorValue(prop->obj()); | 4127 VisitForAccumulatorValue(prop->obj()); |
4114 __ push(eax); | 4128 __ push(eax); |
4129 __ mov(edx, eax); | |
4130 if (FLAG_debug_code) { | |
4131 __ mov(result_register(), Immediate(0xbeefdeed)); // Zap eax. | |
4132 } | |
4115 EmitNamedPropertyLoad(prop); | 4133 EmitNamedPropertyLoad(prop); |
4116 } else { | 4134 } else { |
4117 VisitForStackValue(prop->obj()); | 4135 VisitForStackValue(prop->obj()); |
4118 VisitForAccumulatorValue(prop->key()); | 4136 VisitForAccumulatorValue(prop->key()); |
4119 __ mov(edx, Operand(esp, 0)); | 4137 __ mov(edx, Operand(esp, 0)); // Object. |
4120 __ push(eax); | 4138 __ push(eax); // Key (on stack). |
4139 __ mov(ecx, eax); // Key. | |
Yang
2012/04/27 12:47:12
This is similar to line 1176, except that eax gets
Jakob Kummerow
2012/04/27 13:01:24
No reason. Unified.
| |
4140 if (FLAG_debug_code) { | |
4141 __ mov(result_register(), Immediate(0xbeefdeed)); // Zap eax. | |
4142 } | |
4121 EmitKeyedPropertyLoad(prop); | 4143 EmitKeyedPropertyLoad(prop); |
4122 } | 4144 } |
4123 } | 4145 } |
4124 | 4146 |
4125 // We need a second deoptimization point after loading the value | 4147 // We need a second deoptimization point after loading the value |
4126 // in case evaluating the property load my have a side effect. | 4148 // in case evaluating the property load my have a side effect. |
4127 if (assign_type == VARIABLE) { | 4149 if (assign_type == VARIABLE) { |
4128 PrepareForBailout(expr->expression(), TOS_REG); | 4150 PrepareForBailout(expr->expression(), TOS_REG); |
4129 } else { | 4151 } else { |
4130 PrepareForBailoutForId(expr->CountId(), TOS_REG); | 4152 PrepareForBailoutForId(expr->CountId(), TOS_REG); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4257 } | 4279 } |
4258 | 4280 |
4259 | 4281 |
4260 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { | 4282 void FullCodeGenerator::VisitForTypeofValue(Expression* expr) { |
4261 VariableProxy* proxy = expr->AsVariableProxy(); | 4283 VariableProxy* proxy = expr->AsVariableProxy(); |
4262 ASSERT(!context()->IsEffect()); | 4284 ASSERT(!context()->IsEffect()); |
4263 ASSERT(!context()->IsTest()); | 4285 ASSERT(!context()->IsTest()); |
4264 | 4286 |
4265 if (proxy != NULL && proxy->var()->IsUnallocated()) { | 4287 if (proxy != NULL && proxy->var()->IsUnallocated()) { |
4266 Comment cmnt(masm_, "Global variable"); | 4288 Comment cmnt(masm_, "Global variable"); |
4267 __ mov(eax, GlobalObjectOperand()); | 4289 __ mov(edx, GlobalObjectOperand()); |
4268 __ mov(ecx, Immediate(proxy->name())); | 4290 __ mov(ecx, Immediate(proxy->name())); |
4269 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 4291 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
4270 // Use a regular load, not a contextual load, to avoid a reference | 4292 // Use a regular load, not a contextual load, to avoid a reference |
4271 // error. | 4293 // error. |
4272 CallIC(ic); | 4294 CallIC(ic); |
4273 PrepareForBailout(expr, TOS_REG); | 4295 PrepareForBailout(expr, TOS_REG); |
4274 context()->Plug(eax); | 4296 context()->Plug(eax); |
4275 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { | 4297 } else if (proxy != NULL && proxy->var()->IsLookupSlot()) { |
4276 Label done, slow; | 4298 Label done, slow; |
4277 | 4299 |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4602 *context_length = 0; | 4624 *context_length = 0; |
4603 return previous_; | 4625 return previous_; |
4604 } | 4626 } |
4605 | 4627 |
4606 | 4628 |
4607 #undef __ | 4629 #undef __ |
4608 | 4630 |
4609 } } // namespace v8::internal | 4631 } } // namespace v8::internal |
4610 | 4632 |
4611 #endif // V8_TARGET_ARCH_IA32 | 4633 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |