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/codegen.h" | 7 #include "src/codegen.h" |
8 #include "src/ic/ic.h" | 8 #include "src/ic/ic.h" |
9 #include "src/ic/ic-compiler.h" | 9 #include "src/ic/ic-compiler.h" |
10 #include "src/ic/stub-cache.h" | 10 #include "src/ic/stub-cache.h" |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 // Smi stores don't require further checks. | 402 // Smi stores don't require further checks. |
403 Label non_smi_value; | 403 Label non_smi_value; |
404 __ JumpIfNotSmi(value, &non_smi_value); | 404 __ JumpIfNotSmi(value, &non_smi_value); |
405 if (increment_length == kIncrementLength) { | 405 if (increment_length == kIncrementLength) { |
406 // Add 1 to receiver->length. | 406 // Add 1 to receiver->length. |
407 __ add(FieldOperand(receiver, JSArray::kLengthOffset), | 407 __ add(FieldOperand(receiver, JSArray::kLengthOffset), |
408 Immediate(Smi::FromInt(1))); | 408 Immediate(Smi::FromInt(1))); |
409 } | 409 } |
410 // It's irrelevant whether array is smi-only or not when writing a smi. | 410 // It's irrelevant whether array is smi-only or not when writing a smi. |
411 __ mov(FixedArrayElementOperand(ebx, key), value); | 411 __ mov(FixedArrayElementOperand(ebx, key), value); |
412 __ ret(0); | 412 __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize); |
413 | 413 |
414 __ bind(&non_smi_value); | 414 __ bind(&non_smi_value); |
415 // Escape to elements kind transition case. | 415 // Escape to elements kind transition case. |
416 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); | 416 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); |
417 __ CheckFastObjectElements(edi, &transition_smi_elements); | 417 __ CheckFastObjectElements(edi, &transition_smi_elements); |
418 | 418 |
419 // Fast elements array, store the value to the elements backing store. | 419 // Fast elements array, store the value to the elements backing store. |
420 __ bind(&finish_object_store); | 420 __ bind(&finish_object_store); |
421 if (increment_length == kIncrementLength) { | 421 if (increment_length == kIncrementLength) { |
422 // Add 1 to receiver->length. | 422 // Add 1 to receiver->length. |
423 __ add(FieldOperand(receiver, JSArray::kLengthOffset), | 423 __ add(FieldOperand(receiver, JSArray::kLengthOffset), |
424 Immediate(Smi::FromInt(1))); | 424 Immediate(Smi::FromInt(1))); |
425 } | 425 } |
426 __ mov(FixedArrayElementOperand(ebx, key), value); | 426 __ mov(FixedArrayElementOperand(ebx, key), value); |
427 // Update write barrier for the elements array address. | 427 // Update write barrier for the elements array address. |
428 __ mov(edx, value); // Preserve the value which is returned. | 428 __ mov(edx, value); // Preserve the value which is returned. |
429 __ RecordWriteArray(ebx, edx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET, | 429 __ RecordWriteArray(ebx, edx, key, kDontSaveFPRegs, EMIT_REMEMBERED_SET, |
430 OMIT_SMI_CHECK); | 430 OMIT_SMI_CHECK); |
431 __ ret(0); | 431 __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize); |
432 | 432 |
433 __ bind(fast_double); | 433 __ bind(fast_double); |
434 if (check_map == kCheckMap) { | 434 if (check_map == kCheckMap) { |
435 // Check for fast double array case. If this fails, call through to the | 435 // Check for fast double array case. If this fails, call through to the |
436 // runtime. | 436 // runtime. |
437 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map()); | 437 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map()); |
438 __ j(not_equal, slow); | 438 __ j(not_equal, slow); |
439 // If the value is a number, store it as a double in the FastDoubleElements | 439 // If the value is a number, store it as a double in the FastDoubleElements |
440 // array. | 440 // array. |
441 } | 441 } |
442 | 442 |
443 // HOLECHECK: guards "A[i] double hole?" | 443 // HOLECHECK: guards "A[i] double hole?" |
444 // We have to see if the double version of the hole is present. If so | 444 // We have to see if the double version of the hole is present. If so |
445 // go to the runtime. | 445 // go to the runtime. |
446 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); | 446 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); |
447 __ cmp(FieldOperand(ebx, key, times_4, offset), Immediate(kHoleNanUpper32)); | 447 __ cmp(FieldOperand(ebx, key, times_4, offset), Immediate(kHoleNanUpper32)); |
448 __ j(not_equal, &fast_double_without_map_check); | 448 __ j(not_equal, &fast_double_without_map_check); |
449 __ JumpIfDictionaryInPrototypeChain(receiver, ebx, edi, slow); | 449 __ JumpIfDictionaryInPrototypeChain(receiver, ebx, edi, slow); |
450 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); | 450 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); |
451 | 451 |
452 __ bind(&fast_double_without_map_check); | 452 __ bind(&fast_double_without_map_check); |
453 __ StoreNumberToDoubleElements(value, ebx, key, edi, xmm0, | 453 __ StoreNumberToDoubleElements(value, ebx, key, edi, xmm0, |
454 &transition_double_elements); | 454 &transition_double_elements); |
455 if (increment_length == kIncrementLength) { | 455 if (increment_length == kIncrementLength) { |
456 // Add 1 to receiver->length. | 456 // Add 1 to receiver->length. |
457 __ add(FieldOperand(receiver, JSArray::kLengthOffset), | 457 __ add(FieldOperand(receiver, JSArray::kLengthOffset), |
458 Immediate(Smi::FromInt(1))); | 458 Immediate(Smi::FromInt(1))); |
459 } | 459 } |
460 __ ret(0); | 460 __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize); |
461 | 461 |
462 __ bind(&transition_smi_elements); | 462 __ bind(&transition_smi_elements); |
463 __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset)); | 463 __ mov(ebx, FieldOperand(receiver, HeapObject::kMapOffset)); |
464 | 464 |
465 // Transition the array appropriately depending on the value type. | 465 // Transition the array appropriately depending on the value type. |
466 __ CheckMap(value, masm->isolate()->factory()->heap_number_map(), | 466 __ CheckMap(value, masm->isolate()->factory()->heap_number_map(), |
467 &non_double_value, DONT_DO_SMI_CHECK); | 467 &non_double_value, DONT_DO_SMI_CHECK); |
468 | 468 |
469 // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS | 469 // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS |
470 // and complete the store. | 470 // and complete the store. |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
698 __ pop(ebx); | 698 __ pop(ebx); |
699 __ push(receiver); | 699 __ push(receiver); |
700 __ push(name); | 700 __ push(name); |
701 __ push(ebx); | 701 __ push(ebx); |
702 | 702 |
703 // Do tail-call to runtime routine. | 703 // Do tail-call to runtime routine. |
704 __ TailCallRuntime(Runtime::kKeyedGetProperty); | 704 __ TailCallRuntime(Runtime::kKeyedGetProperty); |
705 } | 705 } |
706 | 706 |
707 static void StoreIC_PushArgs(MacroAssembler* masm) { | 707 static void StoreIC_PushArgs(MacroAssembler* masm) { |
708 Register receiver = StoreDescriptor::ReceiverRegister(); | 708 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); |
709 Register name = StoreDescriptor::NameRegister(); | 709 Register name = StoreWithVectorDescriptor::NameRegister(); |
710 Register value = StoreDescriptor::ValueRegister(); | |
711 Register slot = StoreWithVectorDescriptor::SlotRegister(); | |
712 Register vector = StoreWithVectorDescriptor::VectorRegister(); | |
713 | 710 |
714 __ xchg(value, Operand(esp, 0)); | 711 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); |
715 __ push(slot); | 712 // Current stack layout: |
716 __ push(vector); | 713 // - esp[12] -- value |
| 714 // - esp[8] -- slot |
| 715 // - esp[4] -- vector |
| 716 // - esp[0] -- return address |
| 717 |
| 718 Register return_address = StoreWithVectorDescriptor::SlotRegister(); |
| 719 __ pop(return_address); |
717 __ push(receiver); | 720 __ push(receiver); |
718 __ push(name); | 721 __ push(name); |
719 __ push(value); // Contains the return address. | 722 __ push(return_address); |
720 } | 723 } |
721 | 724 |
722 | 725 |
723 void StoreIC::GenerateMiss(MacroAssembler* masm) { | 726 void StoreIC::GenerateMiss(MacroAssembler* masm) { |
724 // Return address is on the stack. | 727 // Return address is on the stack. |
725 StoreIC_PushArgs(masm); | 728 StoreIC_PushArgs(masm); |
726 | 729 |
727 // Perform tail call to the entry. | 730 // Perform tail call to the entry. |
728 __ TailCallRuntime(Runtime::kStoreIC_Miss); | 731 __ TailCallRuntime(Runtime::kStoreIC_Miss); |
729 } | 732 } |
(...skipping 14 matching lines...) Expand all Loading... |
744 __ push(vector); | 747 __ push(vector); |
745 __ push(slot); | 748 __ push(slot); |
746 | 749 |
747 Register dictionary = ebx; | 750 Register dictionary = ebx; |
748 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 751 __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); |
749 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, | 752 GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, |
750 receiver, edi); | 753 receiver, edi); |
751 __ Drop(3); | 754 __ Drop(3); |
752 Counters* counters = masm->isolate()->counters(); | 755 Counters* counters = masm->isolate()->counters(); |
753 __ IncrementCounter(counters->ic_store_normal_hit(), 1); | 756 __ IncrementCounter(counters->ic_store_normal_hit(), 1); |
754 __ ret(0); | 757 __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize); |
755 | 758 |
756 __ bind(&restore_miss); | 759 __ bind(&restore_miss); |
757 __ pop(slot); | 760 __ pop(slot); |
758 __ pop(vector); | 761 __ pop(vector); |
759 __ pop(receiver); | 762 __ pop(receiver); |
760 __ IncrementCounter(counters->ic_store_normal_miss(), 1); | 763 __ IncrementCounter(counters->ic_store_normal_miss(), 1); |
761 GenerateMiss(masm); | 764 GenerateMiss(masm); |
762 } | 765 } |
763 | 766 |
764 | 767 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 Condition cc = | 850 Condition cc = |
848 (check == ENABLE_INLINED_SMI_CHECK) | 851 (check == ENABLE_INLINED_SMI_CHECK) |
849 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 852 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
850 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 853 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
851 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 854 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
852 } | 855 } |
853 } // namespace internal | 856 } // namespace internal |
854 } // namespace v8 | 857 } // namespace v8 |
855 | 858 |
856 #endif // V8_TARGET_ARCH_IA32 | 859 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |