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

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 10382055: Array index computation dehoisting. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed review comments. Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/flag-definitions.h » ('j') | 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 2730 matching lines...) Expand 10 before | Expand all | Expand 10 after
2741 2741
2742 2742
2743 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2743 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2744 Register elements = ToRegister(instr->elements()); 2744 Register elements = ToRegister(instr->elements());
2745 Register key = EmitLoadRegister(instr->key(), scratch0()); 2745 Register key = EmitLoadRegister(instr->key(), scratch0());
2746 Register result = ToRegister(instr->result()); 2746 Register result = ToRegister(instr->result());
2747 Register scratch = scratch0(); 2747 Register scratch = scratch0();
2748 2748
2749 // Load the result. 2749 // Load the result.
2750 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 2750 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
2751 __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 2751 uint32_t offset = FixedArray::kHeaderSize +
2752 (instr->additional_index() << kPointerSizeLog2);
2753 __ ldr(result, FieldMemOperand(scratch, offset));
2752 2754
2753 // Check for the hole value. 2755 // Check for the hole value.
2754 if (instr->hydrogen()->RequiresHoleCheck()) { 2756 if (instr->hydrogen()->RequiresHoleCheck()) {
2755 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); 2757 __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex);
2756 __ cmp(result, scratch); 2758 __ cmp(result, scratch);
2757 DeoptimizeIf(eq, instr->environment()); 2759 DeoptimizeIf(eq, instr->environment());
2758 } 2760 }
2759 } 2761 }
2760 2762
2761 2763
(...skipping 11 matching lines...) Expand all
2773 if (key_is_constant) { 2775 if (key_is_constant) {
2774 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 2776 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2775 if (constant_key & 0xF0000000) { 2777 if (constant_key & 0xF0000000) {
2776 Abort("array index constant value too big."); 2778 Abort("array index constant value too big.");
2777 } 2779 }
2778 } else { 2780 } else {
2779 key = ToRegister(instr->key()); 2781 key = ToRegister(instr->key());
2780 } 2782 }
2781 2783
2782 Operand operand = key_is_constant 2784 Operand operand = key_is_constant
2783 ? Operand(constant_key * (1 << shift_size) + 2785 ? Operand(((constant_key + instr->additional_index()) << shift_size) +
2784 FixedDoubleArray::kHeaderSize - kHeapObjectTag) 2786 FixedDoubleArray::kHeaderSize - kHeapObjectTag)
2785 : Operand(key, LSL, shift_size); 2787 : Operand(key, LSL, shift_size);
2786 __ add(elements, elements, operand); 2788 __ add(elements, elements, operand);
2787 if (!key_is_constant) { 2789 if (!key_is_constant) {
2788 __ add(elements, elements, 2790 __ add(elements, elements,
2789 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 2791 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
2792 (instr->additional_index() << shift_size)));
2790 } 2793 }
2791 2794
2792 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 2795 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
2793 __ cmp(scratch, Operand(kHoleNanUpper32)); 2796 __ cmp(scratch, Operand(kHoleNanUpper32));
2794 DeoptimizeIf(eq, instr->environment()); 2797 DeoptimizeIf(eq, instr->environment());
2795 2798
2796 __ vldr(result, elements, 0); 2799 __ vldr(result, elements, 0);
2797 } 2800 }
2798 2801
2799 2802
2800 void LCodeGen::DoLoadKeyedSpecializedArrayElement( 2803 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2801 LLoadKeyedSpecializedArrayElement* instr) { 2804 LLoadKeyedSpecializedArrayElement* instr) {
2802 Register external_pointer = ToRegister(instr->external_pointer()); 2805 Register external_pointer = ToRegister(instr->external_pointer());
2803 Register key = no_reg; 2806 Register key = no_reg;
2804 ElementsKind elements_kind = instr->elements_kind(); 2807 ElementsKind elements_kind = instr->elements_kind();
2805 bool key_is_constant = instr->key()->IsConstantOperand(); 2808 bool key_is_constant = instr->key()->IsConstantOperand();
2806 int constant_key = 0; 2809 int constant_key = 0;
2807 if (key_is_constant) { 2810 if (key_is_constant) {
2808 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 2811 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
2809 if (constant_key & 0xF0000000) { 2812 if (constant_key & 0xF0000000) {
2810 Abort("array index constant value too big."); 2813 Abort("array index constant value too big.");
2811 } 2814 }
2812 } else { 2815 } else {
2813 key = ToRegister(instr->key()); 2816 key = ToRegister(instr->key());
2814 } 2817 }
2815 int shift_size = ElementsKindToShiftSize(elements_kind); 2818 int shift_size = ElementsKindToShiftSize(elements_kind);
2819 int additional_offset = instr->additional_index() << shift_size;
2816 2820
2817 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 2821 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
2818 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 2822 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
2819 CpuFeatures::Scope scope(VFP3); 2823 CpuFeatures::Scope scope(VFP3);
2820 DwVfpRegister result = ToDoubleRegister(instr->result()); 2824 DwVfpRegister result = ToDoubleRegister(instr->result());
2821 Operand operand = key_is_constant 2825 Operand operand = key_is_constant
2822 ? Operand(constant_key * (1 << shift_size)) 2826 ? Operand(constant_key << shift_size)
2823 : Operand(key, LSL, shift_size); 2827 : Operand(key, LSL, shift_size);
2824 __ add(scratch0(), external_pointer, operand); 2828 __ add(scratch0(), external_pointer, operand);
2825 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 2829 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2826 __ vldr(result.low(), scratch0(), 0); 2830 __ vldr(result.low(), scratch0(), additional_offset);
2827 __ vcvt_f64_f32(result, result.low()); 2831 __ vcvt_f64_f32(result, result.low());
2828 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 2832 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
2829 __ vldr(result, scratch0(), 0); 2833 __ vldr(result, scratch0(), additional_offset);
2830 } 2834 }
2831 } else { 2835 } else {
2832 Register result = ToRegister(instr->result()); 2836 Register result = ToRegister(instr->result());
2837 if (instr->additional_index() != 0 && !key_is_constant) {
2838 __ add(scratch0(), key, Operand(instr->additional_index()));
2839 }
2833 MemOperand mem_operand(key_is_constant 2840 MemOperand mem_operand(key_is_constant
2834 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) 2841 ? MemOperand(external_pointer,
2835 : MemOperand(external_pointer, key, LSL, shift_size)); 2842 (constant_key << shift_size) + additional_offset)
2843 : (instr->additional_index() == 0
2844 ? MemOperand(external_pointer, key, LSL, shift_size)
2845 : MemOperand(external_pointer, scratch0(), LSL, shift_size)));
2836 switch (elements_kind) { 2846 switch (elements_kind) {
2837 case EXTERNAL_BYTE_ELEMENTS: 2847 case EXTERNAL_BYTE_ELEMENTS:
2838 __ ldrsb(result, mem_operand); 2848 __ ldrsb(result, mem_operand);
2839 break; 2849 break;
2840 case EXTERNAL_PIXEL_ELEMENTS: 2850 case EXTERNAL_PIXEL_ELEMENTS:
2841 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 2851 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
2842 __ ldrb(result, mem_operand); 2852 __ ldrb(result, mem_operand);
2843 break; 2853 break;
2844 case EXTERNAL_SHORT_ELEMENTS: 2854 case EXTERNAL_SHORT_ELEMENTS:
2845 __ ldrsh(result, mem_operand); 2855 __ ldrsh(result, mem_operand);
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
3723 Register value = ToRegister(instr->value()); 3733 Register value = ToRegister(instr->value());
3724 Register elements = ToRegister(instr->object()); 3734 Register elements = ToRegister(instr->object());
3725 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 3735 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3726 Register scratch = scratch0(); 3736 Register scratch = scratch0();
3727 3737
3728 // Do the store. 3738 // Do the store.
3729 if (instr->key()->IsConstantOperand()) { 3739 if (instr->key()->IsConstantOperand()) {
3730 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); 3740 ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
3731 LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); 3741 LConstantOperand* const_operand = LConstantOperand::cast(instr->key());
3732 int offset = 3742 int offset =
3733 ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; 3743 (ToInteger32(const_operand) + instr->additional_index()) * kPointerSize
3744 + FixedArray::kHeaderSize;
3734 __ str(value, FieldMemOperand(elements, offset)); 3745 __ str(value, FieldMemOperand(elements, offset));
3735 } else { 3746 } else {
3736 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); 3747 __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2));
3748 if (instr->additional_index() != 0) {
3749 __ add(scratch,
3750 scratch,
3751 Operand(instr->additional_index() << kPointerSizeLog2));
3752 }
3737 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); 3753 __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize));
3738 } 3754 }
3739 3755
3740 if (instr->hydrogen()->NeedsWriteBarrier()) { 3756 if (instr->hydrogen()->NeedsWriteBarrier()) {
3741 HType type = instr->hydrogen()->value()->type(); 3757 HType type = instr->hydrogen()->value()->type();
3742 SmiCheck check_needed = 3758 SmiCheck check_needed =
3743 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3759 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3744 // Compute address of modified element and store it into key register. 3760 // Compute address of modified element and store it into key register.
3745 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); 3761 __ add(key, scratch, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
3746 __ RecordWrite(elements, 3762 __ RecordWrite(elements,
(...skipping 21 matching lines...) Expand all
3768 if (key_is_constant) { 3784 if (key_is_constant) {
3769 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3785 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3770 if (constant_key & 0xF0000000) { 3786 if (constant_key & 0xF0000000) {
3771 Abort("array index constant value too big."); 3787 Abort("array index constant value too big.");
3772 } 3788 }
3773 } else { 3789 } else {
3774 key = ToRegister(instr->key()); 3790 key = ToRegister(instr->key());
3775 } 3791 }
3776 int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); 3792 int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
3777 Operand operand = key_is_constant 3793 Operand operand = key_is_constant
3778 ? Operand(constant_key * (1 << shift_size) + 3794 ? Operand((constant_key << shift_size) +
3779 FixedDoubleArray::kHeaderSize - kHeapObjectTag) 3795 FixedDoubleArray::kHeaderSize - kHeapObjectTag)
3780 : Operand(key, LSL, shift_size); 3796 : Operand(key, LSL, shift_size);
3781 __ add(scratch, elements, operand); 3797 __ add(scratch, elements, operand);
3782 if (!key_is_constant) { 3798 if (!key_is_constant) {
3783 __ add(scratch, scratch, 3799 __ add(scratch, scratch,
3784 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); 3800 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag));
3785 } 3801 }
3786 3802
3787 if (instr->NeedsCanonicalization()) { 3803 if (instr->NeedsCanonicalization()) {
3788 // Check for NaN. All NaNs must be canonicalized. 3804 // Check for NaN. All NaNs must be canonicalized.
3789 __ VFPCompareAndSetFlags(value, value); 3805 __ VFPCompareAndSetFlags(value, value);
3790 // Only load canonical NaN if the comparison above set the overflow. 3806 // Only load canonical NaN if the comparison above set the overflow.
3791 __ Vmov(value, 3807 __ Vmov(value,
3792 FixedDoubleArray::canonical_not_the_hole_nan_as_double(), 3808 FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
3793 vs); 3809 vs);
3794 } 3810 }
3795 3811
3796 __ vstr(value, scratch, 0); 3812 __ vstr(value, scratch, instr->additional_index() << shift_size);
3797 } 3813 }
3798 3814
3799 3815
3800 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3816 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3801 LStoreKeyedSpecializedArrayElement* instr) { 3817 LStoreKeyedSpecializedArrayElement* instr) {
3802 3818
3803 Register external_pointer = ToRegister(instr->external_pointer()); 3819 Register external_pointer = ToRegister(instr->external_pointer());
3804 Register key = no_reg; 3820 Register key = no_reg;
3805 ElementsKind elements_kind = instr->elements_kind(); 3821 ElementsKind elements_kind = instr->elements_kind();
3806 bool key_is_constant = instr->key()->IsConstantOperand(); 3822 bool key_is_constant = instr->key()->IsConstantOperand();
3807 int constant_key = 0; 3823 int constant_key = 0;
3808 if (key_is_constant) { 3824 if (key_is_constant) {
3809 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3825 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3810 if (constant_key & 0xF0000000) { 3826 if (constant_key & 0xF0000000) {
3811 Abort("array index constant value too big."); 3827 Abort("array index constant value too big.");
3812 } 3828 }
3813 } else { 3829 } else {
3814 key = ToRegister(instr->key()); 3830 key = ToRegister(instr->key());
3815 } 3831 }
3816 int shift_size = ElementsKindToShiftSize(elements_kind); 3832 int shift_size = ElementsKindToShiftSize(elements_kind);
3833 int additional_offset = instr->additional_index() << shift_size;
3817 3834
3818 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3835 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3819 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3836 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3820 CpuFeatures::Scope scope(VFP3); 3837 CpuFeatures::Scope scope(VFP3);
3821 DwVfpRegister value(ToDoubleRegister(instr->value())); 3838 DwVfpRegister value(ToDoubleRegister(instr->value()));
3822 Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) 3839 Operand operand(key_is_constant ? Operand(constant_key << shift_size)
3823 : Operand(key, LSL, shift_size)); 3840 : Operand(key, LSL, shift_size));
3824 __ add(scratch0(), external_pointer, operand); 3841 __ add(scratch0(), external_pointer, operand);
3825 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3842 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3826 __ vcvt_f32_f64(double_scratch0().low(), value); 3843 __ vcvt_f32_f64(double_scratch0().low(), value);
3827 __ vstr(double_scratch0().low(), scratch0(), 0); 3844 __ vstr(double_scratch0().low(), scratch0(), additional_offset);
3828 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS 3845 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3829 __ vstr(value, scratch0(), 0); 3846 __ vstr(value, scratch0(), additional_offset);
3830 } 3847 }
3831 } else { 3848 } else {
3832 Register value(ToRegister(instr->value())); 3849 Register value(ToRegister(instr->value()));
3850 if (instr->additional_index() != 0 && !key_is_constant) {
3851 __ add(scratch0(), key, Operand(instr->additional_index()));
3852 }
3833 MemOperand mem_operand(key_is_constant 3853 MemOperand mem_operand(key_is_constant
3834 ? MemOperand(external_pointer, constant_key * (1 << shift_size)) 3854 ? MemOperand(external_pointer,
3835 : MemOperand(external_pointer, key, LSL, shift_size)); 3855 ((constant_key + instr->additional_index())
3856 << shift_size))
3857 : (instr->additional_index() == 0
3858 ? MemOperand(external_pointer, key, LSL, shift_size)
3859 : MemOperand(external_pointer, scratch0(), LSL, shift_size)));
3836 switch (elements_kind) { 3860 switch (elements_kind) {
3837 case EXTERNAL_PIXEL_ELEMENTS: 3861 case EXTERNAL_PIXEL_ELEMENTS:
3838 case EXTERNAL_BYTE_ELEMENTS: 3862 case EXTERNAL_BYTE_ELEMENTS:
3839 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3863 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3840 __ strb(value, mem_operand); 3864 __ strb(value, mem_operand);
3841 break; 3865 break;
3842 case EXTERNAL_SHORT_ELEMENTS: 3866 case EXTERNAL_SHORT_ELEMENTS:
3843 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 3867 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3844 __ strh(value, mem_operand); 3868 __ strh(value, mem_operand);
3845 break; 3869 break;
(...skipping 1465 matching lines...) Expand 10 before | Expand all | Expand 10 after
5311 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 5335 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
5312 __ ldr(result, FieldMemOperand(scratch, 5336 __ ldr(result, FieldMemOperand(scratch,
5313 FixedArray::kHeaderSize - kPointerSize)); 5337 FixedArray::kHeaderSize - kPointerSize));
5314 __ bind(&done); 5338 __ bind(&done);
5315 } 5339 }
5316 5340
5317 5341
5318 #undef __ 5342 #undef __
5319 5343
5320 } } // namespace v8::internal 5344 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-arm.h ('k') | src/flag-definitions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698