OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1188 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1189 TypeofMode typeof_mode, | 1189 TypeofMode typeof_mode, |
1190 Label* slow) { | 1190 Label* slow) { |
1191 Register context = esi; | 1191 Register context = esi; |
1192 Register temp = edx; | 1192 Register temp = edx; |
1193 | 1193 |
1194 Scope* s = scope(); | 1194 Scope* s = scope(); |
1195 while (s != NULL) { | 1195 while (s != NULL) { |
1196 if (s->num_heap_slots() > 0) { | 1196 if (s->num_heap_slots() > 0) { |
1197 if (s->calls_sloppy_eval()) { | 1197 if (s->calls_sloppy_eval()) { |
1198 // Check that extension is NULL. | 1198 // Check that extension is "the hole". |
1199 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), | 1199 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX), |
1200 Immediate(0)); | 1200 Heap::kTheHoleValueRootIndex, slow); |
1201 __ j(not_equal, slow); | |
1202 } | 1201 } |
1203 // Load next context in chain. | 1202 // Load next context in chain. |
1204 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); | 1203 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); |
1205 // Walk the rest of the chain without clobbering esi. | 1204 // Walk the rest of the chain without clobbering esi. |
1206 context = temp; | 1205 context = temp; |
1207 } | 1206 } |
1208 // If no outer scope calls eval, we do not need to check more | 1207 // If no outer scope calls eval, we do not need to check more |
1209 // context extensions. If we have reached an eval scope, we check | 1208 // context extensions. If we have reached an eval scope, we check |
1210 // all extensions from this point. | 1209 // all extensions from this point. |
1211 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; | 1210 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; |
1212 s = s->outer_scope(); | 1211 s = s->outer_scope(); |
1213 } | 1212 } |
1214 | 1213 |
1215 if (s != NULL && s->is_eval_scope()) { | 1214 if (s != NULL && s->is_eval_scope()) { |
1216 // Loop up the context chain. There is no frame effect so it is | 1215 // Loop up the context chain. There is no frame effect so it is |
1217 // safe to use raw labels here. | 1216 // safe to use raw labels here. |
1218 Label next, fast; | 1217 Label next, fast; |
1219 if (!context.is(temp)) { | 1218 if (!context.is(temp)) { |
1220 __ mov(temp, context); | 1219 __ mov(temp, context); |
1221 } | 1220 } |
1222 __ bind(&next); | 1221 __ bind(&next); |
1223 // Terminate at native context. | 1222 // Terminate at native context. |
1224 __ cmp(FieldOperand(temp, HeapObject::kMapOffset), | 1223 __ cmp(FieldOperand(temp, HeapObject::kMapOffset), |
1225 Immediate(isolate()->factory()->native_context_map())); | 1224 Immediate(isolate()->factory()->native_context_map())); |
1226 __ j(equal, &fast, Label::kNear); | 1225 __ j(equal, &fast, Label::kNear); |
1227 // Check that extension is NULL. | 1226 // Check that extension is "the hole". |
1228 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); | 1227 __ JumpIfNotRoot(ContextOperand(temp, Context::EXTENSION_INDEX), |
1229 __ j(not_equal, slow); | 1228 Heap::kTheHoleValueRootIndex, slow); |
1230 // Load next context in chain. | 1229 // Load next context in chain. |
1231 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1230 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
1232 __ jmp(&next); | 1231 __ jmp(&next); |
1233 __ bind(&fast); | 1232 __ bind(&fast); |
1234 } | 1233 } |
1235 | 1234 |
1236 // All extension objects were empty and it is safe to use a normal global | 1235 // All extension objects were empty and it is safe to use a normal global |
1237 // load machinery. | 1236 // load machinery. |
1238 EmitGlobalVariableLoad(proxy, typeof_mode); | 1237 EmitGlobalVariableLoad(proxy, typeof_mode); |
1239 } | 1238 } |
1240 | 1239 |
1241 | 1240 |
1242 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1241 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1243 Label* slow) { | 1242 Label* slow) { |
1244 DCHECK(var->IsContextSlot()); | 1243 DCHECK(var->IsContextSlot()); |
1245 Register context = esi; | 1244 Register context = esi; |
1246 Register temp = ebx; | 1245 Register temp = ebx; |
1247 | 1246 |
1248 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { | 1247 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { |
1249 if (s->num_heap_slots() > 0) { | 1248 if (s->num_heap_slots() > 0) { |
1250 if (s->calls_sloppy_eval()) { | 1249 if (s->calls_sloppy_eval()) { |
1251 // Check that extension is NULL. | 1250 // Check that extension is "the hole". |
1252 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), | 1251 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX), |
1253 Immediate(0)); | 1252 Heap::kTheHoleValueRootIndex, slow); |
1254 __ j(not_equal, slow); | |
1255 } | 1253 } |
1256 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); | 1254 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); |
1257 // Walk the rest of the chain without clobbering esi. | 1255 // Walk the rest of the chain without clobbering esi. |
1258 context = temp; | 1256 context = temp; |
1259 } | 1257 } |
1260 } | 1258 } |
1261 // Check that last extension is NULL. | 1259 // Check that last extension is "the hole". |
1262 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0)); | 1260 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX), |
1263 __ j(not_equal, slow); | 1261 Heap::kTheHoleValueRootIndex, slow); |
1264 | 1262 |
1265 // This function is used only for loads, not stores, so it's safe to | 1263 // This function is used only for loads, not stores, so it's safe to |
1266 // return an esi-based operand (the write barrier cannot be allowed to | 1264 // return an esi-based operand (the write barrier cannot be allowed to |
1267 // destroy the esi register). | 1265 // destroy the esi register). |
1268 return ContextOperand(context, var->index()); | 1266 return ContextOperand(context, var->index()); |
1269 } | 1267 } |
1270 | 1268 |
1271 | 1269 |
1272 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, | 1270 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, |
1273 TypeofMode typeof_mode, | 1271 TypeofMode typeof_mode, |
(...skipping 3600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4874 Assembler::target_address_at(call_target_address, | 4872 Assembler::target_address_at(call_target_address, |
4875 unoptimized_code)); | 4873 unoptimized_code)); |
4876 return OSR_AFTER_STACK_CHECK; | 4874 return OSR_AFTER_STACK_CHECK; |
4877 } | 4875 } |
4878 | 4876 |
4879 | 4877 |
4880 } // namespace internal | 4878 } // namespace internal |
4881 } // namespace v8 | 4879 } // namespace v8 |
4882 | 4880 |
4883 #endif // V8_TARGET_ARCH_IA32 | 4881 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |