OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3783 __ mov(eax, ebx); | 3783 __ mov(eax, ebx); |
3784 __ ret(0); | 3784 __ ret(0); |
3785 | 3785 |
3786 __ bind(&miss_force_generic); | 3786 __ bind(&miss_force_generic); |
3787 Handle<Code> miss_ic = | 3787 Handle<Code> miss_ic = |
3788 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | 3788 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
3789 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3789 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
3790 } | 3790 } |
3791 | 3791 |
3792 | 3792 |
| 3793 void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( |
| 3794 MacroAssembler* masm) { |
| 3795 // ----------- S t a t e ------------- |
| 3796 // -- eax : key |
| 3797 // -- edx : receiver |
| 3798 // -- esp[0] : return address |
| 3799 // ----------------------------------- |
| 3800 Label miss_force_generic, slow_allocate_heapnumber; |
| 3801 |
| 3802 // This stub is meant to be tail-jumped to, the receiver must already |
| 3803 // have been verified by the caller to not be a smi. |
| 3804 |
| 3805 // Check that the key is a smi. |
| 3806 __ JumpIfNotSmi(eax, &miss_force_generic); |
| 3807 |
| 3808 // Get the elements array. |
| 3809 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); |
| 3810 __ AssertFastElements(ecx); |
| 3811 |
| 3812 // Check that the key is within bounds. |
| 3813 __ cmp(eax, FieldOperand(ecx, FixedDoubleArray::kLengthOffset)); |
| 3814 __ j(above_equal, &miss_force_generic); |
| 3815 |
| 3816 // Check for the hole |
| 3817 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); |
| 3818 __ cmp(FieldOperand(ecx, eax, times_4, offset), Immediate(kHoleNanUpper32)); |
| 3819 __ j(equal, &miss_force_generic); |
| 3820 |
| 3821 // Always allocate a heap number for the result. |
| 3822 if (CpuFeatures::IsSupported(SSE2)) { |
| 3823 CpuFeatures::Scope use_sse2(SSE2); |
| 3824 __ movdbl(xmm0, FieldOperand(ecx, eax, times_4, |
| 3825 FixedDoubleArray::kHeaderSize)); |
| 3826 } else { |
| 3827 __ fld_d(FieldOperand(ecx, eax, times_4, FixedDoubleArray::kHeaderSize)); |
| 3828 } |
| 3829 __ AllocateHeapNumber(ecx, ebx, edi, &slow_allocate_heapnumber); |
| 3830 // Set the value. |
| 3831 if (CpuFeatures::IsSupported(SSE2)) { |
| 3832 CpuFeatures::Scope use_sse2(SSE2); |
| 3833 __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm0); |
| 3834 } else { |
| 3835 __ fstp_d(FieldOperand(ecx, HeapNumber::kValueOffset)); |
| 3836 } |
| 3837 __ mov(eax, ecx); |
| 3838 __ ret(0); |
| 3839 |
| 3840 __ bind(&slow_allocate_heapnumber); |
| 3841 // A value was pushed on the floating point stack before the allocation, if |
| 3842 // the allocation fails it needs to be removed. |
| 3843 if (!CpuFeatures::IsSupported(SSE2)) { |
| 3844 __ ffree(); |
| 3845 __ fincstp(); |
| 3846 } |
| 3847 Handle<Code> slow_ic = |
| 3848 masm->isolate()->builtins()->KeyedLoadIC_Slow(); |
| 3849 __ jmp(slow_ic, RelocInfo::CODE_TARGET); |
| 3850 |
| 3851 __ bind(&miss_force_generic); |
| 3852 Handle<Code> miss_ic = |
| 3853 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
| 3854 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
| 3855 } |
| 3856 |
| 3857 |
3793 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm, | 3858 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm, |
3794 bool is_js_array) { | 3859 bool is_js_array) { |
3795 // ----------- S t a t e ------------- | 3860 // ----------- S t a t e ------------- |
3796 // -- eax : value | 3861 // -- eax : value |
3797 // -- ecx : key | 3862 // -- ecx : key |
3798 // -- edx : receiver | 3863 // -- edx : receiver |
3799 // -- esp[0] : return address | 3864 // -- esp[0] : return address |
3800 // ----------------------------------- | 3865 // ----------------------------------- |
3801 Label miss_force_generic; | 3866 Label miss_force_generic; |
3802 | 3867 |
(...skipping 29 matching lines...) Expand all Loading... |
3832 __ ret(0); | 3897 __ ret(0); |
3833 | 3898 |
3834 // Handle store cache miss, replacing the ic with the generic stub. | 3899 // Handle store cache miss, replacing the ic with the generic stub. |
3835 __ bind(&miss_force_generic); | 3900 __ bind(&miss_force_generic); |
3836 Handle<Code> ic_force_generic = | 3901 Handle<Code> ic_force_generic = |
3837 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3902 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
3838 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 3903 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
3839 } | 3904 } |
3840 | 3905 |
3841 | 3906 |
| 3907 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( |
| 3908 MacroAssembler* masm, |
| 3909 bool is_js_array) { |
| 3910 // ----------- S t a t e ------------- |
| 3911 // -- eax : value |
| 3912 // -- ecx : key |
| 3913 // -- edx : receiver |
| 3914 // -- esp[0] : return address |
| 3915 // ----------------------------------- |
| 3916 Label miss_force_generic, smi_value, is_nan, maybe_nan; |
| 3917 Label have_double_value, not_nan; |
| 3918 |
| 3919 // This stub is meant to be tail-jumped to, the receiver must already |
| 3920 // have been verified by the caller to not be a smi. |
| 3921 |
| 3922 // Check that the key is a smi. |
| 3923 __ JumpIfNotSmi(ecx, &miss_force_generic); |
| 3924 |
| 3925 // Get the elements array. |
| 3926 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
| 3927 __ AssertFastElements(edi); |
| 3928 |
| 3929 if (is_js_array) { |
| 3930 // Check that the key is within bounds. |
| 3931 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. |
| 3932 } else { |
| 3933 // Check that the key is within bounds. |
| 3934 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. |
| 3935 } |
| 3936 __ j(above_equal, &miss_force_generic); |
| 3937 |
| 3938 __ JumpIfSmi(eax, &smi_value, Label::kNear); |
| 3939 |
| 3940 __ CheckMap(eax, |
| 3941 masm->isolate()->factory()->heap_number_map(), |
| 3942 &miss_force_generic, |
| 3943 DONT_DO_SMI_CHECK); |
| 3944 |
| 3945 // Double value, canonicalize NaN. |
| 3946 uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); |
| 3947 __ cmp(FieldOperand(eax, offset), Immediate(kNaNOrInfinityLowerBoundUpper32)); |
| 3948 __ j(greater_equal, &maybe_nan, Label::kNear); |
| 3949 |
| 3950 __ bind(¬_nan); |
| 3951 ExternalReference canonical_nan_reference = |
| 3952 ExternalReference::address_of_canonical_non_hole_nan(); |
| 3953 if (CpuFeatures::IsSupported(SSE2)) { |
| 3954 CpuFeatures::Scope use_sse2(SSE2); |
| 3955 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); |
| 3956 __ bind(&have_double_value); |
| 3957 __ movdbl(FieldOperand(edi, ecx, times_4, FixedDoubleArray::kHeaderSize), |
| 3958 xmm0); |
| 3959 __ ret(0); |
| 3960 } else { |
| 3961 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 3962 __ bind(&have_double_value); |
| 3963 __ fstp_d(FieldOperand(edi, ecx, times_4, FixedDoubleArray::kHeaderSize)); |
| 3964 __ ret(0); |
| 3965 } |
| 3966 |
| 3967 __ bind(&maybe_nan); |
| 3968 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise |
| 3969 // it's an Infinity, and the non-NaN code path applies. |
| 3970 __ j(greater, &is_nan, Label::kNear); |
| 3971 __ cmp(FieldOperand(eax, HeapNumber::kValueOffset), Immediate(0)); |
| 3972 __ j(zero, ¬_nan); |
| 3973 __ bind(&is_nan); |
| 3974 if (CpuFeatures::IsSupported(SSE2)) { |
| 3975 CpuFeatures::Scope use_sse2(SSE2); |
| 3976 __ movdbl(xmm0, Operand::StaticVariable(canonical_nan_reference)); |
| 3977 } else { |
| 3978 __ fld_d(Operand::StaticVariable(canonical_nan_reference)); |
| 3979 } |
| 3980 __ jmp(&have_double_value, Label::kNear); |
| 3981 |
| 3982 __ bind(&smi_value); |
| 3983 // Value is a smi. convert to a double and store. |
| 3984 __ SmiUntag(eax); |
| 3985 __ push(eax); |
| 3986 __ fild_s(Operand(esp, 0)); |
| 3987 __ pop(eax); |
| 3988 __ fstp_d(FieldOperand(edi, ecx, times_4, FixedDoubleArray::kHeaderSize)); |
| 3989 __ ret(0); |
| 3990 |
| 3991 // Handle store cache miss, replacing the ic with the generic stub. |
| 3992 __ bind(&miss_force_generic); |
| 3993 Handle<Code> ic_force_generic = |
| 3994 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| 3995 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
| 3996 } |
| 3997 |
| 3998 |
3842 #undef __ | 3999 #undef __ |
3843 | 4000 |
3844 } } // namespace v8::internal | 4001 } } // namespace v8::internal |
3845 | 4002 |
3846 #endif // V8_TARGET_ARCH_IA32 | 4003 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |