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/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/api-arguments.h" | 8 #include "src/api-arguments.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 3653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3664 } | 3664 } |
3665 | 3665 |
3666 void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 3666 void StoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
3667 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx | 3667 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx |
3668 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx | 3668 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx |
3669 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax | 3669 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax |
3670 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx | 3670 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx |
3671 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi | 3671 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi |
3672 Label miss; | 3672 Label miss; |
3673 | 3673 |
| 3674 if (StoreWithVectorDescriptor::kPassLastArgsOnStack) { |
| 3675 // Current stack layout: |
| 3676 // - esp[8] -- value |
| 3677 // - esp[4] -- slot |
| 3678 // - esp[0] -- return address |
| 3679 STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2); |
| 3680 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); |
| 3681 if (in_frame) { |
| 3682 __ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor"); |
| 3683 // If the vector is not on the stack, then insert the vector beneath |
| 3684 // return address in order to prepare for calling handler with |
| 3685 // StoreWithVector calling convention. |
| 3686 __ push(Operand(esp, 0)); |
| 3687 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister()); |
| 3688 __ RecordComment("]"); |
| 3689 } else { |
| 3690 __ mov(vector, Operand(esp, 1 * kPointerSize)); |
| 3691 } |
| 3692 __ mov(slot, Operand(esp, 2 * kPointerSize)); |
| 3693 __ mov(value, Operand(esp, 3 * kPointerSize)); |
| 3694 } |
| 3695 |
3674 __ push(value); | 3696 __ push(value); |
3675 | 3697 |
3676 Register scratch = value; | 3698 Register scratch = value; |
3677 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, | 3699 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, |
3678 FixedArray::kHeaderSize)); | 3700 FixedArray::kHeaderSize)); |
3679 | 3701 |
3680 // Is it a weak cell? | 3702 // Is it a weak cell? |
3681 Label try_array; | 3703 Label try_array; |
3682 Label not_array, smi_key, key_okay; | 3704 Label not_array, smi_key, key_okay; |
3683 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); | 3705 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3805 __ JumpIfSmi(cached_map, &pop_and_miss); | 3827 __ JumpIfSmi(cached_map, &pop_and_miss); |
3806 DCHECK(!cached_map.is(StoreTransitionDescriptor::MapRegister())); | 3828 DCHECK(!cached_map.is(StoreTransitionDescriptor::MapRegister())); |
3807 __ mov(StoreTransitionDescriptor::MapRegister(), cached_map); | 3829 __ mov(StoreTransitionDescriptor::MapRegister(), cached_map); |
3808 | 3830 |
3809 // Call store transition handler using StoreTransitionDescriptor calling | 3831 // Call store transition handler using StoreTransitionDescriptor calling |
3810 // convention. | 3832 // convention. |
3811 __ pop(key); | 3833 __ pop(key); |
3812 __ pop(vector); | 3834 __ pop(vector); |
3813 __ pop(receiver); | 3835 __ pop(receiver); |
3814 __ pop(value); | 3836 __ pop(value); |
3815 { | 3837 // Ensure that the transition handler we are going to call has the same |
3816 // Put vector and slot beneath return address. | 3838 // number of stack arguments which means that we don't have to adapt them |
3817 __ push(vector); | 3839 // before the call. |
3818 __ push(Operand(esp, 1 * kPointerSize)); // push return address | 3840 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); |
3819 __ mov(Operand(esp, 2 * kPointerSize), slot); | 3841 STATIC_ASSERT(StoreTransitionDescriptor::kStackArgumentsCount == 3); |
3820 } | 3842 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - |
| 3843 StoreWithVectorDescriptor::kValue == |
| 3844 StoreTransitionDescriptor::kParameterCount - |
| 3845 StoreTransitionDescriptor::kValue); |
| 3846 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - |
| 3847 StoreWithVectorDescriptor::kSlot == |
| 3848 StoreTransitionDescriptor::kParameterCount - |
| 3849 StoreTransitionDescriptor::kSlot); |
| 3850 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - |
| 3851 StoreWithVectorDescriptor::kVector == |
| 3852 StoreTransitionDescriptor::kParameterCount - |
| 3853 StoreTransitionDescriptor::kVector); |
3821 __ jmp(Operand::StaticVariable(virtual_register)); | 3854 __ jmp(Operand::StaticVariable(virtual_register)); |
3822 | 3855 |
3823 __ bind(&prepare_next); | 3856 __ bind(&prepare_next); |
3824 __ add(counter, Immediate(Smi::FromInt(3))); | 3857 __ add(counter, Immediate(Smi::FromInt(3))); |
3825 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); | 3858 __ cmp(counter, FieldOperand(feedback, FixedArray::kLengthOffset)); |
3826 __ j(less, &next_loop); | 3859 __ j(less, &next_loop); |
3827 | 3860 |
3828 // We exhausted our array of map handler pairs. | 3861 // We exhausted our array of map handler pairs. |
3829 __ bind(&pop_and_miss); | 3862 __ bind(&pop_and_miss); |
3830 __ pop(key); | 3863 __ pop(key); |
3831 __ pop(vector); | 3864 __ pop(vector); |
3832 __ pop(receiver); | 3865 __ pop(receiver); |
3833 __ jmp(miss); | 3866 __ jmp(miss); |
3834 | 3867 |
3835 __ bind(&load_smi_map); | 3868 __ bind(&load_smi_map); |
3836 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); | 3869 __ LoadRoot(receiver_map, Heap::kHeapNumberMapRootIndex); |
3837 __ jmp(&compare_map); | 3870 __ jmp(&compare_map); |
3838 } | 3871 } |
3839 | 3872 |
3840 void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { | 3873 void KeyedStoreICStub::GenerateImpl(MacroAssembler* masm, bool in_frame) { |
3841 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx | 3874 Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); // edx |
3842 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx | 3875 Register key = StoreWithVectorDescriptor::NameRegister(); // ecx |
3843 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax | 3876 Register value = StoreWithVectorDescriptor::ValueRegister(); // eax |
3844 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx | 3877 Register vector = StoreWithVectorDescriptor::VectorRegister(); // ebx |
3845 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi | 3878 Register slot = StoreWithVectorDescriptor::SlotRegister(); // edi |
3846 Label miss; | 3879 Label miss; |
3847 | 3880 |
| 3881 if (StoreWithVectorDescriptor::kPassLastArgsOnStack) { |
| 3882 // Current stack layout: |
| 3883 // - esp[8] -- value |
| 3884 // - esp[4] -- slot |
| 3885 // - esp[0] -- return address |
| 3886 STATIC_ASSERT(StoreDescriptor::kStackArgumentsCount == 2); |
| 3887 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 3); |
| 3888 if (in_frame) { |
| 3889 __ RecordComment("[ StoreDescriptor -> StoreWithVectorDescriptor"); |
| 3890 // If the vector is not on the stack, then insert the vector beneath |
| 3891 // return address in order to prepare for calling handler with |
| 3892 // StoreWithVector calling convention. |
| 3893 __ push(Operand(esp, 0)); |
| 3894 __ mov(Operand(esp, 4), StoreWithVectorDescriptor::VectorRegister()); |
| 3895 __ RecordComment("]"); |
| 3896 } else { |
| 3897 __ mov(vector, Operand(esp, 1 * kPointerSize)); |
| 3898 } |
| 3899 __ mov(slot, Operand(esp, 2 * kPointerSize)); |
| 3900 __ mov(value, Operand(esp, 3 * kPointerSize)); |
| 3901 } |
| 3902 |
3848 __ push(value); | 3903 __ push(value); |
3849 | 3904 |
3850 Register scratch = value; | 3905 Register scratch = value; |
3851 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, | 3906 __ mov(scratch, FieldOperand(vector, slot, times_half_pointer_size, |
3852 FixedArray::kHeaderSize)); | 3907 FixedArray::kHeaderSize)); |
3853 | 3908 |
3854 // Is it a weak cell? | 3909 // Is it a weak cell? |
3855 Label try_array; | 3910 Label try_array; |
3856 Label not_array, smi_key, key_okay; | 3911 Label not_array, smi_key, key_okay; |
3857 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); | 3912 __ CompareRoot(FieldOperand(scratch, 0), Heap::kWeakCellMapRootIndex); |
(...skipping 1599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5457 kStackUnwindSpace, nullptr, return_value_operand, | 5512 kStackUnwindSpace, nullptr, return_value_operand, |
5458 NULL); | 5513 NULL); |
5459 } | 5514 } |
5460 | 5515 |
5461 #undef __ | 5516 #undef __ |
5462 | 5517 |
5463 } // namespace internal | 5518 } // namespace internal |
5464 } // namespace v8 | 5519 } // namespace v8 |
5465 | 5520 |
5466 #endif // V8_TARGET_ARCH_IA32 | 5521 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |