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_X87 | 5 #if V8_TARGET_ARCH_X87 |
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 1169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1180 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, | 1180 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy, |
1181 TypeofMode typeof_mode, | 1181 TypeofMode typeof_mode, |
1182 Label* slow) { | 1182 Label* slow) { |
1183 Register context = esi; | 1183 Register context = esi; |
1184 Register temp = edx; | 1184 Register temp = edx; |
1185 | 1185 |
1186 Scope* s = scope(); | 1186 Scope* s = scope(); |
1187 while (s != NULL) { | 1187 while (s != NULL) { |
1188 if (s->num_heap_slots() > 0) { | 1188 if (s->num_heap_slots() > 0) { |
1189 if (s->calls_sloppy_eval()) { | 1189 if (s->calls_sloppy_eval()) { |
1190 // Check that extension is NULL. | 1190 // Check that extension is "the hole". |
1191 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), | 1191 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX), |
1192 Immediate(0)); | 1192 Heap::kTheHoleValueRootIndex, slow); |
1193 __ j(not_equal, slow); | |
1194 } | 1193 } |
1195 // Load next context in chain. | 1194 // Load next context in chain. |
1196 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); | 1195 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); |
1197 // Walk the rest of the chain without clobbering esi. | 1196 // Walk the rest of the chain without clobbering esi. |
1198 context = temp; | 1197 context = temp; |
1199 } | 1198 } |
1200 // If no outer scope calls eval, we do not need to check more | 1199 // If no outer scope calls eval, we do not need to check more |
1201 // context extensions. If we have reached an eval scope, we check | 1200 // context extensions. If we have reached an eval scope, we check |
1202 // all extensions from this point. | 1201 // all extensions from this point. |
1203 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; | 1202 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; |
1204 s = s->outer_scope(); | 1203 s = s->outer_scope(); |
1205 } | 1204 } |
1206 | 1205 |
1207 if (s != NULL && s->is_eval_scope()) { | 1206 if (s != NULL && s->is_eval_scope()) { |
1208 // Loop up the context chain. There is no frame effect so it is | 1207 // Loop up the context chain. There is no frame effect so it is |
1209 // safe to use raw labels here. | 1208 // safe to use raw labels here. |
1210 Label next, fast; | 1209 Label next, fast; |
1211 if (!context.is(temp)) { | 1210 if (!context.is(temp)) { |
1212 __ mov(temp, context); | 1211 __ mov(temp, context); |
1213 } | 1212 } |
1214 __ bind(&next); | 1213 __ bind(&next); |
1215 // Terminate at native context. | 1214 // Terminate at native context. |
1216 __ cmp(FieldOperand(temp, HeapObject::kMapOffset), | 1215 __ cmp(FieldOperand(temp, HeapObject::kMapOffset), |
1217 Immediate(isolate()->factory()->native_context_map())); | 1216 Immediate(isolate()->factory()->native_context_map())); |
1218 __ j(equal, &fast, Label::kNear); | 1217 __ j(equal, &fast, Label::kNear); |
1219 // Check that extension is NULL. | 1218 // Check that extension is "the hole". |
1220 __ cmp(ContextOperand(temp, Context::EXTENSION_INDEX), Immediate(0)); | 1219 __ JumpIfNotRoot(ContextOperand(temp, Context::EXTENSION_INDEX), |
1221 __ j(not_equal, slow); | 1220 Heap::kTheHoleValueRootIndex, slow); |
1222 // Load next context in chain. | 1221 // Load next context in chain. |
1223 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); | 1222 __ mov(temp, ContextOperand(temp, Context::PREVIOUS_INDEX)); |
1224 __ jmp(&next); | 1223 __ jmp(&next); |
1225 __ bind(&fast); | 1224 __ bind(&fast); |
1226 } | 1225 } |
1227 | 1226 |
1228 // All extension objects were empty and it is safe to use a normal global | 1227 // All extension objects were empty and it is safe to use a normal global |
1229 // load machinery. | 1228 // load machinery. |
1230 EmitGlobalVariableLoad(proxy, typeof_mode); | 1229 EmitGlobalVariableLoad(proxy, typeof_mode); |
1231 } | 1230 } |
1232 | 1231 |
1233 | 1232 |
1234 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1233 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1235 Label* slow) { | 1234 Label* slow) { |
1236 DCHECK(var->IsContextSlot()); | 1235 DCHECK(var->IsContextSlot()); |
1237 Register context = esi; | 1236 Register context = esi; |
1238 Register temp = ebx; | 1237 Register temp = ebx; |
1239 | 1238 |
1240 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { | 1239 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { |
1241 if (s->num_heap_slots() > 0) { | 1240 if (s->num_heap_slots() > 0) { |
1242 if (s->calls_sloppy_eval()) { | 1241 if (s->calls_sloppy_eval()) { |
1243 // Check that extension is NULL. | 1242 // Check that extension is "the hole". |
1244 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), | 1243 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX), |
1245 Immediate(0)); | 1244 Heap::kTheHoleValueRootIndex, slow); |
1246 __ j(not_equal, slow); | |
1247 } | 1245 } |
1248 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); | 1246 __ mov(temp, ContextOperand(context, Context::PREVIOUS_INDEX)); |
1249 // Walk the rest of the chain without clobbering esi. | 1247 // Walk the rest of the chain without clobbering esi. |
1250 context = temp; | 1248 context = temp; |
1251 } | 1249 } |
1252 } | 1250 } |
1253 // Check that last extension is NULL. | 1251 // Check that last extension is "the hole". |
1254 __ cmp(ContextOperand(context, Context::EXTENSION_INDEX), Immediate(0)); | 1252 __ JumpIfNotRoot(ContextOperand(context, Context::EXTENSION_INDEX), |
1255 __ j(not_equal, slow); | 1253 Heap::kTheHoleValueRootIndex, slow); |
1256 | 1254 |
1257 // This function is used only for loads, not stores, so it's safe to | 1255 // This function is used only for loads, not stores, so it's safe to |
1258 // return an esi-based operand (the write barrier cannot be allowed to | 1256 // return an esi-based operand (the write barrier cannot be allowed to |
1259 // destroy the esi register). | 1257 // destroy the esi register). |
1260 return ContextOperand(context, var->index()); | 1258 return ContextOperand(context, var->index()); |
1261 } | 1259 } |
1262 | 1260 |
1263 | 1261 |
1264 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, | 1262 void FullCodeGenerator::EmitDynamicLookupFastCase(VariableProxy* proxy, |
1265 TypeofMode typeof_mode, | 1263 TypeofMode typeof_mode, |
(...skipping 3600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4866 Assembler::target_address_at(call_target_address, | 4864 Assembler::target_address_at(call_target_address, |
4867 unoptimized_code)); | 4865 unoptimized_code)); |
4868 return OSR_AFTER_STACK_CHECK; | 4866 return OSR_AFTER_STACK_CHECK; |
4869 } | 4867 } |
4870 | 4868 |
4871 | 4869 |
4872 } // namespace internal | 4870 } // namespace internal |
4873 } // namespace v8 | 4871 } // namespace v8 |
4874 | 4872 |
4875 #endif // V8_TARGET_ARCH_X87 | 4873 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |