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 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 // bit test is enough. | 256 // bit test is enough. |
257 STATIC_ASSERT(kNotInternalizedTag != 0); | 257 STATIC_ASSERT(kNotInternalizedTag != 0); |
258 __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), | 258 __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), |
259 kIsNotInternalizedMask); | 259 kIsNotInternalizedMask); |
260 __ j(not_zero, not_unique); | 260 __ j(not_zero, not_unique); |
261 | 261 |
262 __ bind(&unique); | 262 __ bind(&unique); |
263 } | 263 } |
264 | 264 |
265 | 265 |
266 static Operand GenerateMappedArgumentsLookup( | |
267 MacroAssembler* masm, Register object, Register key, Register scratch1, | |
268 Register scratch2, Label* unmapped_case, Label* slow_case) { | |
269 Heap* heap = masm->isolate()->heap(); | |
270 Factory* factory = masm->isolate()->factory(); | |
271 | |
272 // Check that the receiver is a JSObject. Because of the elements | |
273 // map check later, we do not need to check for interceptors or | |
274 // whether it requires access checks. | |
275 __ JumpIfSmi(object, slow_case); | |
276 // Check that the object is some kind of JSObject. | |
277 __ CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, scratch1); | |
278 __ j(below, slow_case); | |
279 | |
280 // Check that the key is a positive smi. | |
281 __ test(key, Immediate(0x80000001)); | |
282 __ j(not_zero, slow_case); | |
283 | |
284 // Load the elements into scratch1 and check its map. | |
285 Handle<Map> arguments_map(heap->sloppy_arguments_elements_map()); | |
286 __ mov(scratch1, FieldOperand(object, JSObject::kElementsOffset)); | |
287 __ CheckMap(scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK); | |
288 | |
289 // Check if element is in the range of mapped arguments. If not, jump | |
290 // to the unmapped lookup with the parameter map in scratch1. | |
291 __ mov(scratch2, FieldOperand(scratch1, FixedArray::kLengthOffset)); | |
292 __ sub(scratch2, Immediate(Smi::FromInt(2))); | |
293 __ cmp(key, scratch2); | |
294 __ j(above_equal, unmapped_case); | |
295 | |
296 // Load element index and check whether it is the hole. | |
297 const int kHeaderSize = FixedArray::kHeaderSize + 2 * kPointerSize; | |
298 __ mov(scratch2, | |
299 FieldOperand(scratch1, key, times_half_pointer_size, kHeaderSize)); | |
300 __ cmp(scratch2, factory->the_hole_value()); | |
301 __ j(equal, unmapped_case); | |
302 | |
303 // Load value from context and return it. We can reuse scratch1 because | |
304 // we do not jump to the unmapped lookup (which requires the parameter | |
305 // map in scratch1). | |
306 const int kContextOffset = FixedArray::kHeaderSize; | |
307 __ mov(scratch1, FieldOperand(scratch1, kContextOffset)); | |
308 return FieldOperand(scratch1, scratch2, times_half_pointer_size, | |
309 Context::kHeaderSize); | |
310 } | |
311 | |
312 | |
313 static Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm, | |
314 Register key, | |
315 Register parameter_map, | |
316 Register scratch, | |
317 Label* slow_case) { | |
318 // Element is in arguments backing store, which is referenced by the | |
319 // second element of the parameter_map. | |
320 const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize; | |
321 Register backing_store = parameter_map; | |
322 __ mov(backing_store, FieldOperand(parameter_map, kBackingStoreOffset)); | |
323 Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map()); | |
324 __ CheckMap(backing_store, fixed_array_map, slow_case, DONT_DO_SMI_CHECK); | |
325 __ mov(scratch, FieldOperand(backing_store, FixedArray::kLengthOffset)); | |
326 __ cmp(key, scratch); | |
327 __ j(greater_equal, slow_case); | |
328 return FieldOperand(backing_store, key, times_half_pointer_size, | |
329 FixedArray::kHeaderSize); | |
330 } | |
331 | |
332 | |
333 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 266 void KeyedLoadIC::GenerateMegamorphic(MacroAssembler* masm) { |
334 // The return address is on the stack. | 267 // The return address is on the stack. |
335 Label slow, check_name, index_smi, index_name, property_array_property; | 268 Label slow, check_name, index_smi, index_name, property_array_property; |
336 Label probe_dictionary, check_number_dictionary; | 269 Label probe_dictionary, check_number_dictionary; |
337 | 270 |
338 Register receiver = LoadDescriptor::ReceiverRegister(); | 271 Register receiver = LoadDescriptor::ReceiverRegister(); |
339 Register key = LoadDescriptor::NameRegister(); | 272 Register key = LoadDescriptor::NameRegister(); |
340 DCHECK(receiver.is(edx)); | 273 DCHECK(receiver.is(edx)); |
341 DCHECK(key.is(ecx)); | 274 DCHECK(key.is(ecx)); |
342 | 275 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); | 363 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); |
431 __ ret(0); | 364 __ ret(0); |
432 | 365 |
433 __ bind(&index_name); | 366 __ bind(&index_name); |
434 __ IndexFromHash(ebx, key); | 367 __ IndexFromHash(ebx, key); |
435 // Now jump to the place where smi keys are handled. | 368 // Now jump to the place where smi keys are handled. |
436 __ jmp(&index_smi); | 369 __ jmp(&index_smi); |
437 } | 370 } |
438 | 371 |
439 | 372 |
440 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | |
441 // Return address is on the stack. | |
442 Label slow, notin; | |
443 Register receiver = StoreDescriptor::ReceiverRegister(); | |
444 Register name = StoreDescriptor::NameRegister(); | |
445 Register value = StoreDescriptor::ValueRegister(); | |
446 DCHECK(receiver.is(edx)); | |
447 DCHECK(name.is(ecx)); | |
448 DCHECK(value.is(eax)); | |
449 | |
450 Operand mapped_location = GenerateMappedArgumentsLookup( | |
451 masm, receiver, name, ebx, edi, ¬in, &slow); | |
452 __ mov(mapped_location, value); | |
453 __ lea(ecx, mapped_location); | |
454 __ mov(edx, value); | |
455 __ RecordWrite(ebx, ecx, edx, kDontSaveFPRegs); | |
456 __ Ret(); | |
457 __ bind(¬in); | |
458 // The unmapped lookup expects that the parameter map is in ebx. | |
459 Operand unmapped_location = | |
460 GenerateUnmappedArgumentsLookup(masm, name, ebx, edi, &slow); | |
461 __ mov(unmapped_location, value); | |
462 __ lea(edi, unmapped_location); | |
463 __ mov(edx, value); | |
464 __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs); | |
465 __ Ret(); | |
466 __ bind(&slow); | |
467 GenerateMiss(masm); | |
468 } | |
469 | |
470 | |
471 static void KeyedStoreGenerateMegamorphicHelper( | 373 static void KeyedStoreGenerateMegamorphicHelper( |
472 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, | 374 MacroAssembler* masm, Label* fast_object, Label* fast_double, Label* slow, |
473 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { | 375 KeyedStoreCheckMap check_map, KeyedStoreIncrementLength increment_length) { |
474 Label transition_smi_elements; | 376 Label transition_smi_elements; |
475 Label finish_object_store, non_double_value, transition_double_elements; | 377 Label finish_object_store, non_double_value, transition_double_elements; |
476 Label fast_double_without_map_check; | 378 Label fast_double_without_map_check; |
477 Register receiver = StoreDescriptor::ReceiverRegister(); | 379 Register receiver = StoreDescriptor::ReceiverRegister(); |
478 Register key = StoreDescriptor::NameRegister(); | 380 Register key = StoreDescriptor::NameRegister(); |
479 Register value = StoreDescriptor::ValueRegister(); | 381 Register value = StoreDescriptor::ValueRegister(); |
480 DCHECK(receiver.is(edx)); | 382 DCHECK(receiver.is(edx)); |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 Condition cc = | 848 Condition cc = |
947 (check == ENABLE_INLINED_SMI_CHECK) | 849 (check == ENABLE_INLINED_SMI_CHECK) |
948 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 850 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
949 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 851 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
950 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 852 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
951 } | 853 } |
952 } | 854 } |
953 } // namespace v8::internal | 855 } // namespace v8::internal |
954 | 856 |
955 #endif // V8_TARGET_ARCH_IA32 | 857 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |