| 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 3806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3817 __ mov(eax, ebx); | 3817 __ mov(eax, ebx); |
| 3818 __ ret(0); | 3818 __ ret(0); |
| 3819 | 3819 |
| 3820 __ bind(&miss_force_generic); | 3820 __ bind(&miss_force_generic); |
| 3821 Handle<Code> miss_ic = | 3821 Handle<Code> miss_ic = |
| 3822 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | 3822 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
| 3823 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3823 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
| 3824 } | 3824 } |
| 3825 | 3825 |
| 3826 | 3826 |
| 3827 void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( |
| 3828 MacroAssembler* masm) { |
| 3829 // ----------- S t a t e ------------- |
| 3830 // -- eax : key |
| 3831 // -- edx : receiver |
| 3832 // -- esp[0] : return address |
| 3833 // ----------------------------------- |
| 3834 Label miss_force_generic, slow_allocate_heapnumber; |
| 3835 |
| 3836 // This stub is meant to be tail-jumped to, the receiver must already |
| 3837 // have been verified by the caller to not be a smi. |
| 3838 |
| 3839 // Check that the key is a smi. |
| 3840 __ JumpIfNotSmi(eax, &miss_force_generic); |
| 3841 |
| 3842 // Get the elements array. |
| 3843 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); |
| 3844 __ AssertFastElements(ecx); |
| 3845 |
| 3846 // Check that the key is within bounds. |
| 3847 __ cmp(eax, FieldOperand(ecx, FixedDoubleArray::kLengthOffset)); |
| 3848 __ j(above_equal, &miss_force_generic); |
| 3849 |
| 3850 // Check for the hole |
| 3851 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); |
| 3852 __ cmp(FieldOperand(ecx, eax, times_4, offset), Immediate(kHoleNanUpper32)); |
| 3853 __ j(equal, &miss_force_generic); |
| 3854 |
| 3855 // Always allocate a heap number for the result. |
| 3856 if (CpuFeatures::IsSupported(SSE2)) { |
| 3857 CpuFeatures::Scope use_sse2(SSE2); |
| 3858 __ movdbl(xmm0, FieldOperand(ecx, eax, times_4, |
| 3859 FixedDoubleArray::kHeaderSize)); |
| 3860 } else { |
| 3861 __ fld_d(FieldOperand(ecx, eax, times_4, FixedDoubleArray::kHeaderSize)); |
| 3862 } |
| 3863 __ AllocateHeapNumber(ecx, ebx, edi, &slow_allocate_heapnumber); |
| 3864 // Set the value. |
| 3865 if (CpuFeatures::IsSupported(SSE2)) { |
| 3866 CpuFeatures::Scope use_sse2(SSE2); |
| 3867 __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm0); |
| 3868 } else { |
| 3869 __ fstp_d(FieldOperand(ecx, HeapNumber::kValueOffset)); |
| 3870 } |
| 3871 __ mov(eax, ecx); |
| 3872 __ ret(0); |
| 3873 |
| 3874 __ bind(&slow_allocate_heapnumber); |
| 3875 // A value was pushed on the floating point stack before the allocation, if |
| 3876 // the allocation fails it needs to be removed. |
| 3877 if (!CpuFeatures::IsSupported(SSE2)) { |
| 3878 __ ffree(); |
| 3879 __ fincstp(); |
| 3880 } |
| 3881 Handle<Code> slow_ic = |
| 3882 masm->isolate()->builtins()->KeyedLoadIC_Slow(); |
| 3883 __ jmp(slow_ic, RelocInfo::CODE_TARGET); |
| 3884 |
| 3885 __ bind(&miss_force_generic); |
| 3886 Handle<Code> miss_ic = |
| 3887 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
| 3888 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
| 3889 } |
| 3890 |
| 3891 |
| 3827 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm, | 3892 void KeyedStoreStubCompiler::GenerateStoreFastElement(MacroAssembler* masm, |
| 3828 bool is_js_array) { | 3893 bool is_js_array) { |
| 3829 // ----------- S t a t e ------------- | 3894 // ----------- S t a t e ------------- |
| 3830 // -- eax : value | 3895 // -- eax : value |
| 3831 // -- ecx : key | 3896 // -- ecx : key |
| 3832 // -- edx : receiver | 3897 // -- edx : receiver |
| 3833 // -- esp[0] : return address | 3898 // -- esp[0] : return address |
| 3834 // ----------------------------------- | 3899 // ----------------------------------- |
| 3835 Label miss_force_generic; | 3900 Label miss_force_generic; |
| 3836 | 3901 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3867 __ ret(0); | 3932 __ ret(0); |
| 3868 | 3933 |
| 3869 // Handle store cache miss, replacing the ic with the generic stub. | 3934 // Handle store cache miss, replacing the ic with the generic stub. |
| 3870 __ bind(&miss_force_generic); | 3935 __ bind(&miss_force_generic); |
| 3871 Handle<Code> ic_force_generic = | 3936 Handle<Code> ic_force_generic = |
| 3872 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3937 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| 3873 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 3938 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
| 3874 } | 3939 } |
| 3875 | 3940 |
| 3876 | 3941 |
| 3942 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( |
| 3943 MacroAssembler* masm, |
| 3944 bool is_js_array) { |
| 3945 // ----------- S t a t e ------------- |
| 3946 // -- eax : value |
| 3947 // -- ecx : key |
| 3948 // -- edx : receiver |
| 3949 // -- esp[0] : return address |
| 3950 // ----------------------------------- |
| 3951 Label miss_force_generic, smi_value, is_nan, maybe_nan; |
| 3952 Label have_double_value, not_nan; |
| 3953 |
| 3954 // This stub is meant to be tail-jumped to, the receiver must already |
| 3955 // have been verified by the caller to not be a smi. |
| 3956 |
| 3957 // Check that the key is a smi. |
| 3958 __ JumpIfNotSmi(ecx, &miss_force_generic); |
| 3959 |
| 3960 // Get the elements array. |
| 3961 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); |
| 3962 __ AssertFastElements(edi); |
| 3963 |
| 3964 if (is_js_array) { |
| 3965 // Check that the key is within bounds. |
| 3966 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. |
| 3967 } else { |
| 3968 // Check that the key is within bounds. |
| 3969 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis. |
| 3970 } |
| 3971 __ j(above_equal, &miss_force_generic); |
| 3972 |
| 3973 __ JumpIfSmi(eax, &smi_value, Label::kNear); |
| 3974 |
| 3975 __ CheckMap(eax, |
| 3976 masm->isolate()->factory()->heap_number_map(), |
| 3977 &miss_force_generic, |
| 3978 DONT_DO_SMI_CHECK); |
| 3979 |
| 3980 // Double value, canonicalize NaN. |
| 3981 uint32_t offset = HeapNumber::kValueOffset + sizeof(kHoleNanLower32); |
| 3982 __ cmp(FieldOperand(eax, offset), Immediate(kNaNOrInfinityLowerBoundUpper32)); |
| 3983 __ j(greater_equal, &maybe_nan, Label::kNear); |
| 3984 |
| 3985 __ bind(¬_nan); |
| 3986 ExternalReference canonical_nan_reference = |
| 3987 ExternalReference::address_of_canonical_non_hole_nan(); |
| 3988 if (CpuFeatures::IsSupported(SSE2)) { |
| 3989 CpuFeatures::Scope use_sse2(SSE2); |
| 3990 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); |
| 3991 __ bind(&have_double_value); |
| 3992 __ movdbl(FieldOperand(edi, ecx, times_4, FixedDoubleArray::kHeaderSize), |
| 3993 xmm0); |
| 3994 __ ret(0); |
| 3995 } else { |
| 3996 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
| 3997 __ bind(&have_double_value); |
| 3998 __ fstp_d(FieldOperand(edi, ecx, times_4, FixedDoubleArray::kHeaderSize)); |
| 3999 __ ret(0); |
| 4000 } |
| 4001 |
| 4002 __ bind(&maybe_nan); |
| 4003 // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise |
| 4004 // it's an Infinity, and the non-NaN code path applies. |
| 4005 __ j(greater, &is_nan, Label::kNear); |
| 4006 __ cmp(FieldOperand(eax, HeapNumber::kValueOffset), Immediate(0)); |
| 4007 __ j(zero, ¬_nan); |
| 4008 __ bind(&is_nan); |
| 4009 if (CpuFeatures::IsSupported(SSE2)) { |
| 4010 CpuFeatures::Scope use_sse2(SSE2); |
| 4011 __ movdbl(xmm0, Operand::StaticVariable(canonical_nan_reference)); |
| 4012 } else { |
| 4013 __ fld_d(Operand::StaticVariable(canonical_nan_reference)); |
| 4014 } |
| 4015 __ jmp(&have_double_value, Label::kNear); |
| 4016 |
| 4017 __ bind(&smi_value); |
| 4018 // Value is a smi. convert to a double and store. |
| 4019 __ SmiUntag(eax); |
| 4020 __ push(eax); |
| 4021 __ fild_s(Operand(esp, 0)); |
| 4022 __ pop(eax); |
| 4023 __ fstp_d(FieldOperand(edi, ecx, times_4, FixedDoubleArray::kHeaderSize)); |
| 4024 __ ret(0); |
| 4025 |
| 4026 // Handle store cache miss, replacing the ic with the generic stub. |
| 4027 __ bind(&miss_force_generic); |
| 4028 Handle<Code> ic_force_generic = |
| 4029 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
| 4030 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
| 4031 } |
| 4032 |
| 4033 |
| 3877 #undef __ | 4034 #undef __ |
| 3878 | 4035 |
| 3879 } } // namespace v8::internal | 4036 } } // namespace v8::internal |
| 3880 | 4037 |
| 3881 #endif // V8_TARGET_ARCH_IA32 | 4038 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |