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

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

Issue 11238016: Consolidated all the key store/load classes in the Hydrogen and Lithium (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Oops, missed a section of commented-out code Created 8 years, 1 month 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
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 2731 matching lines...) Expand 10 before | Expand all | Expand 10 after
2742 Register length = ToRegister(instr->length()); 2742 Register length = ToRegister(instr->length());
2743 Operand index = ToOperand(instr->index()); 2743 Operand index = ToOperand(instr->index());
2744 Register result = ToRegister(instr->result()); 2744 Register result = ToRegister(instr->result());
2745 // There are two words between the frame pointer and the last argument. 2745 // There are two words between the frame pointer and the last argument.
2746 // Subtracting from length accounts for one of them add one more. 2746 // Subtracting from length accounts for one of them add one more.
2747 __ sub(length, index); 2747 __ sub(length, index);
2748 __ mov(result, Operand(arguments, length, times_4, kPointerSize)); 2748 __ mov(result, Operand(arguments, length, times_4, kPointerSize));
2749 } 2749 }
2750 2750
2751 2751
2752 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2752 void LCodeGen::DoLoadKeyedExternal(LLoadKeyed* instr) {
2753 Register result = ToRegister(instr->result());
2754
2755 // Load the result.
2756 __ mov(result,
2757 BuildFastArrayOperand(instr->elements(),
2758 instr->key(),
2759 instr->hydrogen()->key()->representation(),
2760 FAST_ELEMENTS,
2761 FixedArray::kHeaderSize - kHeapObjectTag,
2762 instr->additional_index()));
2763
2764 // Check for the hole value.
2765 if (instr->hydrogen()->RequiresHoleCheck()) {
2766 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
2767 __ test(result, Immediate(kSmiTagMask));
2768 DeoptimizeIf(not_equal, instr->environment());
2769 } else {
2770 __ cmp(result, factory()->the_hole_value());
2771 DeoptimizeIf(equal, instr->environment());
2772 }
2773 }
2774 }
2775
2776
2777 void LCodeGen::DoLoadKeyedFastDoubleElement(
2778 LLoadKeyedFastDoubleElement* instr) {
2779 XMMRegister result = ToDoubleRegister(instr->result());
2780
2781 if (instr->hydrogen()->RequiresHoleCheck()) {
2782 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2783 sizeof(kHoleNanLower32);
2784 Operand hole_check_operand = BuildFastArrayOperand(
2785 instr->elements(), instr->key(),
2786 instr->hydrogen()->key()->representation(),
2787 FAST_DOUBLE_ELEMENTS,
2788 offset,
2789 instr->additional_index());
2790 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
2791 DeoptimizeIf(equal, instr->environment());
2792 }
2793
2794 Operand double_load_operand = BuildFastArrayOperand(
2795 instr->elements(),
2796 instr->key(),
2797 instr->hydrogen()->key()->representation(),
2798 FAST_DOUBLE_ELEMENTS,
2799 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2800 instr->additional_index());
2801 __ movdbl(result, double_load_operand);
2802 }
2803
2804
2805 Operand LCodeGen::BuildFastArrayOperand(
2806 LOperand* elements_pointer,
2807 LOperand* key,
2808 Representation key_representation,
2809 ElementsKind elements_kind,
2810 uint32_t offset,
2811 uint32_t additional_index) {
2812 Register elements_pointer_reg = ToRegister(elements_pointer);
2813 int shift_size = ElementsKindToShiftSize(elements_kind);
2814 // Even though the HLoad/StoreKeyedFastElement instructions force the input
2815 // representation for the key to be an integer, the input gets replaced during
2816 // bound check elimination with the index argument to the bounds check, which
2817 // can be tagged, so that case must be handled here, too.
2818 if (key_representation.IsTagged() && (shift_size >= 1)) {
2819 shift_size -= kSmiTagSize;
2820 }
2821 if (key->IsConstantOperand()) {
2822 int constant_value = ToInteger32(LConstantOperand::cast(key));
2823 if (constant_value & 0xF0000000) {
2824 Abort("array index constant value too big");
2825 }
2826 return Operand(elements_pointer_reg,
2827 ((constant_value + additional_index) << shift_size)
2828 + offset);
2829 } else {
2830 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2831 return Operand(elements_pointer_reg,
2832 ToRegister(key),
2833 scale_factor,
2834 offset + (additional_index << shift_size));
2835 }
2836 }
2837
2838
2839 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2840 LLoadKeyedSpecializedArrayElement* instr) {
2841 ElementsKind elements_kind = instr->elements_kind(); 2753 ElementsKind elements_kind = instr->elements_kind();
2842 LOperand* key = instr->key(); 2754 LOperand* key = instr->key();
2843 if (!key->IsConstantOperand() && 2755 if (!key->IsConstantOperand() &&
2844 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), 2756 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
2845 elements_kind)) { 2757 elements_kind)) {
2846 __ SmiUntag(ToRegister(key)); 2758 __ SmiUntag(ToRegister(key));
2847 } 2759 }
2848 Operand operand(BuildFastArrayOperand( 2760 Operand operand(BuildFastArrayOperand(
2849 instr->external_pointer(), 2761 instr->object(),
2850 key, 2762 key,
2851 instr->hydrogen()->key()->representation(), 2763 instr->hydrogen()->key()->representation(),
2852 elements_kind, 2764 elements_kind,
2853 0, 2765 0,
2854 instr->additional_index())); 2766 instr->additional_index()));
2855 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 2767 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
2856 XMMRegister result(ToDoubleRegister(instr->result())); 2768 XMMRegister result(ToDoubleRegister(instr->result()));
2857 __ movss(result, operand); 2769 __ movss(result, operand);
2858 __ cvtss2sd(result, result); 2770 __ cvtss2sd(result, result);
2859 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 2771 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2894 case FAST_HOLEY_DOUBLE_ELEMENTS: 2806 case FAST_HOLEY_DOUBLE_ELEMENTS:
2895 case DICTIONARY_ELEMENTS: 2807 case DICTIONARY_ELEMENTS:
2896 case NON_STRICT_ARGUMENTS_ELEMENTS: 2808 case NON_STRICT_ARGUMENTS_ELEMENTS:
2897 UNREACHABLE(); 2809 UNREACHABLE();
2898 break; 2810 break;
2899 } 2811 }
2900 } 2812 }
2901 } 2813 }
2902 2814
2903 2815
2816 void LCodeGen::DoLoadKeyedDouble(LLoadKeyed* instr) {
2817 XMMRegister result = ToDoubleRegister(instr->result());
2818
2819 if (instr->hydrogen()->RequiresHoleCheck()) {
2820 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2821 sizeof(kHoleNanLower32);
2822 Operand hole_check_operand = BuildFastArrayOperand(
2823 instr->object(), instr->key(),
2824 instr->hydrogen()->key()->representation(),
2825 FAST_DOUBLE_ELEMENTS,
2826 offset,
2827 instr->additional_index());
2828 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
2829 DeoptimizeIf(equal, instr->environment());
2830 }
2831
2832 Operand double_load_operand = BuildFastArrayOperand(
2833 instr->object(),
2834 instr->key(),
2835 instr->hydrogen()->key()->representation(),
2836 FAST_DOUBLE_ELEMENTS,
2837 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
2838 instr->additional_index());
2839 __ movdbl(result, double_load_operand);
2840 }
2841
2842
2843 void LCodeGen::DoLoadKeyedFixed(LLoadKeyed* instr) {
2844 Register result = ToRegister(instr->result());
2845
2846 // Load the result.
2847 __ mov(result,
2848 BuildFastArrayOperand(instr->object(),
2849 instr->key(),
2850 instr->hydrogen()->key()->representation(),
2851 FAST_ELEMENTS,
2852 FixedArray::kHeaderSize - kHeapObjectTag,
2853 instr->additional_index()));
2854
2855 // Check for the hole value.
2856 if (instr->hydrogen()->RequiresHoleCheck()) {
2857 if (IsFastSmiElementsKind(instr->hydrogen()->elements_kind())) {
2858 __ test(result, Immediate(kSmiTagMask));
2859 DeoptimizeIf(not_equal, instr->environment());
2860 } else {
2861 __ cmp(result, factory()->the_hole_value());
2862 DeoptimizeIf(equal, instr->environment());
2863 }
2864 }
2865 }
2866
danno 2012/10/24 11:42:43 nit: two spaces
mvstanton 2012/10/24 18:24:21 Done.
2867 void LCodeGen::DoLoadKeyed(LLoadKeyed* instr) {
2868 if (instr->is_external()) {
2869 DoLoadKeyedExternal(instr);
2870 } else if (instr->hydrogen()->representation().IsDouble()) {
2871 DoLoadKeyedDouble(instr);
2872 } else {
2873 DoLoadKeyedFixed(instr);
2874 }
2875 }
2876
2877
2878 Operand LCodeGen::BuildFastArrayOperand(
2879 LOperand* elements_pointer,
2880 LOperand* key,
2881 Representation key_representation,
2882 ElementsKind elements_kind,
2883 uint32_t offset,
2884 uint32_t additional_index) {
2885 Register elements_pointer_reg = ToRegister(elements_pointer);
2886 int shift_size = ElementsKindToShiftSize(elements_kind);
2887 // Even though the HLoad/StoreKeyed instructions force the input
2888 // representation for the key to be an integer, the input gets replaced during
2889 // bound check elimination with the index argument to the bounds check, which
2890 // can be tagged, so that case must be handled here, too.
2891 if (key_representation.IsTagged() && (shift_size >= 1)) {
2892 shift_size -= kSmiTagSize;
2893 }
2894 if (key->IsConstantOperand()) {
2895 int constant_value = ToInteger32(LConstantOperand::cast(key));
2896 if (constant_value & 0xF0000000) {
2897 Abort("array index constant value too big");
2898 }
2899 return Operand(elements_pointer_reg,
2900 ((constant_value + additional_index) << shift_size)
2901 + offset);
2902 } else {
2903 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2904 return Operand(elements_pointer_reg,
2905 ToRegister(key),
2906 scale_factor,
2907 offset + (additional_index << shift_size));
2908 }
2909 }
2910
2911
2904 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { 2912 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
2905 ASSERT(ToRegister(instr->context()).is(esi)); 2913 ASSERT(ToRegister(instr->context()).is(esi));
2906 ASSERT(ToRegister(instr->object()).is(edx)); 2914 ASSERT(ToRegister(instr->object()).is(edx));
2907 ASSERT(ToRegister(instr->key()).is(ecx)); 2915 ASSERT(ToRegister(instr->key()).is(ecx));
2908 2916
2909 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); 2917 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
2910 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2918 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2911 } 2919 }
2912 2920
2913 2921
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after
3811 __ cmp(ToOperand(instr->length()), Immediate(constant_index)); 3819 __ cmp(ToOperand(instr->length()), Immediate(constant_index));
3812 } 3820 }
3813 DeoptimizeIf(below_equal, instr->environment()); 3821 DeoptimizeIf(below_equal, instr->environment());
3814 } else { 3822 } else {
3815 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 3823 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
3816 DeoptimizeIf(above_equal, instr->environment()); 3824 DeoptimizeIf(above_equal, instr->environment());
3817 } 3825 }
3818 } 3826 }
3819 3827
3820 3828
3821 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3829 void LCodeGen::DoStoreKeyedExternal(LStoreKeyed* instr) {
3822 LStoreKeyedSpecializedArrayElement* instr) {
3823 ElementsKind elements_kind = instr->elements_kind(); 3830 ElementsKind elements_kind = instr->elements_kind();
3824 LOperand* key = instr->key(); 3831 LOperand* key = instr->key();
3825 if (!key->IsConstantOperand() && 3832 if (!key->IsConstantOperand() &&
3826 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(), 3833 ExternalArrayOpRequiresTemp(instr->hydrogen()->key()->representation(),
3827 elements_kind)) { 3834 elements_kind)) {
3828 __ SmiUntag(ToRegister(key)); 3835 __ SmiUntag(ToRegister(key));
3829 } 3836 }
3830 Operand operand(BuildFastArrayOperand( 3837 Operand operand(BuildFastArrayOperand(
3831 instr->external_pointer(), 3838 instr->object(),
3832 key, 3839 key,
3833 instr->hydrogen()->key()->representation(), 3840 instr->hydrogen()->key()->representation(),
3834 elements_kind, 3841 elements_kind,
3835 0, 3842 0,
3836 instr->additional_index())); 3843 instr->additional_index()));
3837 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3844 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3838 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); 3845 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
3839 __ movss(operand, xmm0); 3846 __ movss(operand, xmm0);
3840 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3847 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3841 __ movdbl(operand, ToDoubleRegister(instr->value())); 3848 __ movdbl(operand, ToDoubleRegister(instr->value()));
(...skipping 23 matching lines...) Expand all
3865 case FAST_HOLEY_DOUBLE_ELEMENTS: 3872 case FAST_HOLEY_DOUBLE_ELEMENTS:
3866 case DICTIONARY_ELEMENTS: 3873 case DICTIONARY_ELEMENTS:
3867 case NON_STRICT_ARGUMENTS_ELEMENTS: 3874 case NON_STRICT_ARGUMENTS_ELEMENTS:
3868 UNREACHABLE(); 3875 UNREACHABLE();
3869 break; 3876 break;
3870 } 3877 }
3871 } 3878 }
3872 } 3879 }
3873 3880
3874 3881
3875 void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { 3882 void LCodeGen::DoStoreKeyedDouble(LStoreKeyed* instr) {
3883 XMMRegister value = ToDoubleRegister(instr->value());
3884
3885 if (instr->NeedsCanonicalization()) {
3886 Label have_value;
3887
3888 __ ucomisd(value, value);
3889 __ j(parity_odd, &have_value); // NaN.
3890
3891 ExternalReference canonical_nan_reference =
3892 ExternalReference::address_of_canonical_non_hole_nan();
3893 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
3894 __ bind(&have_value);
3895 }
3896
3897 Operand double_store_operand = BuildFastArrayOperand(
3898 instr->object(),
3899 instr->key(),
3900 instr->hydrogen()->key()->representation(),
3901 FAST_DOUBLE_ELEMENTS,
3902 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3903 instr->additional_index());
3904 __ movdbl(double_store_operand, value);
3905 }
3906
3907
3908 void LCodeGen::DoStoreKeyedFixed(LStoreKeyed* instr) {
3876 Register value = ToRegister(instr->value()); 3909 Register value = ToRegister(instr->value());
3877 Register elements = ToRegister(instr->object()); 3910 Register elements = ToRegister(instr->object());
3878 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; 3911 Register key = instr->key()->IsRegister() ? ToRegister(instr->key())
danno 2012/10/24 11:42:43 I think this still fits on one line?
mvstanton 2012/10/24 18:24:21 Done.
3912 : no_reg;
3879 3913
3880 Operand operand = BuildFastArrayOperand( 3914 Operand operand = BuildFastArrayOperand(
3881 instr->object(), 3915 instr->object(),
3882 instr->key(), 3916 instr->key(),
3883 instr->hydrogen()->key()->representation(), 3917 instr->hydrogen()->key()->representation(),
3884 FAST_ELEMENTS, 3918 FAST_ELEMENTS,
3885 FixedArray::kHeaderSize - kHeapObjectTag, 3919 FixedArray::kHeaderSize - kHeapObjectTag,
3886 instr->additional_index()); 3920 instr->additional_index());
3887 __ mov(operand, value); 3921 __ mov(operand, value);
3888 3922
3889 if (instr->hydrogen()->NeedsWriteBarrier()) { 3923 if (instr->hydrogen()->NeedsWriteBarrier()) {
3890 ASSERT(!instr->key()->IsConstantOperand()); 3924 ASSERT(!instr->key()->IsConstantOperand());
3891 HType type = instr->hydrogen()->value()->type(); 3925 HType type = instr->hydrogen()->value()->type();
3892 SmiCheck check_needed = 3926 SmiCheck check_needed =
3893 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; 3927 type.IsHeapObject() ? OMIT_SMI_CHECK : INLINE_SMI_CHECK;
3894 // Compute address of modified element and store it into key register. 3928 // Compute address of modified element and store it into key register.
3895 __ lea(key, operand); 3929 __ lea(key, operand);
3896 __ RecordWrite(elements, 3930 __ RecordWrite(elements,
3897 key, 3931 key,
3898 value, 3932 value,
3899 kSaveFPRegs, 3933 kSaveFPRegs,
3900 EMIT_REMEMBERED_SET, 3934 EMIT_REMEMBERED_SET,
3901 check_needed); 3935 check_needed);
3902 } 3936 }
3903 } 3937 }
3904 3938
3905 3939
3906 void LCodeGen::DoStoreKeyedFastDoubleElement( 3940 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) {
3907 LStoreKeyedFastDoubleElement* instr) { 3941 // By cases...external, fast-double, fast
3908 XMMRegister value = ToDoubleRegister(instr->value()); 3942 if (instr->is_external()) {
3909 3943 DoStoreKeyedExternal(instr);
3910 if (instr->NeedsCanonicalization()) { 3944 } else if (instr->hydrogen()->value()->representation().IsDouble()) {
3911 Label have_value; 3945 DoStoreKeyedDouble(instr);
3912 3946 } else {
3913 __ ucomisd(value, value); 3947 DoStoreKeyedFixed(instr);
3914 __ j(parity_odd, &have_value); // NaN.
3915
3916 ExternalReference canonical_nan_reference =
3917 ExternalReference::address_of_canonical_non_hole_nan();
3918 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
3919 __ bind(&have_value);
3920 } 3948 }
3921
3922 Operand double_store_operand = BuildFastArrayOperand(
3923 instr->elements(),
3924 instr->key(),
3925 instr->hydrogen()->key()->representation(),
3926 FAST_DOUBLE_ELEMENTS,
3927 FixedDoubleArray::kHeaderSize - kHeapObjectTag,
3928 instr->additional_index());
3929 __ movdbl(double_store_operand, value);
3930 } 3949 }
3931 3950
3932 3951
3933 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3952 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3934 ASSERT(ToRegister(instr->context()).is(esi)); 3953 ASSERT(ToRegister(instr->context()).is(esi));
3935 ASSERT(ToRegister(instr->object()).is(edx)); 3954 ASSERT(ToRegister(instr->object()).is(edx));
3936 ASSERT(ToRegister(instr->key()).is(ecx)); 3955 ASSERT(ToRegister(instr->key()).is(ecx));
3937 ASSERT(ToRegister(instr->value()).is(eax)); 3956 ASSERT(ToRegister(instr->value()).is(eax));
3938 3957
3939 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode) 3958 Handle<Code> ic = (instr->strict_mode_flag() == kStrictMode)
(...skipping 1597 matching lines...) Expand 10 before | Expand all | Expand 10 after
5537 FixedArray::kHeaderSize - kPointerSize)); 5556 FixedArray::kHeaderSize - kPointerSize));
5538 __ bind(&done); 5557 __ bind(&done);
5539 } 5558 }
5540 5559
5541 5560
5542 #undef __ 5561 #undef __
5543 5562
5544 } } // namespace v8::internal 5563 } } // namespace v8::internal
5545 5564
5546 #endif // V8_TARGET_ARCH_IA32 5565 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698