Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(724)

Side by Side Diff: src/arm/stub-cache-arm.cc

Issue 11028115: DoNumberTagD performance improvement (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Fix remaining code review comments Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 3769 matching lines...) Expand 10 before | Expand all | Expand 10 after
3780 // the value can be represented in a Smi. If not, we need to convert 3780 // the value can be represented in a Smi. If not, we need to convert
3781 // it to a HeapNumber. 3781 // it to a HeapNumber.
3782 Label box_int; 3782 Label box_int;
3783 __ cmp(value, Operand(0xC0000000)); 3783 __ cmp(value, Operand(0xC0000000));
3784 __ b(mi, &box_int); 3784 __ b(mi, &box_int);
3785 // Tag integer as smi and return it. 3785 // Tag integer as smi and return it.
3786 __ mov(r0, Operand(value, LSL, kSmiTagSize)); 3786 __ mov(r0, Operand(value, LSL, kSmiTagSize));
3787 __ Ret(); 3787 __ Ret();
3788 3788
3789 __ bind(&box_int); 3789 __ bind(&box_int);
3790 // Allocate a HeapNumber for the result and perform int-to-double
3791 // conversion. Don't touch r0 or r1 as they are needed if allocation
3792 // fails.
3793 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3794 __ AllocateHeapNumber(r5, r3, r4, r6, &slow);
3795 // Now we can use r0 for the result as key is not needed any more.
3796 __ mov(r0, r5);
3797
3798 if (CpuFeatures::IsSupported(VFP2)) { 3790 if (CpuFeatures::IsSupported(VFP2)) {
3799 CpuFeatures::Scope scope(VFP2); 3791 CpuFeatures::Scope scope(VFP2);
3792 // Allocate a HeapNumber for the result and perform int-to-double
3793 // conversion. Don't touch r0 or r1 as they are needed if allocation
3794 // fails.
3795 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3796
3797 __ AllocateHeapNumber(r5, r3, r4, r6, &slow, DONT_TAG_RESULT);
3798 // Now we can use r0 for the result as key is not needed any more.
3799 __ add(r0, r5, Operand(kHeapObjectTag));
3800 __ vmov(s0, value); 3800 __ vmov(s0, value);
3801 __ vcvt_f64_s32(d0, s0); 3801 __ vcvt_f64_s32(d0, s0);
3802 __ sub(r3, r0, Operand(kHeapObjectTag)); 3802 __ vstr(d0, r5, HeapNumber::kValueOffset);
3803 __ vstr(d0, r3, HeapNumber::kValueOffset);
3804 __ Ret(); 3803 __ Ret();
3805 } else { 3804 } else {
3805 // Allocate a HeapNumber for the result and perform int-to-double
3806 // conversion. Don't touch r0 or r1 as they are needed if allocation
3807 // fails.
3808 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3809 __ AllocateHeapNumber(r5, r3, r4, r6, &slow, TAG_RESULT);
3810 // Now we can use r0 for the result as key is not needed any more.
3811 __ mov(r0, r5);
3806 Register dst1 = r1; 3812 Register dst1 = r1;
3807 Register dst2 = r3; 3813 Register dst2 = r3;
3808 FloatingPointHelper::Destination dest = 3814 FloatingPointHelper::Destination dest =
3809 FloatingPointHelper::kCoreRegisters; 3815 FloatingPointHelper::kCoreRegisters;
3810 FloatingPointHelper::ConvertIntToDouble(masm, 3816 FloatingPointHelper::ConvertIntToDouble(masm,
3811 value, 3817 value,
3812 dest, 3818 dest,
3813 d0, 3819 d0,
3814 dst1, 3820 dst1,
3815 dst2, 3821 dst2,
(...skipping 15 matching lines...) Expand all
3831 // Tag integer as smi and return it. 3837 // Tag integer as smi and return it.
3832 __ mov(r0, Operand(value, LSL, kSmiTagSize)); 3838 __ mov(r0, Operand(value, LSL, kSmiTagSize));
3833 __ Ret(); 3839 __ Ret();
3834 3840
3835 __ bind(&box_int); 3841 __ bind(&box_int);
3836 __ vmov(s0, value); 3842 __ vmov(s0, value);
3837 // Allocate a HeapNumber for the result and perform int-to-double 3843 // Allocate a HeapNumber for the result and perform int-to-double
3838 // conversion. Don't use r0 and r1 as AllocateHeapNumber clobbers all 3844 // conversion. Don't use r0 and r1 as AllocateHeapNumber clobbers all
3839 // registers - also when jumping due to exhausted young space. 3845 // registers - also when jumping due to exhausted young space.
3840 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 3846 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3841 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); 3847 __ AllocateHeapNumber(r2, r3, r4, r6, &slow, DONT_TAG_RESULT);
3842 3848
3843 __ vcvt_f64_u32(d0, s0); 3849 __ vcvt_f64_u32(d0, s0);
3844 __ sub(r1, r2, Operand(kHeapObjectTag)); 3850 __ vstr(d0, r2, HeapNumber::kValueOffset);
3845 __ vstr(d0, r1, HeapNumber::kValueOffset);
3846 3851
3847 __ mov(r0, r2); 3852 __ add(r0, r2, Operand(kHeapObjectTag));
3848 __ Ret(); 3853 __ Ret();
3849 } else { 3854 } else {
3850 // Check whether unsigned integer fits into smi. 3855 // Check whether unsigned integer fits into smi.
3851 Label box_int_0, box_int_1, done; 3856 Label box_int_0, box_int_1, done;
3852 __ tst(value, Operand(0x80000000)); 3857 __ tst(value, Operand(0x80000000));
3853 __ b(ne, &box_int_0); 3858 __ b(ne, &box_int_0);
3854 __ tst(value, Operand(0x40000000)); 3859 __ tst(value, Operand(0x40000000));
3855 __ b(ne, &box_int_1); 3860 __ b(ne, &box_int_1);
3856 // Tag integer as smi and return it. 3861 // Tag integer as smi and return it.
3857 __ mov(r0, Operand(value, LSL, kSmiTagSize)); 3862 __ mov(r0, Operand(value, LSL, kSmiTagSize));
(...skipping 11 matching lines...) Expand all
3869 // Integer has one leading zero. 3874 // Integer has one leading zero.
3870 GenerateUInt2Double(masm, hiword, loword, r4, 1); 3875 GenerateUInt2Double(masm, hiword, loword, r4, 1);
3871 3876
3872 3877
3873 __ bind(&done); 3878 __ bind(&done);
3874 // Integer was converted to double in registers hiword:loword. 3879 // Integer was converted to double in registers hiword:loword.
3875 // Wrap it into a HeapNumber. Don't use r0 and r1 as AllocateHeapNumber 3880 // Wrap it into a HeapNumber. Don't use r0 and r1 as AllocateHeapNumber
3876 // clobbers all registers - also when jumping due to exhausted young 3881 // clobbers all registers - also when jumping due to exhausted young
3877 // space. 3882 // space.
3878 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 3883 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3879 __ AllocateHeapNumber(r4, r5, r7, r6, &slow); 3884 __ AllocateHeapNumber(r4, r5, r7, r6, &slow, TAG_RESULT);
3880 3885
3881 __ str(hiword, FieldMemOperand(r4, HeapNumber::kExponentOffset)); 3886 __ str(hiword, FieldMemOperand(r4, HeapNumber::kExponentOffset));
3882 __ str(loword, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); 3887 __ str(loword, FieldMemOperand(r4, HeapNumber::kMantissaOffset));
3883 3888
3884 __ mov(r0, r4); 3889 __ mov(r0, r4);
3885 __ Ret(); 3890 __ Ret();
3886 } 3891 }
3887 } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3892 } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3888 // For the floating-point array type, we need to always allocate a 3893 // For the floating-point array type, we need to always allocate a
3889 // HeapNumber. 3894 // HeapNumber.
3890 if (CpuFeatures::IsSupported(VFP2)) { 3895 if (CpuFeatures::IsSupported(VFP2)) {
3891 CpuFeatures::Scope scope(VFP2); 3896 CpuFeatures::Scope scope(VFP2);
3892 // Allocate a HeapNumber for the result. Don't use r0 and r1 as 3897 // Allocate a HeapNumber for the result. Don't use r0 and r1 as
3893 // AllocateHeapNumber clobbers all registers - also when jumping due to 3898 // AllocateHeapNumber clobbers all registers - also when jumping due to
3894 // exhausted young space. 3899 // exhausted young space.
3895 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 3900 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3896 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); 3901 __ AllocateHeapNumber(r2, r3, r4, r6, &slow, DONT_TAG_RESULT);
3897 __ vcvt_f64_f32(d0, s0); 3902 __ vcvt_f64_f32(d0, s0);
3898 __ sub(r1, r2, Operand(kHeapObjectTag)); 3903 __ vstr(d0, r2, HeapNumber::kValueOffset);
3899 __ vstr(d0, r1, HeapNumber::kValueOffset);
3900 3904
3901 __ mov(r0, r2); 3905 __ add(r0, r2, Operand(kHeapObjectTag));
3902 __ Ret(); 3906 __ Ret();
3903 } else { 3907 } else {
3904 // Allocate a HeapNumber for the result. Don't use r0 and r1 as 3908 // Allocate a HeapNumber for the result. Don't use r0 and r1 as
3905 // AllocateHeapNumber clobbers all registers - also when jumping due to 3909 // AllocateHeapNumber clobbers all registers - also when jumping due to
3906 // exhausted young space. 3910 // exhausted young space.
3907 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 3911 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3908 __ AllocateHeapNumber(r3, r4, r5, r6, &slow); 3912 __ AllocateHeapNumber(r3, r4, r5, r6, &slow, TAG_RESULT);
3909 // VFP is not available, do manual single to double conversion. 3913 // VFP is not available, do manual single to double conversion.
3910 3914
3911 // r2: floating point value (binary32) 3915 // r2: floating point value (binary32)
3912 // r3: heap number for result 3916 // r3: heap number for result
3913 3917
3914 // Extract mantissa to r0. OK to clobber r0 now as there are no jumps to 3918 // Extract mantissa to r0. OK to clobber r0 now as there are no jumps to
3915 // the slow case from here. 3919 // the slow case from here.
3916 __ and_(r0, value, Operand(kBinary32MantissaMask)); 3920 __ and_(r0, value, Operand(kBinary32MantissaMask));
3917 3921
3918 // Extract exponent to r1. OK to clobber r1 now as there are no jumps to 3922 // Extract exponent to r1. OK to clobber r1 now as there are no jumps to
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3954 __ mov(r0, r3); 3958 __ mov(r0, r3);
3955 __ Ret(); 3959 __ Ret();
3956 } 3960 }
3957 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3961 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3958 if (CpuFeatures::IsSupported(VFP2)) { 3962 if (CpuFeatures::IsSupported(VFP2)) {
3959 CpuFeatures::Scope scope(VFP2); 3963 CpuFeatures::Scope scope(VFP2);
3960 // Allocate a HeapNumber for the result. Don't use r0 and r1 as 3964 // Allocate a HeapNumber for the result. Don't use r0 and r1 as
3961 // AllocateHeapNumber clobbers all registers - also when jumping due to 3965 // AllocateHeapNumber clobbers all registers - also when jumping due to
3962 // exhausted young space. 3966 // exhausted young space.
3963 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex); 3967 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
3964 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); 3968 __ AllocateHeapNumber(r2, r3, r4, r6, &slow, DONT_TAG_RESULT);
3965 __ sub(r1, r2, Operand(kHeapObjectTag)); 3969 __ vstr(d0, r2, HeapNumber::kValueOffset);
3966 __ vstr(d0, r1, HeapNumber::kValueOffset);
3967 3970
3968 __ mov(r0, r2); 3971 __ add(r0, r2, Operand(kHeapObjectTag));
3969 __ Ret(); 3972 __ Ret();
3970 } else { 3973 } else {
3971 // Allocate a HeapNumber for the result. Don't use r0 and r1 as 3974 // Allocate a HeapNumber for the result. Don't use r0 and r1 as
3972 // AllocateHeapNumber clobbers all registers - also when jumping due to 3975 // AllocateHeapNumber clobbers all registers - also when jumping due to
3973 // exhausted young space. 3976 // exhausted young space.
3974 __ LoadRoot(r7, Heap::kHeapNumberMapRootIndex); 3977 __ LoadRoot(r7, Heap::kHeapNumberMapRootIndex);
3975 __ AllocateHeapNumber(r4, r5, r6, r7, &slow); 3978 __ AllocateHeapNumber(r4, r5, r6, r7, &slow, TAG_RESULT);
3976 3979
3977 __ str(r2, FieldMemOperand(r4, HeapNumber::kMantissaOffset)); 3980 __ str(r2, FieldMemOperand(r4, HeapNumber::kMantissaOffset));
3978 __ str(r3, FieldMemOperand(r4, HeapNumber::kExponentOffset)); 3981 __ str(r3, FieldMemOperand(r4, HeapNumber::kExponentOffset));
3979 __ mov(r0, r4); 3982 __ mov(r0, r4);
3980 __ Ret(); 3983 __ Ret();
3981 } 3984 }
3982 3985
3983 } else { 3986 } else {
3984 // Tag integer as smi and return it. 3987 // Tag integer as smi and return it.
3985 __ mov(r0, Operand(value, LSL, kSmiTagSize)); 3988 __ mov(r0, Operand(value, LSL, kSmiTagSize));
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
4432 __ add(indexed_double_offset, elements_reg, 4435 __ add(indexed_double_offset, elements_reg,
4433 Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize)); 4436 Operand(key_reg, LSL, kDoubleSizeLog2 - kSmiTagSize));
4434 uint32_t upper_32_offset = FixedArray::kHeaderSize + sizeof(kHoleNanLower32); 4437 uint32_t upper_32_offset = FixedArray::kHeaderSize + sizeof(kHoleNanLower32);
4435 __ ldr(scratch, FieldMemOperand(indexed_double_offset, upper_32_offset)); 4438 __ ldr(scratch, FieldMemOperand(indexed_double_offset, upper_32_offset));
4436 __ cmp(scratch, Operand(kHoleNanUpper32)); 4439 __ cmp(scratch, Operand(kHoleNanUpper32));
4437 __ b(&miss_force_generic, eq); 4440 __ b(&miss_force_generic, eq);
4438 4441
4439 // Non-NaN. Allocate a new heap number and copy the double value into it. 4442 // Non-NaN. Allocate a new heap number and copy the double value into it.
4440 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); 4443 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
4441 __ AllocateHeapNumber(heap_number_reg, scratch2, scratch3, 4444 __ AllocateHeapNumber(heap_number_reg, scratch2, scratch3,
4442 heap_number_map, &slow_allocate_heapnumber); 4445 heap_number_map, &slow_allocate_heapnumber, TAG_RESULT);
4443 4446
4444 // Don't need to reload the upper 32 bits of the double, it's already in 4447 // Don't need to reload the upper 32 bits of the double, it's already in
4445 // scratch. 4448 // scratch.
4446 __ str(scratch, FieldMemOperand(heap_number_reg, 4449 __ str(scratch, FieldMemOperand(heap_number_reg,
4447 HeapNumber::kExponentOffset)); 4450 HeapNumber::kExponentOffset));
4448 __ ldr(scratch, FieldMemOperand(indexed_double_offset, 4451 __ ldr(scratch, FieldMemOperand(indexed_double_offset,
4449 FixedArray::kHeaderSize)); 4452 FixedArray::kHeaderSize));
4450 __ str(scratch, FieldMemOperand(heap_number_reg, 4453 __ str(scratch, FieldMemOperand(heap_number_reg,
4451 HeapNumber::kMantissaOffset)); 4454 HeapNumber::kMantissaOffset));
4452 4455
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
4774 __ Jump(ic_slow, RelocInfo::CODE_TARGET); 4777 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
4775 } 4778 }
4776 } 4779 }
4777 4780
4778 4781
4779 #undef __ 4782 #undef __
4780 4783
4781 } } // namespace v8::internal 4784 } } // namespace v8::internal
4782 4785
4783 #endif // V8_TARGET_ARCH_ARM 4786 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/macro-assembler-arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698